aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-08-29 14:31:32 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-02 17:27:36 +0200
commitedee5c3dc0d922ec3b6a44d66193e9a57b8a979e (patch)
tree5e40caa777c01a7999d736ead63ae239d1eb5b98 /src/qml
parent3ad8b0f0e8193bb7b62ffee6b33588ef6b51459c (diff)
Move prototype pointer into QV4::InternalClass
The prototype is actually the same for most objects. By moving it into the internal class, we can save 8 bytes per object, as well as allowing for some future optimizations. Also fix a bug in the implementation of the Error prototype objects. Change-Id: I4d4b641055f644a9b088f27be34bfdb0446279b7 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qv4compileddata.cpp2
-rw-r--r--src/qml/jsapi/qjsvalue.cpp17
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4booleanobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h3
-rw-r--r--src/qml/jsruntime/qv4engine.cpp116
-rw-r--r--src/qml/jsruntime/qv4engine_p.h1
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp31
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h27
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp29
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h3
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp25
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp48
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4numberobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4object.cpp46
-rw-r--r--src/qml/jsruntime/qv4object_p.h9
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp2
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp27
-rw-r--r--src/qml/jsruntime/qv4objectproto_p.h2
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp4
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp8
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp2
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp9
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp11
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h3
-rw-r--r--src/qml/jsruntime/qv4variantobject.cpp15
-rw-r--r--src/qml/jsruntime/qv4variantobject_p.h3
-rw-r--r--src/qml/qml/qqmlcomponent.cpp2
-rw-r--r--src/qml/qml/qqmlcontextwrapper.cpp4
-rw-r--r--src/qml/qml/qqmllistwrapper.cpp2
-rw-r--r--src/qml/qml/qqmllocale.cpp2
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp4
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp4
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp28
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp2
-rw-r--r--src/qml/qml/v8/qv8engine.cpp4
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp4
-rw-r--r--src/qml/util/qqmladaptormodel.cpp4
43 files changed, 292 insertions, 231 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 4c1b05b04e..696531fec3 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -43,6 +43,7 @@
#include "qv4jsir_p.h"
#include <private/qv4engine_p.h>
#include <private/qv4function_p.h>
+#include <private/qv4objectproto_p.h>
#include <private/qv4lookup_p.h>
#include <private/qv4regexpobject_p.h>
#include <private/qv4unwindhelper_p.h>
@@ -124,6 +125,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
int memberCount = 0;
const CompiledData::JSClassMember *member = data->jsClassAt(i, &memberCount);
QV4::InternalClass *klass = engine->emptyClass;
+ klass = klass->changePrototype(engine->objectPrototype);
for (int j = 0; j < memberCount; ++j, ++member)
klass = klass->addMember(runtimeStrings[member->nameOffset], member->isAccessor ? QV4::Attr_Accessor : QV4::Attr_Data);
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index cff760b49b..b737ee0073 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -662,9 +662,9 @@ QJSValue QJSValue::prototype() const
Object *o = d->value.asObject();
if (!o)
return QJSValue();
- if (!o->prototype)
+ if (!o->prototype())
return QJSValue(NullValue);
- return new QJSValuePrivate(o->internalClass->engine, Value::fromObject(o->prototype));
+ return new QJSValuePrivate(o->internalClass->engine, Value::fromObject(o->prototype()));
}
/*!
@@ -685,7 +685,7 @@ void QJSValue::setPrototype(const QJSValue& prototype)
if (!o)
return;
if (prototype.d->value.isNull()) {
- o->prototype = 0;
+ o->setPrototype(0);
return;
}
@@ -696,15 +696,8 @@ void QJSValue::setPrototype(const QJSValue& prototype)
qWarning("QJSValue::setPrototype() failed: cannot set a prototype created in a different engine");
return;
}
- Object *pp = p;
- while (pp) {
- if (pp == o) {
- qWarning("QJSValue::setPrototype() failed: cyclic prototype value");
- return;
- }
- pp = pp->prototype;
- }
- o->prototype = p;
+ if (!o->setPrototype(p))
+ qWarning("QJSValue::setPrototype() failed: cyclic prototype value");
}
/*!
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 60e7afdaec..6fc661565d 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -84,8 +84,8 @@ Value ArrayCtor::call(Managed *that, const CallData &d)
return construct(that, d);
}
-ArrayPrototype::ArrayPrototype(ExecutionContext *context)
- : ArrayObject(context->engine)
+ArrayPrototype::ArrayPrototype(InternalClass *ic)
+ : ArrayObject(ic)
{
}
diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h
index f5c256669f..0d76542535 100644
--- a/src/qml/jsruntime/qv4arrayobject_p.h
+++ b/src/qml/jsruntime/qv4arrayobject_p.h
@@ -62,7 +62,7 @@ protected:
struct ArrayPrototype: ArrayObject
{
- ArrayPrototype(ExecutionContext *context);
+ ArrayPrototype(InternalClass *ic);
void init(ExecutionContext *ctx, const Value &ctor);
diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h
index 0cdcdec1f1..b55f82b76f 100644
--- a/src/qml/jsruntime/qv4booleanobject_p.h
+++ b/src/qml/jsruntime/qv4booleanobject_p.h
@@ -62,7 +62,7 @@ protected:
struct BooleanPrototype: BooleanObject
{
- BooleanPrototype(ExecutionEngine *engine): BooleanObject(engine, Value::fromBoolean(false)) {}
+ BooleanPrototype(InternalClass *ic): BooleanObject(ic) {}
void init(ExecutionContext *ctx, const Value &ctor);
static Value method_toString(SimpleCallContext *ctx);
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index 89ca057a1b..8c925d46e2 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -53,6 +53,7 @@ namespace QV4 {
struct DateObject: Object {
Value value;
+ DateObject(InternalClass *ic): Object(ic), value(Value::fromDouble(qSNaN())) { type = Type_DateObject; }
DateObject(ExecutionEngine *engine, const Value &value): Object(engine), value(value) { type = Type_DateObject; }
DateObject(ExecutionEngine *engine, const QDateTime &value);
@@ -72,7 +73,7 @@ protected:
struct DatePrototype: DateObject
{
- DatePrototype(ExecutionEngine *engine): DateObject(engine, Value::fromDouble(qSNaN())) {}
+ DatePrototype(InternalClass *ic): DateObject(ic) {}
void init(ExecutionContext *ctx, const Value &ctor);
static double getThisDate(ExecutionContext *ctx);
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 08093ca24c..00b7905a45 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -136,46 +136,36 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
id_uintMax = newIdentifier(QStringLiteral("4294967295"));
id_name = newIdentifier(QStringLiteral("name"));
- arrayClass = emptyClass->addMember(id_length, Attr_NotConfigurable|Attr_NotEnumerable);
- InternalClass *argsClass = emptyClass->addMember(id_length, Attr_NotEnumerable);
+ objectPrototype = new (memoryManager) ObjectPrototype(emptyClass);
+ objectClass = emptyClass->changePrototype(objectPrototype);
+
+ arrayClass = objectClass->addMember(id_length, Attr_NotConfigurable|Attr_NotEnumerable);
+ arrayPrototype = new (memoryManager) ArrayPrototype(arrayClass);
+ arrayClass = arrayClass->changePrototype(arrayPrototype);
+
+ InternalClass *argsClass = objectClass->addMember(id_length, Attr_NotEnumerable);
argumentsObjectClass = argsClass->addMember(id_callee, Attr_Data|Attr_NotEnumerable);
strictArgumentsObjectClass = argsClass->addMember(id_callee, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
strictArgumentsObjectClass = strictArgumentsObjectClass->addMember(id_caller, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
initRootContext();
- objectPrototype = new (memoryManager) ObjectPrototype(this);
- stringPrototype = new (memoryManager) StringPrototype(this);
- numberPrototype = new (memoryManager) NumberPrototype(this);
- booleanPrototype = new (memoryManager) BooleanPrototype(this);
- arrayPrototype = new (memoryManager) ArrayPrototype(rootContext);
- datePrototype = new (memoryManager) DatePrototype(this);
- functionPrototype = new (memoryManager) FunctionPrototype(rootContext);
- regExpPrototype = new (memoryManager) RegExpPrototype(this);
- errorPrototype = new (memoryManager) ErrorPrototype(this);
- evalErrorPrototype = new (memoryManager) EvalErrorPrototype(this);
- rangeErrorPrototype = new (memoryManager) RangeErrorPrototype(this);
- referenceErrorPrototype = new (memoryManager) ReferenceErrorPrototype(this);
- syntaxErrorPrototype = new (memoryManager) SyntaxErrorPrototype(this);
- typeErrorPrototype = new (memoryManager) TypeErrorPrototype(this);
- uRIErrorPrototype = new (memoryManager) URIErrorPrototype(this);
-
- variantPrototype = new (memoryManager) VariantPrototype(this);
- sequencePrototype = new (memoryManager) SequencePrototype(this);
-
- stringPrototype->prototype = objectPrototype;
- numberPrototype->prototype = objectPrototype;
- booleanPrototype->prototype = objectPrototype;
- arrayPrototype->prototype = objectPrototype;
- datePrototype->prototype = objectPrototype;
- functionPrototype->prototype = objectPrototype;
- regExpPrototype->prototype = objectPrototype;
- errorPrototype->prototype = objectPrototype;
- evalErrorPrototype->prototype = objectPrototype;
- rangeErrorPrototype->prototype = objectPrototype;
- referenceErrorPrototype->prototype = objectPrototype;
- syntaxErrorPrototype->prototype = objectPrototype;
- typeErrorPrototype->prototype = objectPrototype;
- uRIErrorPrototype->prototype = objectPrototype;
+ stringPrototype = new (memoryManager) StringPrototype(objectClass);
+ numberPrototype = new (memoryManager) NumberPrototype(objectClass);
+ booleanPrototype = new (memoryManager) BooleanPrototype(objectClass);
+ datePrototype = new (memoryManager) DatePrototype(objectClass);
+ functionPrototype = new (memoryManager) FunctionPrototype(objectClass);
+ regExpPrototype = new (memoryManager) RegExpPrototype(objectClass);
+ errorPrototype = new (memoryManager) ErrorPrototype(objectClass);
+ InternalClass *errorProtoClass = emptyClass->changePrototype(errorPrototype);
+ evalErrorPrototype = new (memoryManager) EvalErrorPrototype(errorProtoClass);
+ rangeErrorPrototype = new (memoryManager) RangeErrorPrototype(errorProtoClass);
+ referenceErrorPrototype = new (memoryManager) ReferenceErrorPrototype(errorProtoClass);
+ syntaxErrorPrototype = new (memoryManager) SyntaxErrorPrototype(errorProtoClass);
+ typeErrorPrototype = new (memoryManager) TypeErrorPrototype(errorProtoClass);
+ uRIErrorPrototype = new (memoryManager) URIErrorPrototype(errorProtoClass);
+
+ variantPrototype = new (memoryManager) VariantPrototype(objectClass);
+ sequencePrototype = new (memoryManager) SequencePrototype(arrayClass->changePrototype(arrayPrototype));
objectCtor = Value::fromObject(new (memoryManager) ObjectCtor(rootContext));
stringCtor = Value::fromObject(new (memoryManager) StringCtor(rootContext));
@@ -193,21 +183,21 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
typeErrorCtor = Value::fromObject(new (memoryManager) TypeErrorCtor(rootContext));
uRIErrorCtor = Value::fromObject(new (memoryManager) URIErrorCtor(rootContext));
- objectCtor.objectValue()->prototype = functionPrototype;
- stringCtor.objectValue()->prototype = functionPrototype;
- numberCtor.objectValue()->prototype = functionPrototype;
- booleanCtor.objectValue()->prototype = functionPrototype;
- arrayCtor.objectValue()->prototype = functionPrototype;
- functionCtor.objectValue()->prototype = functionPrototype;
- dateCtor.objectValue()->prototype = functionPrototype;
- regExpCtor.objectValue()->prototype = functionPrototype;
- errorCtor.objectValue()->prototype = functionPrototype;
- evalErrorCtor.objectValue()->prototype = functionPrototype;
- rangeErrorCtor.objectValue()->prototype = functionPrototype;
- referenceErrorCtor.objectValue()->prototype = functionPrototype;
- syntaxErrorCtor.objectValue()->prototype = functionPrototype;
- typeErrorCtor.objectValue()->prototype = functionPrototype;
- uRIErrorCtor.objectValue()->prototype = functionPrototype;
+ objectCtor.objectValue()->setPrototype(functionPrototype);
+ stringCtor.objectValue()->setPrototype(functionPrototype);
+ numberCtor.objectValue()->setPrototype(functionPrototype);
+ booleanCtor.objectValue()->setPrototype(functionPrototype);
+ arrayCtor.objectValue()->setPrototype(functionPrototype);
+ functionCtor.objectValue()->setPrototype(functionPrototype);
+ dateCtor.objectValue()->setPrototype(functionPrototype);
+ regExpCtor.objectValue()->setPrototype(functionPrototype);
+ errorCtor.objectValue()->setPrototype(functionPrototype);
+ evalErrorCtor.objectValue()->setPrototype(functionPrototype);
+ rangeErrorCtor.objectValue()->setPrototype(functionPrototype);
+ referenceErrorCtor.objectValue()->setPrototype(functionPrototype);
+ syntaxErrorCtor.objectValue()->setPrototype(functionPrototype);
+ typeErrorCtor.objectValue()->setPrototype(functionPrototype);
+ uRIErrorCtor.objectValue()->setPrototype(functionPrototype);
objectPrototype->init(rootContext, objectCtor);
stringPrototype->init(this, stringCtor);
@@ -337,14 +327,14 @@ BoundFunction *ExecutionEngine::newBoundFunction(ExecutionContext *scope, Functi
Object *ExecutionEngine::newObject()
{
Object *object = new (memoryManager) Object(this);
- object->prototype = objectPrototype;
+ object->setPrototype(objectPrototype);
return object;
}
Object *ExecutionEngine::newObject(InternalClass *internalClass)
{
Object *object = new (memoryManager) Object(internalClass);
- object->prototype = objectPrototype;
+ object->setPrototype(objectPrototype);
return object;
}
@@ -361,28 +351,27 @@ String *ExecutionEngine::newIdentifier(const QString &text)
Object *ExecutionEngine::newStringObject(const Value &value)
{
StringObject *object = new (memoryManager) StringObject(this, value);
- object->prototype = stringPrototype;
+ object->setPrototype(stringPrototype);
return object;
}
Object *ExecutionEngine::newNumberObject(const Value &value)
{
NumberObject *object = new (memoryManager) NumberObject(this, value);
- object->prototype = numberPrototype;
+ object->setPrototype(numberPrototype);
return object;
}
Object *ExecutionEngine::newBooleanObject(const Value &value)
{
Object *object = new (memoryManager) BooleanObject(this, value);
- object->prototype = booleanPrototype;
+ object->setPrototype(booleanPrototype);
return object;
}
ArrayObject *ExecutionEngine::newArrayObject(int count)
{
ArrayObject *object = new (memoryManager) ArrayObject(this);
- object->prototype = arrayPrototype;
if (count) {
if (count < 0x1000)
@@ -395,21 +384,20 @@ ArrayObject *ExecutionEngine::newArrayObject(int count)
ArrayObject *ExecutionEngine::newArrayObject(const QStringList &list)
{
ArrayObject *object = new (memoryManager) ArrayObject(this, list);
- object->prototype = arrayPrototype;
return object;
}
DateObject *ExecutionEngine::newDateObject(const Value &value)
{
DateObject *object = new (memoryManager) DateObject(this, value);
- object->prototype = datePrototype;
+ object->setPrototype(datePrototype);
return object;
}
DateObject *ExecutionEngine::newDateObject(const QDateTime &dt)
{
DateObject *object = new (memoryManager) DateObject(this, dt);
- object->prototype = datePrototype;
+ object->setPrototype(datePrototype);
return object;
}
@@ -429,21 +417,21 @@ RegExpObject *ExecutionEngine::newRegExpObject(const QString &pattern, int flags
RegExpObject *ExecutionEngine::newRegExpObject(RegExp* re, bool global)
{
RegExpObject *object = new (memoryManager) RegExpObject(this, re, global);
- object->prototype = regExpPrototype;
+ object->setPrototype(regExpPrototype);
return object;
}
RegExpObject *ExecutionEngine::newRegExpObject(const QRegExp &re)
{
RegExpObject *object = new (memoryManager) RegExpObject(this, re);
- object->prototype = regExpPrototype;
+ object->setPrototype(regExpPrototype);
return object;
}
Object *ExecutionEngine::newErrorObject(const Value &value)
{
ErrorObject *object = new (memoryManager) ErrorObject(this, value);
- object->prototype = errorPrototype;
+ object->setPrototype(errorPrototype);
return object;
}
@@ -628,9 +616,9 @@ void ExecutionEngine::requireArgumentsAccessors(int n)
argumentsAccessors.resize(n);
for (int i = oldSize; i < n; ++i) {
FunctionObject *get = new (memoryManager) ArgumentsGetterFunction(rootContext, i);
- get->prototype = functionPrototype;
+ get->setPrototype(functionPrototype);
FunctionObject *set = new (memoryManager) ArgumentsSetterFunction(rootContext, i);
- set->prototype = functionPrototype;
+ set->setPrototype(functionPrototype);
Property pd = Property::fromAccessor(get, set);
argumentsAccessors[i] = pd;
}
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 8f6e47e5f1..c368f4e81e 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -170,6 +170,7 @@ struct Q_QML_EXPORT ExecutionEngine
QQmlJS::MemoryPool classPool;
InternalClass *emptyClass;
+ InternalClass *objectClass;
InternalClass *arrayClass;
InternalClass *argumentsObjectClass;
InternalClass *strictArgumentsObjectClass;
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index 6c7c290452..f0d7d7205e 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -72,6 +72,15 @@
using namespace QV4;
+ErrorObject::ErrorObject(InternalClass *ic)
+ : Object(ic)
+ , stack(0)
+{
+ type = Type_ErrorObject;
+ vtbl = &static_vtbl;
+ defineDefaultProperty(ic->engine, QStringLiteral("name"), Value::fromString(ic->engine, "Error"));
+}
+
ErrorObject::ErrorObject(ExecutionEngine *engine, const Value &message, ErrorType t)
: Object(engine)
, stack(0)
@@ -158,68 +167,68 @@ SyntaxErrorObject::SyntaxErrorObject(ExecutionEngine *engine, const Value &msg)
: ErrorObject(engine, msg, SyntaxError)
{
vtbl = &static_vtbl;
- prototype = engine->syntaxErrorPrototype;
+ setPrototype(engine->syntaxErrorPrototype);
}
SyntaxErrorObject::SyntaxErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber)
: ErrorObject(engine, msg, fileName, lineNumber, columnNumber, SyntaxError)
{
vtbl = &static_vtbl;
- prototype = engine->syntaxErrorPrototype;
+ setPrototype(engine->syntaxErrorPrototype);
}
EvalErrorObject::EvalErrorObject(ExecutionEngine *engine, const Value &message)
: ErrorObject(engine, message, EvalError)
{
- prototype = engine->evalErrorPrototype;
+ setPrototype(engine->evalErrorPrototype);
}
RangeErrorObject::RangeErrorObject(ExecutionEngine *engine, const Value &message)
: ErrorObject(engine, message, RangeError)
{
- prototype = engine->rangeErrorPrototype;
+ setPrototype(engine->rangeErrorPrototype);
}
RangeErrorObject::RangeErrorObject(ExecutionEngine *engine, const QString &message)
: ErrorObject(engine, Value::fromString(engine, message), RangeError)
{
- prototype = engine->rangeErrorPrototype;
+ setPrototype(engine->rangeErrorPrototype);
}
ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const Value &message)
: ErrorObject(engine, message, ReferenceError)
{
- prototype = engine->referenceErrorPrototype;
+ setPrototype(engine->referenceErrorPrototype);
}
ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const QString &message)
: ErrorObject(engine, Value::fromString(engine, message), ReferenceError)
{
- prototype = engine->referenceErrorPrototype;
+ setPrototype(engine->referenceErrorPrototype);
}
ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber)
: ErrorObject(engine, msg, fileName, lineNumber, columnNumber, ReferenceError)
{
- prototype = engine->referenceErrorPrototype;
+ setPrototype(engine->referenceErrorPrototype);
}
TypeErrorObject::TypeErrorObject(ExecutionEngine *engine, const Value &message)
: ErrorObject(engine, message, TypeError)
{
- prototype = engine->typeErrorPrototype;
+ setPrototype(engine->typeErrorPrototype);
}
TypeErrorObject::TypeErrorObject(ExecutionEngine *engine, const QString &message)
: ErrorObject(engine, Value::fromString(engine, message), TypeError)
{
- prototype = engine->typeErrorPrototype;
+ setPrototype(engine->typeErrorPrototype);
}
URIErrorObject::URIErrorObject(ExecutionEngine *engine, const Value &message)
: ErrorObject(engine, message, URIError)
{
- prototype = engine->uRIErrorPrototype;
+ setPrototype(engine->uRIErrorPrototype);
}
DEFINE_MANAGED_VTABLE(ErrorCtor);
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index c51023205f..e7bf995c53 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -63,6 +63,7 @@ struct ErrorObject: Object {
URIError
};
+ ErrorObject(InternalClass *ic);
ErrorObject(ExecutionEngine *engine, const Value &message, ErrorType t = Error);
ErrorObject(ExecutionEngine *engine, const QString &message, const QString &fileName, int line, int column, ErrorType t = Error);
@@ -184,46 +185,46 @@ protected:
struct ErrorPrototype: ErrorObject
{
// ### shouldn't be undefined
- ErrorPrototype(ExecutionEngine *engine): ErrorObject(engine, Value::undefinedValue()) {}
+ ErrorPrototype(InternalClass *ic): ErrorObject(ic) {}
void init(ExecutionEngine *engine, const Value &ctor) { init(engine, ctor, this); }
static void init(ExecutionEngine *engine, const Value &ctor, Object *obj);
static Value method_toString(SimpleCallContext *ctx);
};
-struct EvalErrorPrototype: EvalErrorObject
+struct EvalErrorPrototype: ErrorObject
{
- EvalErrorPrototype(ExecutionEngine *engine): EvalErrorObject(engine, Value::undefinedValue()) { vtbl = &static_vtbl; }
+ EvalErrorPrototype(InternalClass *ic): ErrorObject(ic) { vtbl = &static_vtbl; }
void init(ExecutionEngine *engine, const Value &ctor) { ErrorPrototype::init(engine, ctor, this); }
};
-struct RangeErrorPrototype: RangeErrorObject
+struct RangeErrorPrototype: ErrorObject
{
- RangeErrorPrototype(ExecutionEngine *engine): RangeErrorObject(engine, Value::undefinedValue()) { vtbl = &static_vtbl; }
+ RangeErrorPrototype(InternalClass *ic): ErrorObject(ic) { vtbl = &static_vtbl; }
void init(ExecutionEngine *engine, const Value &ctor) { ErrorPrototype::init(engine, ctor, this); }
};
-struct ReferenceErrorPrototype: ReferenceErrorObject
+struct ReferenceErrorPrototype: ErrorObject
{
- ReferenceErrorPrototype(ExecutionEngine *engine): ReferenceErrorObject(engine, Value::undefinedValue()) { vtbl = &static_vtbl; }
+ ReferenceErrorPrototype(InternalClass *ic): ErrorObject(ic) { vtbl = &static_vtbl; }
void init(ExecutionEngine *engine, const Value &ctor) { ErrorPrototype::init(engine, ctor, this); }
};
-struct SyntaxErrorPrototype: SyntaxErrorObject
+struct SyntaxErrorPrototype: ErrorObject
{
- SyntaxErrorPrototype(ExecutionEngine *engine): SyntaxErrorObject(engine, Value::undefinedValue()) { vtbl = &static_vtbl; }
+ SyntaxErrorPrototype(InternalClass *ic): ErrorObject(ic) { vtbl = &static_vtbl; }
void init(ExecutionEngine *engine, const Value &ctor) { ErrorPrototype::init(engine, ctor, this); }
};
-struct TypeErrorPrototype: TypeErrorObject
+struct TypeErrorPrototype: ErrorObject
{
- TypeErrorPrototype(ExecutionEngine *engine): TypeErrorObject(engine, Value::undefinedValue()) { vtbl = &static_vtbl; }
+ TypeErrorPrototype(InternalClass *ic): ErrorObject(ic) { vtbl = &static_vtbl; }
void init(ExecutionEngine *engine, const Value &ctor) { ErrorPrototype::init(engine, ctor, this); }
};
-struct URIErrorPrototype: URIErrorObject
+struct URIErrorPrototype: ErrorObject
{
- URIErrorPrototype(ExecutionEngine *engine): URIErrorObject(engine, Value::undefinedValue()) { vtbl = &static_vtbl; }
+ URIErrorPrototype(InternalClass *ic): ErrorObject(ic) { vtbl = &static_vtbl; }
void init(ExecutionEngine *engine, const Value &ctor) { ErrorPrototype::init(engine, ctor, this); }
};
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 995434aca2..59892033c4 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -80,7 +80,7 @@ FunctionObject::FunctionObject(ExecutionContext *scope, String *name)
, function(0)
{
vtbl = &static_vtbl;
- prototype = scope->engine->functionPrototype;
+ setPrototype(scope->engine->functionPrototype);
type = Type_FunctionObject;
needsActivation = true;
@@ -94,6 +94,21 @@ FunctionObject::FunctionObject(ExecutionContext *scope, String *name)
defineReadonlyProperty(scope->engine->id_name, Value::fromString(name));
}
+FunctionObject::FunctionObject(InternalClass *ic)
+ : Object(ic)
+ , scope(ic->engine->rootContext)
+ , name(name)
+ , formalParameterList(0)
+ , varList(0)
+ , formalParameterCount(0)
+ , varCount(0)
+ , function(0)
+{
+ vtbl = &static_vtbl;
+
+ type = Type_FunctionObject;
+}
+
FunctionObject::~FunctionObject()
{
if (function)
@@ -120,7 +135,7 @@ bool FunctionObject::hasInstance(Managed *that, const Value &value)
ctx->throwTypeError();
while (v) {
- v = v->prototype;
+ v = v->prototype();
if (! v)
break;
@@ -139,7 +154,7 @@ Value FunctionObject::construct(Managed *that, const CallData &)
Object *obj = v4->newObject();
Value proto = f->get(v4->id_prototype);
if (proto.isObject())
- obj->prototype = proto.objectValue();
+ obj->setPrototype(proto.objectValue());
return Value::fromObject(obj);
}
@@ -235,8 +250,8 @@ Value FunctionCtor::call(Managed *that, const CallData &d)
return construct(that, d);
}
-FunctionPrototype::FunctionPrototype(ExecutionContext *ctx)
- : FunctionObject(ctx)
+FunctionPrototype::FunctionPrototype(InternalClass *ic)
+ : FunctionObject(ic)
{
}
@@ -375,7 +390,7 @@ Value ScriptFunction::construct(Managed *that, const CallData &d)
Object *obj = v4->newObject();
Value proto = f->get(v4->id_prototype);
if (proto.isObject())
- obj->prototype = proto.objectValue();
+ obj->setPrototype(proto.objectValue());
ExecutionContext *context = v4->current;
CallData dd = d;
@@ -469,7 +484,7 @@ Value SimpleScriptFunction::construct(Managed *that, const CallData &d)
Object *obj = v4->newObject();
Value proto = f->get(v4->id_prototype);
if (proto.isObject())
- obj->prototype = proto.objectValue();
+ obj->setPrototype(proto.objectValue());
ExecutionContext *context = v4->current;
void *stackSpace = alloca(requiredMemoryForExecutionContectSimple(f));
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index fdfb1e6a2b..8b900db55d 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -108,6 +108,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
Function *function;
FunctionObject(ExecutionContext *scope, String *name = 0);
+ FunctionObject(InternalClass *ic);
~FunctionObject();
Value newInstance();
@@ -144,7 +145,7 @@ protected:
struct FunctionPrototype: FunctionObject
{
- FunctionPrototype(ExecutionContext *ctx);
+ FunctionPrototype(InternalClass *ic);
void init(ExecutionContext *ctx, const Value &ctor);
static Value method_toString(SimpleCallContext *ctx);
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index 50803db73d..59b1989e72 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -50,6 +50,9 @@ QT_BEGIN_NAMESPACE
uint QV4::qHash(const QV4::InternalClassTransition &t, uint)
{
+ if (t.flags == QV4::InternalClassTransition::ProtoChange)
+ // INT_MAX is prime, so this should give a decent distribution of keys
+ return (uint)((quintptr)t.prototype * INT_MAX);
return t.id->hashValue ^ t.flags;
}
@@ -160,6 +163,8 @@ InternalClass *InternalClass::changeMember(String *string, PropertyAttributes da
// create a new class and add it to the tree
InternalClass *newClass = engine->newClass(*this);
newClass->propertyData[idx] = data;
+
+ transitions.insert(t, newClass);
return newClass;
}
@@ -178,8 +183,17 @@ InternalClass *InternalClass::changePrototype(Object *proto)
return tit.value();
// create a new class and add it to the tree
- InternalClass *newClass = engine->newClass(*this);
- newClass->prototype = proto;
+ InternalClass *newClass;
+ if (this == engine->emptyClass) {
+ newClass = engine->newClass(*this);
+ newClass->prototype = proto;
+ } else {
+ newClass = engine->emptyClass->changePrototype(proto);
+ for (int i = 0; i < nameMap.size(); ++i)
+ newClass = newClass->addMember(nameMap.at(i), propertyData.at(i));
+ }
+
+ transitions.insert(t, newClass);
return newClass;
}
@@ -231,7 +245,7 @@ void InternalClass::removeMember(Object *object, Identifier *id)
}
// create a new class and add it to the tree
- object->internalClass = engine->emptyClass;
+ object->internalClass = engine->emptyClass->changePrototype(prototype);
for (int i = 0; i < nameMap.size(); ++i) {
if (i == propIdx)
continue;
@@ -259,6 +273,7 @@ InternalClass *InternalClass::sealed()
return m_sealed;
m_sealed = engine->emptyClass;
+ m_sealed = m_sealed->changePrototype(prototype);
for (int i = 0; i < nameMap.size(); ++i) {
PropertyAttributes attrs = propertyData.at(i);
attrs.setConfigurable(false);
@@ -275,6 +290,7 @@ InternalClass *InternalClass::frozen()
return m_frozen;
m_frozen = engine->emptyClass;
+ m_frozen = m_frozen->changePrototype(prototype);
for (int i = 0; i < nameMap.size(); ++i) {
PropertyAttributes attrs = propertyData.at(i);
attrs.setWritable(false);
@@ -315,7 +331,8 @@ void InternalClass::destroy()
void InternalClass::markObjects()
{
- prototype->mark();
+ if (prototype)
+ prototype->mark();
for (QHash<Transition, InternalClass *>::ConstIterator it = transitions.begin(), end = transitions.end();
it != end; ++it)
it.value()->markObjects();
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 68a4c5ca71..740f30f061 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -861,7 +861,7 @@ JsonObject::JsonObject(ExecutionContext *context)
: Object(context->engine)
{
type = Type_JSONObject;
- prototype = context->engine->objectPrototype;
+ setPrototype(context->engine->objectPrototype);
defineDefaultProperty(context, QStringLiteral("parse"), method_parse, 2);
defineDefaultProperty(context, QStringLiteral("stringify"), method_stringify, 3);
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index b7a6f73822..94df9685e3 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -49,7 +49,7 @@ Property *Lookup::lookup(Object *obj, PropertyAttributes *attrs)
{
int i = 0;
while (i < level && obj && obj->internalClass == classList[i]) {
- obj = obj->prototype;
+ obj = obj->prototype();
++i;
}
@@ -68,7 +68,7 @@ Property *Lookup::lookup(Object *obj, PropertyAttributes *attrs)
return obj->memberData + index;
}
- obj = obj->prototype;
+ obj = obj->prototype();
++i;
}
level = i;
@@ -80,7 +80,7 @@ Property *Lookup::lookup(Object *obj, PropertyAttributes *attrs)
return obj->memberData + index;
}
- obj = obj->prototype;
+ obj = obj->prototype();
}
return 0;
}
@@ -122,9 +122,9 @@ void Lookup::getter1(Lookup *l, Value *result, const Value &object)
{
if (Object *o = object.asObject()) {
if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype->internalClass) {
+ l->classList[1] == o->prototype()->internalClass) {
if (result)
- *result = o->prototype->memberData[l->index].value;
+ *result = o->prototype()->memberData[l->index].value;
return;
}
}
@@ -136,9 +136,9 @@ void Lookup::getter2(Lookup *l, Value *result, const Value &object)
{
if (Object *o = object.asObject()) {
if (l->classList[0] == o->internalClass) {
- o = o->prototype;
+ o = o->prototype();
if (l->classList[1] == o->internalClass) {
- o = o->prototype;
+ o = o->prototype();
if (l->classList[2] == o->internalClass) {
if (result)
*result = o->memberData[l->index].value;
@@ -177,9 +177,9 @@ void Lookup::getterAccessor1(Lookup *l, Value *result, const Value &object)
{
if (Object *o = object.asObject()) {
if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype->internalClass) {
+ l->classList[1] == o->prototype()->internalClass) {
Value res;
- FunctionObject *getter = o->prototype->memberData[l->index].getter();
+ FunctionObject *getter = o->prototype()->memberData[l->index].getter();
if (!getter) {
res = Value::undefinedValue();
} else {
@@ -200,9 +200,9 @@ void Lookup::getterAccessor2(Lookup *l, Value *result, const Value &object)
{
if (Object *o = object.asObject()) {
if (l->classList[0] == o->internalClass) {
- o = o->prototype;
+ o = o->prototype();
if (l->classList[1] == o->internalClass) {
- o = o->prototype;
+ o = o->prototype();
if (l->classList[2] == o->internalClass) {
Value res;
FunctionObject *getter = o->memberData[l->index].getter();
@@ -271,8 +271,8 @@ void Lookup::globalGetter1(Lookup *l, ExecutionContext *ctx, Value *result)
{
Object *o = ctx->engine->globalObject;
if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype->internalClass) {
- *result = o->prototype->memberData[l->index].value;
+ l->classList[1] == o->prototype()->internalClass) {
+ *result = o->prototype()->memberData[l->index].value;
return;
}
l->globalGetter = globalGetterGeneric;
@@ -283,11 +283,11 @@ void Lookup::globalGetter2(Lookup *l, ExecutionContext *ctx, Value *result)
{
Object *o = ctx->engine->globalObject;
if (l->classList[0] == o->internalClass) {
- o = o->prototype;
+ o = o->prototype();
if (l->classList[1] == o->internalClass) {
- o = o->prototype;
+ o = o->prototype();
if (l->classList[2] == o->internalClass) {
- *result = o->prototype->memberData[l->index].value;
+ *result = o->prototype()->memberData[l->index].value;
return;
}
}
@@ -318,8 +318,8 @@ void Lookup::globalGetterAccessor1(Lookup *l, ExecutionContext *ctx, Value *resu
{
Object *o = ctx->engine->globalObject;
if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype->internalClass) {
- FunctionObject *getter = o->prototype->memberData[l->index].getter();
+ l->classList[1] == o->prototype()->internalClass) {
+ FunctionObject *getter = o->prototype()->memberData[l->index].getter();
if (!getter) {
*result = Value::undefinedValue();
} else {
@@ -337,9 +337,9 @@ void Lookup::globalGetterAccessor2(Lookup *l, ExecutionContext *ctx, Value *resu
{
Object *o = ctx->engine->globalObject;
if (l->classList[0] == o->internalClass) {
- o = o->prototype;
+ o = o->prototype();
if (l->classList[1] == o->internalClass) {
- o = o->prototype;
+ o = o->prototype();
if (l->classList[2] == o->internalClass) {
FunctionObject *getter = o->memberData[l->index].getter();
if (!getter) {
@@ -384,7 +384,7 @@ void Lookup::setterInsert0(Lookup *l, const Value &object, const Value &value)
{
Object *o = object.asObject();
if (o && o->internalClass == l->classList[0]) {
- if (!o->prototype) {
+ if (!o->prototype()) {
o->memberData[l->index].value = value;
o->internalClass = l->classList[3];
return;
@@ -399,7 +399,7 @@ void Lookup::setterInsert1(Lookup *l, const Value &object, const Value &value)
{
Object *o = object.asObject();
if (o && o->internalClass == l->classList[0]) {
- Object *p = o->prototype;
+ Object *p = o->prototype();
if (p && p->internalClass == l->classList[1]) {
o->memberData[l->index].value = value;
o->internalClass = l->classList[3];
@@ -415,9 +415,9 @@ void Lookup::setterInsert2(Lookup *l, const Value &object, const Value &value)
{
Object *o = object.asObject();
if (o && o->internalClass == l->classList[0]) {
- Object *p = o->prototype;
+ Object *p = o->prototype();
if (p && p->internalClass == l->classList[1]) {
- p = p->prototype;
+ p = p->prototype();
if (p && p->internalClass == l->classList[2]) {
o->ensureMemberIndex(l->index);
o->memberData[l->index].value = value;
diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp
index 7aa56f51bd..ac9833264a 100644
--- a/src/qml/jsruntime/qv4mathobject.cpp
+++ b/src/qml/jsruntime/qv4mathobject.cpp
@@ -54,7 +54,7 @@ MathObject::MathObject(ExecutionContext *ctx)
: Object(ctx->engine)
{
type = Type_MathObject;
- prototype = ctx->engine->objectPrototype;
+ setPrototype(ctx->engine->objectPrototype);
defineReadonlyProperty(ctx->engine, QStringLiteral("E"), Value::fromDouble(::exp(1.0)));
defineReadonlyProperty(ctx->engine, QStringLiteral("LN2"), Value::fromDouble(::log(2.0)));
diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h
index 224840ebb7..096b4b3d9f 100644
--- a/src/qml/jsruntime/qv4numberobject_p.h
+++ b/src/qml/jsruntime/qv4numberobject_p.h
@@ -62,7 +62,7 @@ protected:
struct NumberPrototype: NumberObject
{
- NumberPrototype(ExecutionEngine *engine): NumberObject(engine, Value::fromDouble(0)) {}
+ NumberPrototype(InternalClass *ic): NumberObject(ic) {}
void init(ExecutionContext *ctx, const Value &ctor);
static Value method_toString(SimpleCallContext *ctx);
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index f76abdbb01..fd4c03160e 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -70,7 +70,6 @@ DEFINE_MANAGED_VTABLE(Object);
Object::Object(ExecutionEngine *engine)
: Managed(engine->emptyClass)
- , prototype(0)
, memberDataAlloc(InlinePropertySize), memberData(inlineProperties)
, arrayOffset(0), arrayDataLen(0), arrayAlloc(0), arrayAttributes(0), arrayData(0), sparseArray(0)
{
@@ -81,7 +80,6 @@ Object::Object(ExecutionEngine *engine)
Object::Object(InternalClass *internalClass)
: Managed(internalClass)
- , prototype(0)
, memberDataAlloc(InlinePropertySize), memberData(inlineProperties)
, arrayOffset(0), arrayDataLen(0), arrayAlloc(0), arrayAttributes(0), arrayData(0), sparseArray(0)
{
@@ -106,6 +104,18 @@ Object::~Object()
_data = 0;
}
+bool Object::setPrototype(Object *proto)
+{
+ Object *pp = proto;
+ while (pp) {
+ if (pp == this)
+ return false;
+ pp = pp->prototype();
+ }
+ internalClass = internalClass->changePrototype(proto);
+ return true;
+}
+
void Object::destroy(Managed *that)
{
static_cast<Object *>(that)->~Object();
@@ -267,8 +277,6 @@ void Object::defineReadonlyProperty(String *name, Value value)
void Object::markObjects(Managed *that)
{
Object *o = static_cast<Object *>(that);
- if (o->prototype)
- o->prototype->mark();
for (int i = 0; i < o->internalClass->size; ++i) {
const Property &pd = o->memberData[i];
@@ -373,7 +381,7 @@ Property *Object::__getPropertyDescriptor__(String *name, PropertyAttributes *at
return o->memberData + idx;
}
- o = o->prototype;
+ o = o->prototype();
}
if (attrs)
*attrs = Attr_Invalid;
@@ -401,7 +409,7 @@ Property *Object::__getPropertyDescriptor__(uint index, PropertyAttributes *attr
return p;
}
}
- o = o->prototype;
+ o = o->prototype();
}
if (attrs)
*attrs = Attr_Invalid;
@@ -417,7 +425,7 @@ bool Object::__hasProperty__(String *name) const
while (o) {
if (!o->query(name).isEmpty())
return true;
- o = o->prototype;
+ o = o->prototype();
}
return false;
@@ -432,7 +440,7 @@ bool Object::__hasProperty__(uint index) const
while (o) {
if (!o->queryIndexed(index).isEmpty())
return true;
- o = o->prototype;
+ o = o->prototype();
}
return false;
@@ -565,19 +573,19 @@ void Object::setLookup(Managed *m, Lookup *l, const Value &value)
l->classList[0] = c;
l->classList[3] = o->internalClass;
l->index = idx;
- if (!o->prototype) {
+ if (!o->prototype()) {
l->setter = Lookup::setterInsert0;
return;
}
- o = o->prototype;
+ o = o->prototype();
l->classList[1] = o->internalClass;
- if (!o->prototype) {
+ if (!o->prototype()) {
l->setter = Lookup::setterInsert1;
return;
}
- o = o->prototype;
+ o = o->prototype();
l->classList[2] = o->internalClass;
- if (!o->prototype)
+ if (!o->prototype())
l->setter = Lookup::setterInsert2;
}
@@ -660,7 +668,7 @@ Value Object::internalGet(String *name, bool *hasProperty)
return getValue(o->memberData + idx, o->internalClass->propertyData.at(idx));
}
- o = o->prototype;
+ o = o->prototype();
}
if (hasProperty)
@@ -690,7 +698,7 @@ Value Object::internalGetIndexed(uint index, bool *hasProperty)
break;
}
}
- o = o->prototype;
+ o = o->prototype();
}
if (pd) {
@@ -742,12 +750,12 @@ void Object::internalPut(String *name, const Value &value)
pd->value = value;
}
return;
- } else if (!prototype) {
+ } else if (!prototype()) {
if (!extensible)
goto reject;
} else {
// clause 4
- if ((pd = prototype->__getPropertyDescriptor__(name, &attrs))) {
+ if ((pd = prototype()->__getPropertyDescriptor__(name, &attrs))) {
if (attrs.isAccessor()) {
if (!pd->setter())
goto reject;
@@ -820,12 +828,12 @@ void Object::internalPutIndexed(uint index, const Value &value)
else
pd->value = value;
return;
- } else if (!prototype) {
+ } else if (!prototype()) {
if (!extensible)
goto reject;
} else {
// clause 4
- if ((pd = prototype->__getPropertyDescriptor__(index, &attrs))) {
+ if ((pd = prototype()->__getPropertyDescriptor__(index, &attrs))) {
if (attrs.isAccessor()) {
if (!pd->setter())
goto reject;
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index fc9af6f3a5..7d4aae5aa7 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -105,7 +105,6 @@ typedef Value (*PropertyEnumeratorFunction)(Object *object);
typedef PropertyAttributes (*PropertyQueryFunction)(const Object *object, String *name);
struct Q_QML_EXPORT Object: Managed {
- Object *prototype;
uint memberDataAlloc;
Property *memberData;
@@ -128,6 +127,9 @@ struct Q_QML_EXPORT Object: Managed {
Object(InternalClass *internalClass);
~Object();
+ Object *prototype() const { return internalClass->prototype; }
+ bool setPrototype(Object *proto);
+
Property *__getOwnProperty__(String *name, PropertyAttributes *attrs = 0);
Property *__getOwnProperty__(uint index, PropertyAttributes *attrs = 0);
@@ -277,7 +279,7 @@ public:
inline bool protoHasArray() {
Object *p = this;
- while ((p = p->prototype))
+ while ((p = p->prototype()))
if (p->arrayDataLen)
return true;
@@ -350,11 +352,13 @@ protected:
struct BooleanObject: Object {
Value value;
+ BooleanObject(InternalClass *ic): Object(ic), value(Value::fromBoolean(false)) { type = Type_BooleanObject; }
BooleanObject(ExecutionEngine *engine, const Value &value): Object(engine), value(value) { type = Type_BooleanObject; }
};
struct NumberObject: Object {
Value value;
+ NumberObject(InternalClass *ic): Object(ic), value(Value::fromInt32(0)) { type = Type_NumberObject; }
NumberObject(ExecutionEngine *engine, const Value &value): Object(engine), value(value) { type = Type_NumberObject; }
};
@@ -363,6 +367,7 @@ struct ArrayObject: Object {
LengthPropertyIndex = 0
};
+ ArrayObject(InternalClass *ic) : Object(ic) { init(ic->engine); }
ArrayObject(ExecutionEngine *engine) : Object(engine) { init(engine); }
ArrayObject(ExecutionEngine *engine, const QStringList &list);
void init(ExecutionEngine *engine);
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index a89bfdb797..338398c0d8 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -82,7 +82,7 @@ Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *a
}
if (flags & WithProtoChain)
- current = current->prototype;
+ current = current->prototype();
else
current = 0;
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index ec60a9b343..fbf86645e2 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -86,7 +86,7 @@ Value ObjectCtor::construct(Managed *that, const CallData &d)
Object *obj = v4->newObject();
Value proto = ctor->get(v4->id_prototype);
if (proto.isObject())
- obj->prototype = proto.objectValue();
+ obj->setPrototype(proto.objectValue());
return Value::fromObject(obj);
}
return __qmljs_to_object(v4->current, d.args[0]);
@@ -139,7 +139,7 @@ Value ObjectPrototype::method_getPrototypeOf(SimpleCallContext *ctx)
if (! o.isObject())
ctx->throwTypeError();
- Object *p = o.objectValue()->prototype;
+ Object *p = o.objectValue()->prototype();
return p ? Value::fromObject(p) : Value::nullValue();
}
@@ -172,7 +172,7 @@ Value ObjectPrototype::method_create(SimpleCallContext *ctx)
ctx->throwTypeError();
Object *newObject = ctx->engine->newObject();
- newObject->prototype = O.asObject();
+ newObject->setPrototype(O.asObject());
Value objValue = Value::fromObject(newObject);
if (ctx->argumentCount > 1 && !ctx->argument(1).isUndefined()) {
@@ -412,11 +412,11 @@ Value ObjectPrototype::method_isPrototypeOf(SimpleCallContext *ctx)
return Value::fromBoolean(false);
Object *O = ctx->thisObject.toObject(ctx);
- Object *proto = V.objectValue()->prototype;
+ Object *proto = V.objectValue()->prototype();
while (proto) {
if (O == proto)
return Value::fromBoolean(true);
- proto = proto->prototype;
+ proto = proto->prototype();
}
return Value::fromBoolean(false);
}
@@ -481,7 +481,7 @@ Value ObjectPrototype::method_get_proto(SimpleCallContext *ctx)
if (!o)
ctx->throwTypeError();
- return Value::fromObject(o->prototype);
+ return Value::fromObject(o->prototype());
}
Value ObjectPrototype::method_set_proto(SimpleCallContext *ctx)
@@ -493,22 +493,13 @@ Value ObjectPrototype::method_set_proto(SimpleCallContext *ctx)
Value proto = ctx->argument(0);
bool ok = false;
if (proto.isNull()) {
- o->prototype = 0;
+ o->setPrototype(0);
ok = true;
} else if (Object *p = proto.asObject()) {
- if (o->prototype == p) {
+ if (o->prototype() == p) {
ok = true;
} else if (o->extensible) {
- Object *pp = p;
- while (pp) {
- if (pp == o)
- break;
- pp = pp->prototype;
- }
- if (!pp) {
- ok = true;
- o->prototype = p;
- }
+ ok = o->setPrototype(p);
}
}
if (!ok)
diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h
index afa0ce09f5..be51c41580 100644
--- a/src/qml/jsruntime/qv4objectproto_p.h
+++ b/src/qml/jsruntime/qv4objectproto_p.h
@@ -62,7 +62,7 @@ protected:
struct ObjectPrototype: Object
{
- ObjectPrototype(ExecutionEngine *engine) : Object(engine) {}
+ ObjectPrototype(InternalClass *ic) : Object(ic) {}
void init(ExecutionContext *ctx, const Value &ctor);
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 70413489aa..fe821928b5 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -246,7 +246,7 @@ QObjectWrapper::QObjectWrapper(ExecutionEngine *engine, QObject *object)
, m_object(object)
{
vtbl = &static_vtbl;
- prototype = engine->objectPrototype;
+ setPrototype(engine->objectPrototype);
m_destroy = engine->newIdentifier(QStringLiteral("destroy"));
m_toString = engine->newIdentifier(QStringLiteral("toString"));
@@ -1759,7 +1759,7 @@ QmlSignalHandler::QmlSignalHandler(ExecutionEngine *engine, QObject *object, int
, m_signalIndex(signalIndex)
{
vtbl = &static_vtbl;
- prototype = engine->objectPrototype;
+ setPrototype(engine->objectPrototype);
}
DEFINE_MANAGED_VTABLE(QmlSignalHandler);
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 16b23e2edb..05829b4e94 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -70,6 +70,14 @@ using namespace QV4;
DEFINE_MANAGED_VTABLE(RegExpObject);
+RegExpObject::RegExpObject(InternalClass *ic)
+ : Object(ic)
+ , value(RegExp::create(ic->engine, QString(), false, false))
+ , global(false)
+{
+ init(ic->engine);
+}
+
RegExpObject::RegExpObject(ExecutionEngine *engine, RegExp* value, bool global)
: Object(engine)
, value(value)
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index 2179dbdb7d..6c4f12c1e4 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -77,6 +77,8 @@ struct RegExpObject: Object {
RegExp* value;
Property *lastIndexProperty(ExecutionContext *ctx);
bool global;
+
+ RegExpObject(InternalClass *ic);
RegExpObject(ExecutionEngine *engine, RegExp* value, bool global);
RegExpObject(ExecutionEngine *engine, const QRegExp &re);
~RegExpObject() {}
@@ -107,7 +109,7 @@ protected:
struct RegExpPrototype: RegExpObject
{
- RegExpPrototype(ExecutionEngine* engine): RegExpObject(engine, RegExp::create(engine, QString()), false) {}
+ RegExpPrototype(InternalClass *ic): RegExpObject(ic) {}
void init(ExecutionContext *ctx, const Value &ctor);
static Value method_exec(SimpleCallContext *ctx);
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index f145050f17..a9095ffcf7 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1242,7 +1242,7 @@ void __qmljs_builtin_setup_arguments_object(ExecutionContext *ctx, Value *result
assert(ctx->type >= ExecutionContext::Type_CallContext);
CallContext *c = static_cast<CallContext *>(ctx);
ArgumentsObject *args = new (c->engine->memoryManager) ArgumentsObject(c);
- args->prototype = c->engine->objectPrototype;
+ args->setPrototype(c->engine->objectPrototype);
*result = Value::fromObject(args);
}
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 1d5c271069..cc5e2d626a 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -172,7 +172,7 @@ public:
{
type = Type_QmlSequence;
vtbl = &static_vtbl;
- prototype = engine->sequencePrototype;
+ setPrototype(engine->sequencePrototype);
init(engine);
}
@@ -184,7 +184,7 @@ public:
{
type = Type_QmlSequence;
vtbl = &static_vtbl;
- prototype = engine->sequencePrototype;
+ setPrototype(engine->sequencePrototype);
loadReference();
init(engine);
}
@@ -523,10 +523,9 @@ template<>
DEFINE_MANAGED_VTABLE(QQmlRealList);
#define REGISTER_QML_SEQUENCE_METATYPE(unused, unused2, SequenceType, unused3) qRegisterMetaType<SequenceType>(#SequenceType);
-SequencePrototype::SequencePrototype(ExecutionEngine *engine)
- : QV4::Object(engine)
+SequencePrototype::SequencePrototype(InternalClass *ic)
+ : QV4::Object(ic)
{
- prototype = engine->arrayPrototype;
FOREACH_QML_SEQUENCE_TYPE(REGISTER_QML_SEQUENCE_METATYPE)
}
#undef REGISTER_QML_SEQUENCE_METATYPE
diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h
index 2cade45092..ceae4e6f97 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -65,7 +65,7 @@ namespace QV4 {
struct SequencePrototype : public QV4::Object
{
- SequencePrototype(QV4::ExecutionEngine *engine);
+ SequencePrototype(QV4::InternalClass *ic);
void init(QV4::ExecutionEngine *engine);
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index ab802cabce..6fd312ab24 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -76,6 +76,17 @@ using namespace QV4;
DEFINE_MANAGED_VTABLE(StringObject);
+StringObject::StringObject(InternalClass *ic)
+ : Object(ic), value(Value::fromString(ic->engine, ""))
+{
+ vtbl = &static_vtbl;
+ type = Type_StringObject;
+
+ tmpProperty.value = Value::undefinedValue();
+
+ defineReadonlyProperty(ic->engine->id_length, Value::fromInt32(0));
+}
+
StringObject::StringObject(ExecutionEngine *engine, const Value &value)
: Object(engine), value(value)
{
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index cf489eb05c..6d2ccce641 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -54,6 +54,7 @@ struct StringObject: Object {
Value value;
mutable Property tmpProperty;
+ StringObject(InternalClass *ic);
StringObject(ExecutionEngine *engine, const Value &value);
Property *getIndex(uint index) const;
@@ -78,7 +79,7 @@ protected:
struct StringPrototype: StringObject
{
- StringPrototype(ExecutionEngine *engine): StringObject(engine, Value::fromString(engine, QString())) {}
+ StringPrototype(InternalClass *ic): StringObject(ic) {}
void init(ExecutionEngine *engine, const Value &ctor);
static Value method_toString(SimpleCallContext *context);
diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp
index f18c5b582e..1989e3dcf5 100644
--- a/src/qml/jsruntime/qv4variantobject.cpp
+++ b/src/qml/jsruntime/qv4variantobject.cpp
@@ -51,13 +51,21 @@ using namespace QV4;
DEFINE_MANAGED_VTABLE(VariantObject);
+VariantObject::VariantObject(InternalClass *ic)
+ : Object(ic)
+ , ExecutionEngine::ScarceResourceData(QVariant())
+ , m_vmePropertyReferenceCount(0)
+{
+ vtbl = &static_vtbl;
+}
+
VariantObject::VariantObject(ExecutionEngine *engine, const QVariant &value)
: Object(engine)
, ExecutionEngine::ScarceResourceData(value)
, m_vmePropertyReferenceCount(0)
{
vtbl = &static_vtbl;
- prototype = engine->variantPrototype;
+ setPrototype(engine->variantPrototype);
if (isScarce())
internalClass->engine->scarceResources.insert(this);
}
@@ -132,10 +140,9 @@ void VariantObject::removeVmePropertyReference()
}
-VariantPrototype::VariantPrototype(ExecutionEngine *engine)
- : VariantObject(engine, QVariant())
+VariantPrototype::VariantPrototype(InternalClass *ic)
+ : VariantObject(ic)
{
- prototype = engine->objectPrototype;
}
void VariantPrototype::init(ExecutionEngine *engine)
diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h
index 876539aae1..eadf0ac4cf 100644
--- a/src/qml/jsruntime/qv4variantobject_p.h
+++ b/src/qml/jsruntime/qv4variantobject_p.h
@@ -68,6 +68,7 @@ struct VariantObject : Object, public ExecutionEngine::ScarceResourceData
{
Q_MANAGED
public:
+ VariantObject(InternalClass *ic);
VariantObject(ExecutionEngine *engine, const QVariant &value);
static QVariant toVariant(const QV4::Value &v);
@@ -84,7 +85,7 @@ public:
struct VariantPrototype : VariantObject
{
public:
- VariantPrototype(ExecutionEngine *engine);
+ VariantPrototype(InternalClass *ic);
void init(ExecutionEngine *engine);
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 5c26f689de..5f3a2e971c 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1342,7 +1342,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
QV4::ExecutionEngine *v4 = QV8Engine::getV4(args->engine());
QmlIncubatorObject *r = new (v4->memoryManager) QmlIncubatorObject(args->engine(), mode);
- r->prototype = e->incubationProto.value().asObject();
+ r->setPrototype(e->incubationProto.value().asObject());
if (!valuemap.isEmpty()) {
r->valuemap = valuemap;
diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp
index 9ba3a51757..7c99bbcf9f 100644
--- a/src/qml/qml/qqmlcontextwrapper.cpp
+++ b/src/qml/qml/qqmlcontextwrapper.cpp
@@ -78,7 +78,7 @@ QV4::Value QmlContextWrapper::qmlScope(QV8Engine *v8, QQmlContextData *ctxt, QOb
ExecutionEngine *v4 = QV8Engine::getV4(v8);
QmlContextWrapper *w = new (v4->memoryManager) QmlContextWrapper(v8, ctxt, scope);
- w->prototype = v4->objectPrototype;
+ w->setPrototype(v4->objectPrototype);
return Value::fromObject(w);
}
@@ -93,7 +93,7 @@ QV4::Value QmlContextWrapper::urlScope(QV8Engine *v8, const QUrl &url)
QmlContextWrapper *w = new (v4->memoryManager) QmlContextWrapper(v8, context, 0);
w->isNullWrapper = true;
- w->prototype = v4->objectPrototype;
+ w->setPrototype(v4->objectPrototype);
return Value::fromObject(w);
}
diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp
index 7afbe3fd29..8b135f2ea9 100644
--- a/src/qml/qml/qqmllistwrapper.cpp
+++ b/src/qml/qml/qqmllistwrapper.cpp
@@ -57,7 +57,7 @@ QmlListWrapper::QmlListWrapper(QV8Engine *engine)
v8(engine)
{
vtbl = &static_vtbl;
- prototype = QV8Engine::getV4(engine)->objectPrototype;
+ setPrototype(QV8Engine::getV4(engine)->objectPrototype);
}
QmlListWrapper::~QmlListWrapper()
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 4694e33abd..f248b8b495 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -814,7 +814,7 @@ QV4::Value QQmlLocale::locale(QV8Engine *v8engine, const QString &locale)
QQmlLocaleData *wrapper = new (engine->memoryManager) QQmlLocaleData(engine);
if (!locale.isEmpty())
wrapper->locale = QLocale(locale);
- wrapper->prototype = d->prototype.value().asObject();
+ wrapper->setPrototype(d->prototype.value().asObject());
return QV4::Value::fromObject(wrapper);
}
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 20c403c95c..ab64fe1efb 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -93,7 +93,7 @@ Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlType *t, TypeNameMod
ExecutionEngine *v4 = QV8Engine::getV4(v8);
QmlTypeWrapper *w = new (v4->memoryManager) QmlTypeWrapper(v8);
- w->prototype = v4->objectPrototype;
+ w->setPrototype(v4->objectPrototype);
w->mode = mode; w->object = o; w->type = t;
return Value::fromObject(w);
}
@@ -107,7 +107,7 @@ Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlTypeNameCache *t, co
ExecutionEngine *v4 = QV8Engine::getV4(v8);
QmlTypeWrapper *w = new (v4->memoryManager) QmlTypeWrapper(v8);
- w->prototype = v4->objectPrototype;
+ w->setPrototype(v4->objectPrototype);
w->mode = mode; w->object = o; w->typeNamespace = t; w->importNamespace = importNamespace;
t->addref();
return Value::fromObject(w);
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 64baf8b1ce..f494fba11f 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -145,7 +145,7 @@ Value QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property,
initProto(v4);
QmlValueTypeReference *r = new (v4->memoryManager) QmlValueTypeReference(v8);
- r->prototype = v4->qmlExtensions()->valueTypeWrapperPrototype;
+ r->setPrototype(v4->qmlExtensions()->valueTypeWrapperPrototype);
r->type = type; r->object = object; r->property = property;
return Value::fromObject(r);
}
@@ -156,7 +156,7 @@ Value QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, QQmlValu
initProto(v4);
QmlValueTypeCopy *r = new (v4->memoryManager) QmlValueTypeCopy(v8);
- r->prototype = v4->qmlExtensions()->valueTypeWrapperPrototype;
+ r->setPrototype(v4->qmlExtensions()->valueTypeWrapperPrototype);
r->type = type; r->value = value;
return Value::fromObject(r);
}
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 5045d700ed..2f93ad5582 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -579,7 +579,7 @@ Value Node::create(QV8Engine *engine, NodeImpl *data)
switch (data->type) {
case NodeImpl::Attr:
- instance->prototype = Attr::prototype(v4).asObject();
+ instance->setPrototype(Attr::prototype(v4).asObject());
break;
case NodeImpl::Comment:
case NodeImpl::Document:
@@ -591,13 +591,13 @@ Value Node::create(QV8Engine *engine, NodeImpl *data)
case NodeImpl::ProcessingInstruction:
return Value::undefinedValue();
case NodeImpl::CDATA:
- instance->prototype = CDATA::prototype(v4).asObject();
+ instance->setPrototype(CDATA::prototype(v4).asObject());
break;
case NodeImpl::Text:
- instance->prototype = Text::prototype(v4).asObject();
+ instance->setPrototype(Text::prototype(v4).asObject());
break;
case NodeImpl::Element:
- instance->prototype = Element::prototype(v4).asObject();
+ instance->setPrototype(Element::prototype(v4).asObject());
break;
}
@@ -609,7 +609,7 @@ Value Element::prototype(ExecutionEngine *engine)
QQmlXMLHttpRequestData *d = xhrdata(engine->v8Engine);
if (d->elementPrototype.isEmpty()) {
Object *p = engine->newObject();
- p->prototype = NodePrototype::getProto(engine).asObject();
+ p->setPrototype(NodePrototype::getProto(engine).asObject());
p->defineAccessorProperty(engine, QStringLiteral("tagName"), NodePrototype::method_get_nodeName, 0);
d->elementPrototype = Value::fromObject(p);
engine->v8Engine->freezeObject(d->elementPrototype.value());
@@ -622,7 +622,7 @@ Value Attr::prototype(ExecutionEngine *engine)
QQmlXMLHttpRequestData *d = xhrdata(engine->v8Engine);
if (d->attrPrototype.isEmpty()) {
Object *p = engine->newObject();
- p->prototype = NodePrototype::getProto(engine).asObject();
+ p->setPrototype(NodePrototype::getProto(engine).asObject());
p->defineAccessorProperty(engine, QStringLiteral("name"), name, 0);
p->defineAccessorProperty(engine, QStringLiteral("value"), value, 0);
p->defineAccessorProperty(engine, QStringLiteral("ownerElement"), ownerElement, 0);
@@ -673,7 +673,7 @@ Value CharacterData::prototype(ExecutionEngine *v4)
QQmlXMLHttpRequestData *d = xhrdata(v4->v8Engine);
if (d->characterDataPrototype.isEmpty()) {
Object *p = v4->newObject();
- p->prototype = NodePrototype::getProto(v4).asObject();
+ p->setPrototype(NodePrototype::getProto(v4).asObject());
p->defineAccessorProperty(v4, QStringLiteral("data"), NodePrototype::method_get_nodeValue, 0);
p->defineAccessorProperty(v4, QStringLiteral("length"), length, 0);
d->characterDataPrototype = Value::fromObject(p);
@@ -704,7 +704,7 @@ Value Text::prototype(ExecutionEngine *v4)
QQmlXMLHttpRequestData *d = xhrdata(v4->v8Engine);
if (d->textPrototype.isEmpty()) {
Object *p = v4->newObject();
- p->prototype = CharacterData::prototype(v4).asObject();
+ p->setPrototype(CharacterData::prototype(v4).asObject());
p->defineAccessorProperty(v4, QStringLiteral("isElementContentWhitespace"), isElementContentWhitespace, 0);
p->defineAccessorProperty(v4, QStringLiteral("wholeText"), wholeText, 0);
d->textPrototype = Value::fromObject(p);
@@ -719,7 +719,7 @@ Value CDATA::prototype(ExecutionEngine *v4)
QQmlXMLHttpRequestData *d = xhrdata(v4->v8Engine);
if (d->cdataPrototype.isEmpty()) {
Object *p = v4->newObject();
- p->prototype = Text::prototype(v4).asObject();
+ p->setPrototype(Text::prototype(v4).asObject());
d->cdataPrototype = Value::fromObject(p);
v4->v8Engine->freezeObject(d->cdataPrototype);
}
@@ -731,7 +731,7 @@ Value Document::prototype(ExecutionEngine *v4)
QQmlXMLHttpRequestData *d = xhrdata(v4->v8Engine);
if (d->documentPrototype.isEmpty()) {
Object *p = v4->newObject();
- p->prototype = NodePrototype::getProto(v4).asObject();
+ p->setPrototype(NodePrototype::getProto(v4).asObject());
p->defineAccessorProperty(v4, QStringLiteral("xmlVersion"), xmlVersion, 0);
p->defineAccessorProperty(v4, QStringLiteral("xmlEncoding"), xmlEncoding, 0);
p->defineAccessorProperty(v4, QStringLiteral("xmlStandalone"), xmlStandalone, 0);
@@ -826,7 +826,7 @@ Value Document::load(QV8Engine *engine, const QByteArray &data)
}
Object *instance = new (v4->memoryManager) Node(v4, document);
- instance->prototype = Document::prototype(v4).asObject();
+ instance->setPrototype(Document::prototype(v4).asObject());
return Value::fromObject(instance);
}
@@ -893,7 +893,7 @@ Value NamedNodeMap::create(QV8Engine *engine, NodeImpl *data, const QList<NodeIm
ExecutionEngine *v4 = QV8Engine::getV4(engine);
NamedNodeMap *instance = new (v4->memoryManager) NamedNodeMap(v4, data, list);
- instance->prototype = v4->objectPrototype;
+ instance->setPrototype(v4->objectPrototype);
return Value::fromObject(instance);
}
@@ -935,7 +935,7 @@ Value NodeList::create(QV8Engine *engine, NodeImpl *data)
QQmlXMLHttpRequestData *d = xhrdata(engine);
ExecutionEngine *v4 = QV8Engine::getV4(engine);
NodeList *instance = new (v4->memoryManager) NodeList(v4, data);
- instance->prototype = v4->objectPrototype;
+ instance->setPrototype(v4->objectPrototype);
return Value::fromObject(instance);
}
@@ -1574,7 +1574,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
QV8Engine *engine = that->engine()->v8Engine;
QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(engine, engine->networkAccessManager());
QQmlXMLHttpRequestWrapper *w = new (that->engine()->memoryManager) QQmlXMLHttpRequestWrapper(that->engine(), r);
- w->prototype = ctor->proto;
+ w->setPrototype(ctor->proto);
return Value::fromObject(w);
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index ac1cdef30e..3f67de2782 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1309,7 +1309,7 @@ Value QtObject::method_get_inputMethod(SimpleCallContext *ctx)
QV4::ConsoleObject::ConsoleObject(ExecutionEngine *v4)
: Object(v4)
{
- prototype = v4->objectPrototype;
+ setPrototype(v4->objectPrototype);
defineDefaultProperty(v4, QStringLiteral("debug"), method_log);
defineDefaultProperty(v4, QStringLiteral("log"), method_log);
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 96c92c4c7c..117fea272c 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -825,7 +825,7 @@ bool QV8Engine::metaTypeFromJS(const QV4::Value &value, int type, void *data) {
return true;
} else if (QV4::Object *o = value.asObject()) {
// Look in the prototype chain.
- QV4::Object *proto = o->prototype;
+ QV4::Object *proto = o->prototype();
while (proto) {
bool canCast = false;
if (QV4::VariantObject *vo = proto->as<QV4::VariantObject>()) {
@@ -845,7 +845,7 @@ bool QV8Engine::metaTypeFromJS(const QV4::Value &value, int type, void *data) {
*reinterpret_cast<void* *>(data) = var.data();
return true;
}
- proto = proto->prototype;
+ proto = proto->prototype();
}
}
} else if (value.isNull() && name.endsWith('*')) {
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 91b20e6d81..b1b4862b18 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -2379,7 +2379,7 @@ QQmlV4Handle QQmlDelegateModelGroup::get(int index)
QV8Engine *v8 = model->m_cacheMetaType->v8Engine;
QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8);
QV4::Object *o = new (v4->memoryManager) QQmlDelegateModelItemObject(v4, cacheItem);
- o->prototype = model->m_cacheMetaType->modelItemProto.value().asObject();
+ o->setPrototype(model->m_cacheMetaType->modelItemProto.value().asObject());
++cacheItem->scriptRef;
return QQmlV4Handle(QV4::Value::fromObject(o));
@@ -3160,7 +3160,7 @@ public:
QV4::Object *changeProto = engineData(v4->v8Engine)->changeProto.value().asObject();
QQmlDelegateModelGroupChange *object = new (v4->memoryManager) QQmlDelegateModelGroupChange(v4);
- object->prototype = changeProto;
+ object->setPrototype(changeProto);
object->change = change;
if (hasProperty)
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
index 4e81275e2f..ffd9de0e16 100644
--- a/src/qml/util/qqmladaptormodel.cpp
+++ b/src/qml/util/qqmladaptormodel.cpp
@@ -429,7 +429,7 @@ public:
}
QV4::Object *proto = type->prototype.value().asObject();
QV4::Object *o = new (proto->engine()->memoryManager) QQmlDelegateModelItemObject(proto->engine(), this);
- o->prototype = proto;
+ o->setPrototype(proto);
QV4::Value data = QV4::Value::fromObject(o);
++scriptRef;
return data;
@@ -602,7 +602,7 @@ public:
{
QQmlAdaptorModelEngineData *data = engineData(v4->v8Engine);
QV4::Object *o = new (v4->memoryManager) QQmlDelegateModelItemObject(v4, this);
- o->prototype = data->listItemProto.value().asObject();
+ o->setPrototype(data->listItemProto.value().asObject());
QV4::Value val = QV4::Value::fromObject(o);
++scriptRef;
return val;