From edee5c3dc0d922ec3b6a44d66193e9a57b8a979e Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 29 Aug 2013 14:31:32 +0200 Subject: 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 --- src/qml/compiler/qv4compileddata.cpp | 2 + src/qml/jsapi/qjsvalue.cpp | 17 ++--- src/qml/jsruntime/qv4arrayobject.cpp | 4 +- src/qml/jsruntime/qv4arrayobject_p.h | 2 +- src/qml/jsruntime/qv4booleanobject_p.h | 2 +- src/qml/jsruntime/qv4dateobject_p.h | 3 +- src/qml/jsruntime/qv4engine.cpp | 116 ++++++++++++++------------------ src/qml/jsruntime/qv4engine_p.h | 1 + src/qml/jsruntime/qv4errorobject.cpp | 31 ++++++--- src/qml/jsruntime/qv4errorobject_p.h | 27 ++++---- src/qml/jsruntime/qv4functionobject.cpp | 29 ++++++-- src/qml/jsruntime/qv4functionobject_p.h | 3 +- src/qml/jsruntime/qv4internalclass.cpp | 25 +++++-- src/qml/jsruntime/qv4jsonobject.cpp | 2 +- src/qml/jsruntime/qv4lookup.cpp | 48 ++++++------- src/qml/jsruntime/qv4mathobject.cpp | 2 +- src/qml/jsruntime/qv4numberobject_p.h | 2 +- src/qml/jsruntime/qv4object.cpp | 46 +++++++------ src/qml/jsruntime/qv4object_p.h | 9 ++- src/qml/jsruntime/qv4objectiterator.cpp | 2 +- src/qml/jsruntime/qv4objectproto.cpp | 27 +++----- src/qml/jsruntime/qv4objectproto_p.h | 2 +- src/qml/jsruntime/qv4qobjectwrapper.cpp | 4 +- src/qml/jsruntime/qv4regexpobject.cpp | 8 +++ src/qml/jsruntime/qv4regexpobject_p.h | 4 +- src/qml/jsruntime/qv4runtime.cpp | 2 +- src/qml/jsruntime/qv4sequenceobject.cpp | 9 ++- src/qml/jsruntime/qv4sequenceobject_p.h | 2 +- src/qml/jsruntime/qv4stringobject.cpp | 11 +++ src/qml/jsruntime/qv4stringobject_p.h | 3 +- src/qml/jsruntime/qv4variantobject.cpp | 15 +++-- src/qml/jsruntime/qv4variantobject_p.h | 3 +- src/qml/qml/qqmlcomponent.cpp | 2 +- src/qml/qml/qqmlcontextwrapper.cpp | 4 +- src/qml/qml/qqmllistwrapper.cpp | 2 +- src/qml/qml/qqmllocale.cpp | 2 +- src/qml/qml/qqmltypewrapper.cpp | 4 +- src/qml/qml/qqmlvaluetypewrapper.cpp | 4 +- src/qml/qml/qqmlxmlhttprequest.cpp | 28 ++++---- src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 2 +- src/qml/qml/v8/qv8engine.cpp | 4 +- src/qml/types/qqmldelegatemodel.cpp | 4 +- src/qml/util/qqmladaptormodel.cpp | 4 +- 43 files changed, 292 insertions(+), 231 deletions(-) (limited to 'src/qml') 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 #include +#include #include #include #include @@ -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::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(that)->~Object(); @@ -267,8 +277,6 @@ void Object::defineReadonlyProperty(String *name, Value value) void Object::markObjects(Managed *that) { Object *o = static_cast(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(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); -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 QListmemoryManager) 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()) { @@ -845,7 +845,7 @@ bool QV8Engine::metaTypeFromJS(const QV4::Value &value, int type, void *data) { *reinterpret_cast(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; -- cgit v1.2.3