From fbcd0a22f643f0b0ec1404507d63bdf35cd9a195 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 21 Nov 2013 13:15:46 +0100 Subject: Move the vtable pointer from the object to the internal class This saves one pointer per object, and willmake other optimizations easier in the future. Change-Id: I1324cad31998896b5dc76af3c8a7ee9d86283bfe Reviewed-by: Simon Hausmann --- src/qml/debugger/qv4debugservice.cpp | 6 +- src/qml/jsruntime/qv4argumentsobject.cpp | 10 ++-- src/qml/jsruntime/qv4argumentsobject_p.h | 8 ++- src/qml/jsruntime/qv4arrayobject.cpp | 2 +- src/qml/jsruntime/qv4booleanobject.cpp | 2 +- src/qml/jsruntime/qv4context.cpp | 55 ++++++++---------- src/qml/jsruntime/qv4context_p.h | 98 ++++++++++++++++++++------------ src/qml/jsruntime/qv4dateobject.cpp | 4 +- src/qml/jsruntime/qv4dateobject_p.h | 4 +- src/qml/jsruntime/qv4debugging.cpp | 4 +- src/qml/jsruntime/qv4debugging_p.h | 2 +- src/qml/jsruntime/qv4engine.cpp | 17 ++++-- src/qml/jsruntime/qv4engine_p.h | 30 ---------- src/qml/jsruntime/qv4errorobject.cpp | 28 ++++----- src/qml/jsruntime/qv4errorobject_p.h | 12 ++-- src/qml/jsruntime/qv4functionobject.cpp | 27 ++++----- src/qml/jsruntime/qv4functionobject_p.h | 6 +- src/qml/jsruntime/qv4global_p.h | 2 + src/qml/jsruntime/qv4globalobject.cpp | 2 +- src/qml/jsruntime/qv4internalclass.cpp | 49 +++++++++++++++- src/qml/jsruntime/qv4internalclass_p.h | 13 ++++- src/qml/jsruntime/qv4managed.cpp | 23 +++++--- src/qml/jsruntime/qv4managed_p.h | 26 +++++---- src/qml/jsruntime/qv4mm.cpp | 10 ++-- src/qml/jsruntime/qv4numberobject.cpp | 2 +- src/qml/jsruntime/qv4object.cpp | 10 ++-- src/qml/jsruntime/qv4object_p.h | 16 +++--- src/qml/jsruntime/qv4objectiterator_p.h | 2 +- src/qml/jsruntime/qv4objectproto.cpp | 2 +- src/qml/jsruntime/qv4qobjectwrapper.cpp | 6 +- src/qml/jsruntime/qv4regexp.cpp | 2 +- src/qml/jsruntime/qv4regexpobject.cpp | 4 +- src/qml/jsruntime/qv4scopedvalue_p.h | 2 +- src/qml/jsruntime/qv4script.cpp | 6 +- src/qml/jsruntime/qv4sequenceobject.cpp | 4 +- src/qml/jsruntime/qv4string.cpp | 5 +- src/qml/jsruntime/qv4string_p.h | 2 +- src/qml/jsruntime/qv4stringobject.cpp | 6 +- src/qml/jsruntime/qv4variantobject.cpp | 4 +- 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 | 2 +- src/qml/qml/qqmlvaluetypewrapper.cpp | 2 +- src/qml/qml/qqmlxmlhttprequest.cpp | 12 ++-- src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 4 +- src/qml/types/qqmldelegatemodel.cpp | 6 +- src/qml/types/qqmldelegatemodel_p_p.h | 2 +- 49 files changed, 303 insertions(+), 248 deletions(-) (limited to 'src/qml') diff --git a/src/qml/debugger/qv4debugservice.cpp b/src/qml/debugger/qv4debugservice.cpp index 400bb18edd..1bf38dc15d 100644 --- a/src/qml/debugger/qv4debugservice.cpp +++ b/src/qml/debugger/qv4debugservice.cpp @@ -432,7 +432,7 @@ public: QJsonArray scopes; // Only type and index are used by Qt Creator, so we keep it easy: - QVector scopeTypes = debugger->getScopeTypes(frameNr); + QVector scopeTypes = debugger->getScopeTypes(frameNr); for (int i = 0, ei = scopeTypes.count(); i != ei; ++i) { int type = encodeScopeType(scopeTypes[i]); if (type == -1) @@ -448,7 +448,7 @@ public: return frame; } - int encodeScopeType(QV4::ExecutionContext::Type scopeType) + int encodeScopeType(QV4::ExecutionContext::ContextType scopeType) { switch (scopeType) { case QV4::ExecutionContext::Type_GlobalContext: @@ -480,7 +480,7 @@ public: QJsonObject anonymous; anonymous[QLatin1String("properties")] = properties; - QVector scopeTypes = debugger->getScopeTypes(frameNr); + QVector scopeTypes = debugger->getScopeTypes(frameNr); scope[QLatin1String("type")] = encodeScopeType(scopeTypes[scopeNr]); scope[QLatin1String("index")] = scopeNr; scope[QLatin1String("frameIndex")] = frameNr; diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index 749509c353..0fd0242111 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -47,9 +47,10 @@ using namespace QV4; DEFINE_MANAGED_VTABLE(ArgumentsObject); ArgumentsObject::ArgumentsObject(CallContext *context) - : Object(context->engine), context(context), fullyCreated(false) + : Object(context->strictMode ? context->engine->strictArgumentsObjectClass : context->engine->argumentsObjectClass) + , context(context) + , fullyCreated(false) { - vtbl = &static_vtbl; type = Type_ArgumentsObject; flags &= ~SimpleArray; @@ -58,8 +59,6 @@ ArgumentsObject::ArgumentsObject(CallContext *context) ScopedObject protectThis(scope, this); if (context->strictMode) { - internalClass = v4->strictArgumentsObjectClass; - Property pd = Property::fromAccessor(v4->thrower, v4->thrower); Q_ASSERT(CalleePropertyIndex == internalClass->find(context->engine->id_callee)); Q_ASSERT(CallerPropertyIndex == internalClass->find(context->engine->id_caller)); @@ -72,7 +71,6 @@ ArgumentsObject::ArgumentsObject(CallContext *context) arrayDataLen = context->callData->argc; fullyCreated = true; } else { - internalClass = engine()->argumentsObjectClass; Q_ASSERT(CalleePropertyIndex == internalClass->find(context->engine->id_callee)); memberData[CalleePropertyIndex].value = context->function->asReturnedValue(); isNonStrictArgumentsObject = true; @@ -80,6 +78,8 @@ ArgumentsObject::ArgumentsObject(CallContext *context) Q_ASSERT(LengthPropertyIndex == internalClass->find(context->engine->id_length)); Property *lp = memberData + ArrayObject::LengthPropertyIndex; lp->value = Primitive::fromInt32(context->realArgumentCount); + + setVTable(&static_vtbl); } void ArgumentsObject::destroy(Managed *that) diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h index 7c58c48bcc..d306fae92b 100644 --- a/src/qml/jsruntime/qv4argumentsobject_p.h +++ b/src/qml/jsruntime/qv4argumentsobject_p.h @@ -54,7 +54,9 @@ struct ArgumentsGetterFunction: FunctionObject uint index; ArgumentsGetterFunction(ExecutionContext *scope, uint index) - : FunctionObject(scope), index(index) { vtbl = &static_vtbl; } + : FunctionObject(scope), index(index) { + setVTable(&static_vtbl); + } static ReturnedValue call(Managed *that, CallData *d); }; @@ -65,7 +67,9 @@ struct ArgumentsSetterFunction: FunctionObject uint index; ArgumentsSetterFunction(ExecutionContext *scope, uint index) - : FunctionObject(scope), index(index) { vtbl = &static_vtbl; } + : FunctionObject(scope), index(index) { + setVTable(&static_vtbl); + } static ReturnedValue call(Managed *that, CallData *callData); }; diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index a0f0345b8b..39b9b9eb60 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -51,7 +51,7 @@ DEFINE_MANAGED_VTABLE(ArrayCtor); ArrayCtor::ArrayCtor(ExecutionContext *scope) : FunctionObject(scope, QStringLiteral("Array")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue ArrayCtor::construct(Managed *m, CallData *callData) diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp index a0d0027e5f..f8edfb7850 100644 --- a/src/qml/jsruntime/qv4booleanobject.cpp +++ b/src/qml/jsruntime/qv4booleanobject.cpp @@ -49,7 +49,7 @@ DEFINE_MANAGED_VTABLE(BooleanObject); BooleanCtor::BooleanCtor(ExecutionContext *scope) : FunctionObject(scope, QStringLiteral("Boolean")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue BooleanCtor::construct(Managed *m, CallData *callData) diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index aea7827832..f9b63ac12a 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -76,12 +76,10 @@ const ManagedVTable ExecutionContext::static_vtbl = CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData *callData) { CallContext *c = static_cast(engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(function, callData->argc))); - c->init(); + new (c) CallContext(engine, this, Type_CallContext); engine->current = c; - c->initBaseContext(Type_CallContext, engine, this); - c->function = function; c->realArgumentCount = callData->argc; @@ -114,28 +112,22 @@ CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData WithContext *ExecutionContext::newWithContext(ObjectRef with) { - WithContext *w = new (engine->memoryManager) WithContext; + WithContext *w = new (engine->memoryManager) WithContext(this, with); engine->current = w; - w->initWithContext(this, with); return w; } CatchContext *ExecutionContext::newCatchContext(const StringRef exceptionVarName, const ValueRef exceptionValue) { - CatchContext *c = new (engine->memoryManager) CatchContext; + CatchContext *c = new (engine->memoryManager) CatchContext(this, exceptionVarName, exceptionValue); engine->current = c; - c->initCatchContext(this, exceptionVarName, exceptionValue); return c; } CallContext *ExecutionContext::newQmlContext(FunctionObject *f, ObjectRef qml) { CallContext *c = static_cast(engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(f, 0))); - c->init(); - - engine->current = c; - c->initQmlContext(this, qml, f); - + new (c) CallContext(this, qml, f); return c; } @@ -200,20 +192,22 @@ unsigned int ExecutionContext::variableCount() const } -void GlobalContext::initGlobalContext(ExecutionEngine *eng) +GlobalContext::GlobalContext(ExecutionEngine *eng, ExecutionContext *parent) + : ExecutionContext(eng, Type_GlobalContext, parent) { - initBaseContext(Type_GlobalContext, eng, /*parentContext*/0); - callData = reinterpret_cast(this + 1); - callData->tag = QV4::Value::_Integer_Type; - callData->argc = 0; - callData->thisObject = eng->globalObject; - callData->args[0] = Encode::undefined(); + if (!parent) { + callData = reinterpret_cast(this + 1); + callData->tag = QV4::Value::_Integer_Type; + callData->argc = 0; + callData->thisObject = eng->globalObject; + callData->args[0] = Encode::undefined(); + } global = 0; } -void WithContext::initWithContext(ExecutionContext *p, ObjectRef with) +WithContext::WithContext(ExecutionContext *p, ObjectRef with) + : ExecutionContext(p->engine, Type_WithContext, p) { - initBaseContext(Type_WithContext, p->engine, p); callData = p->callData; outer = p; lookups = p->lookups; @@ -222,9 +216,9 @@ void WithContext::initWithContext(ExecutionContext *p, ObjectRef with) withObject = with.getPointer(); } -void CatchContext::initCatchContext(ExecutionContext *p, const StringRef exceptionVarName, const ValueRef exceptionValue) +CatchContext::CatchContext(ExecutionContext *p, const StringRef exceptionVarName, const ValueRef exceptionValue) + : ExecutionContext(p->engine, Type_CatchContext, p) { - initBaseContext(Type_CatchContext, p->engine, p); strictMode = p->strictMode; callData = p->callData; outer = p; @@ -235,18 +229,17 @@ void CatchContext::initCatchContext(ExecutionContext *p, const StringRef excepti this->exceptionValue = exceptionValue; } -void CallContext::initQmlContext(ExecutionContext *parentContext, ObjectRef qml, FunctionObject *function) +CallContext::CallContext(ExecutionContext *parentContext, ObjectRef qml, FunctionObject *function) + : ExecutionContext(parentContext->engine, Type_QmlContext, parentContext) { - initBaseContext(Type_QmlContext, parentContext->engine, parentContext); - this->function = function; - this->callData = reinterpret_cast(this + 1); - this->callData->tag = QV4::Value::_Integer_Type; - this->callData->argc = 0; - this->callData->thisObject = Primitive::undefinedValue(); + callData = reinterpret_cast(this + 1); + callData->tag = QV4::Value::_Integer_Type; + callData->argc = 0; + callData->thisObject = Primitive::undefinedValue(); strictMode = true; - this->outer = function->scope; + outer = function->scope; #ifndef QT_NO_DEBUG assert(outer->next != (ExecutionContext *)0x1); #endif diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index c06c10453b..2cdcf2b906 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -44,6 +44,7 @@ #include "qv4global_p.h" #include "qv4value_def_p.h" #include "qv4managed_p.h" +#include "qv4engine_p.h" QT_BEGIN_NAMESPACE @@ -69,19 +70,8 @@ struct WithContext; struct Q_QML_EXPORT ExecutionContext : public Managed { Q_MANAGED - ExecutionContext() - : Managed(0) { - vtbl = &static_vtbl; - } - void init() { - _data = 0; - internalClass = 0; - inUse = 1; - extensible = 1; - vtbl = &static_vtbl; - } - enum Type { + enum ContextType { Type_GlobalContext = 0x1, Type_CatchContext = 0x2, Type_WithContext = 0x3, @@ -90,7 +80,23 @@ struct Q_QML_EXPORT ExecutionContext : public Managed Type_QmlContext = 0x6 }; - Type type; + ExecutionContext(ExecutionEngine *engine, ContextType t, ExecutionContext *parent) + : Managed(engine->emptyClass) + { + setVTable(&static_vtbl); + this->type = t; + strictMode = false; + this->engine = engine; + this->parent = parent; + outer = 0; + lookups = 0; + compilationUnit = 0; + currentEvalCode = 0; + interpreterInstructionPointer = 0; + lineNumber = -1; + } + + ContextType type; bool strictMode; CallData *callData; @@ -112,20 +118,6 @@ struct Q_QML_EXPORT ExecutionContext : public Managed const uchar **interpreterInstructionPointer; int lineNumber; - void initBaseContext(Type type, ExecutionEngine *engine, ExecutionContext *parentContext) - { - this->type = type; - strictMode = false; - this->engine = engine; - parent = parentContext; - outer = 0; - lookups = 0; - compilationUnit = 0; - currentEvalCode = 0; - interpreterInstructionPointer = 0; - lineNumber = -1; - } - CallContext *newCallContext(FunctionObject *f, CallData *callData); WithContext *newWithContext(ObjectRef with); CatchContext *newCatchContext(const StringRef exceptionVarName, const ValueRef exceptionValue); @@ -168,17 +160,20 @@ struct Q_QML_EXPORT ExecutionContext : public Managed struct CallContext : public ExecutionContext { + CallContext(ExecutionEngine *engine, ExecutionContext *parent, ContextType t = Type_SimpleCallContext) + : ExecutionContext(engine, t, parent) + { + function = 0; + locals = 0; + activation = 0; + } + CallContext(ExecutionContext *parentContext, ObjectRef qml, QV4::FunctionObject *function); + FunctionObject *function; int realArgumentCount; SafeValue *locals; Object *activation; - void initSimpleCallContext(ExecutionEngine *engine, ExecutionContext *parent) { - initBaseContext(Type_SimpleCallContext, engine, parent); - function = 0; - locals = 0; - activation = 0; - } void initQmlContext(ExecutionContext *parentContext, ObjectRef qml, QV4::FunctionObject *function); inline ReturnedValue argument(int i); @@ -187,14 +182,14 @@ struct CallContext : public ExecutionContext struct GlobalContext : public ExecutionContext { - void initGlobalContext(ExecutionEngine *e); + GlobalContext(ExecutionEngine *engine, ExecutionContext *parent = 0); Object *global; }; struct CatchContext : public ExecutionContext { - void initCatchContext(ExecutionContext *p, const StringRef exceptionVarName, const ValueRef exceptionValue); + CatchContext(ExecutionContext *p, const StringRef exceptionVarName, const ValueRef exceptionValue); SafeString exceptionVarName; SafeValue exceptionValue; @@ -202,9 +197,8 @@ struct CatchContext : public ExecutionContext struct WithContext : public ExecutionContext { + WithContext(ExecutionContext *p, ObjectRef with); Object *withObject; - - void initWithContext(ExecutionContext *p, ObjectRef with); }; inline CallContext *ExecutionContext::asCallContext() @@ -217,6 +211,36 @@ inline const CallContext *ExecutionContext::asCallContext() const return type >= Type_SimpleCallContext ? static_cast(this) : 0; } + +inline void ExecutionEngine::pushContext(CallContext *context) +{ + context->parent = current; + current = context; + current->currentEvalCode = 0; +} + +inline ExecutionContext *ExecutionEngine::popContext() +{ + current = current->parent; + return current; +} + +struct ExecutionContextSaver +{ + ExecutionEngine *engine; + ExecutionContext *savedContext; + + ExecutionContextSaver(ExecutionContext *context) + : engine(context->engine) + , savedContext(context) + { + } + ~ExecutionContextSaver() + { + engine->current = savedContext; + } +}; + /* Function *f, int argc */ #define requiredMemoryForExecutionContect(f, argc) \ sizeof(CallContext) + sizeof(Value) * (f->varCount + qMax((uint)argc, f->formalParameterCount)) + sizeof(CallData) diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index b732c8a04a..5d0c8ccf8e 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -646,7 +646,7 @@ DEFINE_MANAGED_VTABLE(DateObject); DateObject::DateObject(ExecutionEngine *engine, const QDateTime &date) : Object(engine->dateClass) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_DateObject; value.setDouble(date.isValid() ? date.toMSecsSinceEpoch() : qSNaN()); } @@ -661,7 +661,7 @@ DEFINE_MANAGED_VTABLE(DateCtor); DateCtor::DateCtor(ExecutionContext *scope) : FunctionObject(scope, QStringLiteral("Date")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue DateCtor::construct(Managed *m, CallData *callData) diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h index e96cac2f20..f74037a32a 100644 --- a/src/qml/jsruntime/qv4dateobject_p.h +++ b/src/qml/jsruntime/qv4dateobject_p.h @@ -55,7 +55,7 @@ struct DateObject: Object { Q_MANAGED SafeValue value; DateObject(ExecutionEngine *engine, const ValueRef date): Object(engine->dateClass) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_DateObject; value = date; } @@ -65,7 +65,7 @@ struct DateObject: Object { protected: DateObject(InternalClass *ic): Object(ic) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_DateObject; value = Primitive::fromDouble(qSNaN()); } diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp index 1673428c0b..e14ea252fb 100644 --- a/src/qml/jsruntime/qv4debugging.cpp +++ b/src/qml/jsruntime/qv4debugging.cpp @@ -449,9 +449,9 @@ void Debugger::collectReturnedValue(Collector *collector) const collector->collect(o); } -QVector Debugger::getScopeTypes(int frame) const +QVector Debugger::getScopeTypes(int frame) const { - QVector types; + QVector types; if (state() != Paused) return types; diff --git a/src/qml/jsruntime/qv4debugging_p.h b/src/qml/jsruntime/qv4debugging_p.h index 98b549995e..0e19c51935 100644 --- a/src/qml/jsruntime/qv4debugging_p.h +++ b/src/qml/jsruntime/qv4debugging_p.h @@ -163,7 +163,7 @@ public: bool collectThisInContext(Collector *collector, int frame = 0); void collectThrownValue(Collector *collector); void collectReturnedValue(Collector *collector) const; - QVector getScopeTypes(int frame = 0) const; + QVector getScopeTypes(int frame = 0) const; public: // compile-time interface void maybeBreakAtInstruction(const uchar *code, bool breakPointHit); diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 50db0e09fb..b50d4d87e5 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ #include +#include #include #include #include @@ -215,16 +216,22 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory) id_valueOf = newIdentifier(QStringLiteral("valueOf")); ObjectPrototype *objectPrototype = new (memoryManager) ObjectPrototype(emptyClass); - objectClass = emptyClass->changePrototype(objectPrototype); + objectClass = emptyClass->changeVTable(&Object::static_vtbl); + objectClass = objectClass->changePrototype(objectPrototype); + Q_ASSERT(objectClass->vtable == &Object::static_vtbl); arrayClass = objectClass->addMember(id_length, Attr_NotConfigurable|Attr_NotEnumerable); ArrayPrototype *arrayPrototype = new (memoryManager) ArrayPrototype(arrayClass); arrayClass = arrayClass->changePrototype(arrayPrototype); - InternalClass *argsClass = objectClass->addMember(id_length, Attr_NotEnumerable); + InternalClass *argsClass = objectClass->changeVTable(&ArgumentsObject::static_vtbl); + argsClass = argsClass->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); + Q_ASSERT(argumentsObjectClass->vtable == &ArgumentsObject::static_vtbl); + Q_ASSERT(strictArgumentsObjectClass->vtable == &ArgumentsObject::static_vtbl); + initRootContext(); StringPrototype *stringPrototype = new (memoryManager) StringPrototype(objectClass); @@ -391,10 +398,9 @@ void ExecutionEngine::enableDebugger() void ExecutionEngine::initRootContext() { rootContext = static_cast(memoryManager->allocManaged(sizeof(GlobalContext) + sizeof(CallData))); - rootContext->init(); + new (rootContext) GlobalContext(this); current = rootContext; current->parent = 0; - rootContext->initGlobalContext(this); } InternalClass *ExecutionEngine::newClass(const InternalClass &other) @@ -404,11 +410,10 @@ InternalClass *ExecutionEngine::newClass(const InternalClass &other) ExecutionContext *ExecutionEngine::pushGlobalContext() { - GlobalContext *g = new (memoryManager) GlobalContext; + GlobalContext *g = new (memoryManager) GlobalContext(this, current); ExecutionContext *oldNext = g->next; memcpy(g, rootContext, sizeof(GlobalContext)); g->next = oldNext; - g->parent = current; current = g; return current; diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index c37d4f125d..77378fbc5b 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -44,7 +44,6 @@ #include "qv4global_p.h" #include "private/qv4isel_p.h" #include "qv4util_p.h" -#include "qv4context_p.h" #include "qv4property_p.h" #include @@ -356,35 +355,6 @@ private: QmlExtensions *m_qmlExtensions; }; -inline void ExecutionEngine::pushContext(CallContext *context) -{ - context->parent = current; - current = context; - current->currentEvalCode = 0; -} - -inline ExecutionContext *ExecutionEngine::popContext() -{ - current = current->parent; - return current; -} - -struct ExecutionContextSaver -{ - ExecutionEngine *engine; - ExecutionContext *savedContext; - - ExecutionContextSaver(ExecutionContext *context) - : engine(context->engine) - , savedContext(context) - { - } - ~ExecutionContextSaver() - { - engine->current = savedContext; - } -}; - inline void Managed::mark(QV4::ExecutionEngine *engine) { diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp index bac29d19e1..d5b4975b72 100644 --- a/src/qml/jsruntime/qv4errorobject.cpp +++ b/src/qml/jsruntime/qv4errorobject.cpp @@ -77,7 +77,7 @@ ErrorObject::ErrorObject(InternalClass *ic) , stack(0) { type = Type_ErrorObject; - vtbl = &static_vtbl; + setVTable(&static_vtbl); Scope scope(engine()); ScopedValue protectThis(scope, this); @@ -91,7 +91,7 @@ ErrorObject::ErrorObject(InternalClass *ic, const ValueRef message, ErrorType t) , stack(0) { type = Type_ErrorObject; - vtbl = &static_vtbl; + setVTable(&static_vtbl); subtype = t; Scope scope(engine()); @@ -116,7 +116,7 @@ ErrorObject::ErrorObject(InternalClass *ic, const QString &message, ErrorObject: , stack(0) { type = Type_ErrorObject; - vtbl = &static_vtbl; + setVTable(&static_vtbl); subtype = t; Scope scope(engine()); @@ -141,7 +141,7 @@ ErrorObject::ErrorObject(InternalClass *ic, const QString &message, const QStrin , stack(0) { type = Type_ErrorObject; - vtbl = &static_vtbl; + setVTable(&static_vtbl); subtype = t; Scope scope(engine()); @@ -207,13 +207,13 @@ DEFINE_MANAGED_VTABLE(SyntaxErrorObject); SyntaxErrorObject::SyntaxErrorObject(ExecutionEngine *engine, const ValueRef msg) : ErrorObject(engine->syntaxErrorClass, msg, SyntaxError) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } SyntaxErrorObject::SyntaxErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber) : ErrorObject(engine->syntaxErrorClass, msg, fileName, lineNumber, columnNumber, SyntaxError) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } EvalErrorObject::EvalErrorObject(ExecutionEngine *engine, const ValueRef message) @@ -272,13 +272,13 @@ DEFINE_MANAGED_VTABLE(URIErrorCtor); ErrorCtor::ErrorCtor(ExecutionContext *scope) : FunctionObject(scope, QStringLiteral("Error")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ErrorCtor::ErrorCtor(ExecutionContext *scope, const QString &name) : FunctionObject(scope, name) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue ErrorCtor::construct(Managed *m, CallData *callData) @@ -296,7 +296,7 @@ ReturnedValue ErrorCtor::call(Managed *that, CallData *callData) EvalErrorCtor::EvalErrorCtor(ExecutionContext *scope) : ErrorCtor(scope, QStringLiteral("EvalError")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue EvalErrorCtor::construct(Managed *m, CallData *callData) @@ -309,7 +309,7 @@ ReturnedValue EvalErrorCtor::construct(Managed *m, CallData *callData) RangeErrorCtor::RangeErrorCtor(ExecutionContext *scope) : ErrorCtor(scope, QStringLiteral("RangeError")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue RangeErrorCtor::construct(Managed *m, CallData *callData) @@ -322,7 +322,7 @@ ReturnedValue RangeErrorCtor::construct(Managed *m, CallData *callData) ReferenceErrorCtor::ReferenceErrorCtor(ExecutionContext *scope) : ErrorCtor(scope, QStringLiteral("ReferenceError")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue ReferenceErrorCtor::construct(Managed *m, CallData *callData) @@ -335,7 +335,7 @@ ReturnedValue ReferenceErrorCtor::construct(Managed *m, CallData *callData) SyntaxErrorCtor::SyntaxErrorCtor(ExecutionContext *scope) : ErrorCtor(scope, QStringLiteral("SyntaxError")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue SyntaxErrorCtor::construct(Managed *m, CallData *callData) @@ -348,7 +348,7 @@ ReturnedValue SyntaxErrorCtor::construct(Managed *m, CallData *callData) TypeErrorCtor::TypeErrorCtor(ExecutionContext *scope) : ErrorCtor(scope, QStringLiteral("TypeError")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue TypeErrorCtor::construct(Managed *m, CallData *callData) @@ -361,7 +361,7 @@ ReturnedValue TypeErrorCtor::construct(Managed *m, CallData *callData) URIErrorCtor::URIErrorCtor(ExecutionContext *scope) : ErrorCtor(scope, QStringLiteral("URIError")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue URIErrorCtor::construct(Managed *m, CallData *callData) diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h index 3f4cb8fc43..def776d3b6 100644 --- a/src/qml/jsruntime/qv4errorobject_p.h +++ b/src/qml/jsruntime/qv4errorobject_p.h @@ -184,37 +184,37 @@ struct ErrorPrototype: ErrorObject struct EvalErrorPrototype: ErrorObject { - EvalErrorPrototype(InternalClass *ic): ErrorObject(ic) { vtbl = &static_vtbl; } + EvalErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(&static_vtbl); } void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); } }; struct RangeErrorPrototype: ErrorObject { - RangeErrorPrototype(InternalClass *ic): ErrorObject(ic) { vtbl = &static_vtbl; } + RangeErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(&static_vtbl); } void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); } }; struct ReferenceErrorPrototype: ErrorObject { - ReferenceErrorPrototype(InternalClass *ic): ErrorObject(ic) { vtbl = &static_vtbl; } + ReferenceErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(&static_vtbl); } void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); } }; struct SyntaxErrorPrototype: ErrorObject { - SyntaxErrorPrototype(InternalClass *ic): ErrorObject(ic) { vtbl = &static_vtbl; } + SyntaxErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(&static_vtbl); } void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); } }; struct TypeErrorPrototype: ErrorObject { - TypeErrorPrototype(InternalClass *ic): ErrorObject(ic) { vtbl = &static_vtbl; } + TypeErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(&static_vtbl); } void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); } }; struct URIErrorPrototype: ErrorObject { - URIErrorPrototype(InternalClass *ic): ErrorObject(ic) { vtbl = &static_vtbl; } + URIErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(&static_vtbl); } void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); } }; diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index b9859d20e5..6ca11879ec 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -110,7 +110,7 @@ FunctionObject::FunctionObject(InternalClass *ic) , varCount(0) , function(0) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); name = ic->engine->id_undefined; type = Type_FunctionObject; @@ -126,7 +126,7 @@ FunctionObject::~FunctionObject() void FunctionObject::init(const StringRef n, bool createProto) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); name = n; Scope s(internalClass->engine); @@ -221,7 +221,7 @@ DEFINE_MANAGED_VTABLE(FunctionCtor); FunctionCtor::FunctionCtor(ExecutionContext *scope) : FunctionObject(scope, QStringLiteral("Function")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } // 15.3.2 @@ -386,7 +386,7 @@ DEFINE_MANAGED_VTABLE(ScriptFunction); ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function) : FunctionObject(scope, function->name, true) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); Scope s(scope); ScopedValue protectThis(s, this); @@ -471,7 +471,7 @@ DEFINE_MANAGED_VTABLE(SimpleScriptFunction); SimpleScriptFunction::SimpleScriptFunction(ExecutionContext *scope, Function *function) : FunctionObject(scope, function->name, true) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); Scope s(scope); ScopedValue protectThis(s, this); @@ -519,8 +519,7 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData) ExecutionContext *context = v4->current; - CallContext ctx; - ctx.initSimpleCallContext(v4, context); + CallContext ctx(v4, context); ctx.strictMode = f->strictMode; ctx.callData = callData; ctx.function = f.getPointer(); @@ -557,8 +556,7 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData) Scope scope(v4); ExecutionContext *context = v4->current; - CallContext ctx; - ctx.initSimpleCallContext(v4, context); + CallContext ctx(v4, context); ctx.strictMode = f->strictMode; ctx.callData = callData; ctx.function = f; @@ -588,7 +586,7 @@ BuiltinFunction::BuiltinFunction(ExecutionContext *scope, const StringRef name, : FunctionObject(scope, name) , code(code) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue BuiltinFunction::construct(Managed *f, CallData *) @@ -606,8 +604,7 @@ ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData) ExecutionContext *context = v4->current; - CallContext ctx; - ctx.initSimpleCallContext(v4, context); + CallContext ctx(v4, context); ctx.strictMode = f->scope->strictMode; // ### needed? scope or parent context? ctx.callData = callData; v4->pushContext(&ctx); @@ -625,10 +622,8 @@ ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData) CHECK_STACK_LIMITS(v4); ExecutionContext *context = v4->current; - Scope scope(v4); - CallContext ctx; - ctx.initSimpleCallContext(v4, context); + CallContext ctx(v4, context); ctx.strictMode = f->scope->strictMode; // ### needed? scope or parent context? ctx.callData = callData; v4->pushContext(&ctx); @@ -646,7 +641,7 @@ BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObjectRef target, , target(target) , boundArgs(boundArgs) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); subtype = FunctionObject::BoundFunction; this->boundThis = boundThis; diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index 990989363c..2e1f1d1180 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -125,10 +125,10 @@ struct Q_QML_EXPORT FunctionObject: Object { static ReturnedValue construct(Managed *that, CallData *); static ReturnedValue call(Managed *that, CallData *d); inline ReturnedValue construct(CallData *callData) { - return vtbl->construct(this, callData); + return internalClass->vtable->construct(this, callData); } inline ReturnedValue call(CallData *callData) { - return vtbl->call(this, callData); + return internalClass->vtable->call(this, callData); } static FunctionObject *cast(const Value &v) { @@ -194,7 +194,7 @@ struct IndexedBuiltinFunction: FunctionObject , code(code) , index(index) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } static ReturnedValue construct(Managed *m, CallData *) diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index 7d7338f19c..1d465df0c0 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -119,6 +119,8 @@ struct Object; struct ObjectPrototype; struct ObjectIterator; struct ExecutionContext; +struct GlobalContext; +struct CallContext; struct ScriptFunction; struct InternalClass; struct Property; diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp index 33a97554ca..d4c4dbfa31 100644 --- a/src/qml/jsruntime/qv4globalobject.cpp +++ b/src/qml/jsruntime/qv4globalobject.cpp @@ -349,7 +349,7 @@ DEFINE_MANAGED_VTABLE(EvalFunction); EvalFunction::EvalFunction(ExecutionContext *scope) : FunctionObject(scope, scope->engine->id_eval) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(1)); } diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index cb799a473c..3b4890fcb3 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -126,10 +126,21 @@ uint PropertyHash::lookup(const Identifier *identifier) const } } +InternalClass::InternalClass(ExecutionEngine *engine) + : engine(engine) + , prototype(0) + , vtable(&Managed::static_vtbl) + , m_sealed(0) + , m_frozen(0) + , size(0) +{ +} + InternalClass::InternalClass(const QV4::InternalClass &other) : engine(other.engine) , prototype(other.prototype) + , vtable(other.vtable) , propertyTable(other.propertyTable) , nameMap(other.nameMap) , propertyData(other.propertyData) @@ -184,11 +195,41 @@ InternalClass *InternalClass::changePrototype(Object *proto) // create a new class and add it to the tree InternalClass *newClass; - if (this == engine->emptyClass) { + if (!size) { newClass = engine->newClass(*this); newClass->prototype = proto; } else { - newClass = engine->emptyClass->changePrototype(proto); + newClass = engine->emptyClass->changeVTable(vtable); + newClass = newClass->changePrototype(proto); + for (uint i = 0; i < size; ++i) + newClass = newClass->addMember(nameMap.at(i), propertyData.at(i)); + } + + transitions.insert(t, newClass); + return newClass; +} + +InternalClass *InternalClass::changeVTable(const ManagedVTable *vt) +{ + if (vtable == vt) + return this; + + Transition t; + t.vtable = vt; + t.flags = Transition::VTableChange; + + QHash::const_iterator tit = transitions.constFind(t); + if (tit != transitions.constEnd()) + return tit.value(); + + // create a new class and add it to the tree + InternalClass *newClass; + if (this == engine->emptyClass) { + newClass = engine->newClass(*this); + newClass->vtable = vt; + } else { + newClass = engine->emptyClass->changeVTable(vt); + newClass = newClass->changePrototype(prototype); for (uint i = 0; i < size; ++i) newClass = newClass->addMember(nameMap.at(i), propertyData.at(i)); } @@ -343,7 +384,9 @@ void InternalClass::markObjects() for (QHash::ConstIterator it = transitions.begin(), end = transitions.end(); it != end; ++it) { - if (it.key().flags == Transition::ProtoChange) { + if (it.key().flags == Transition::VTableChange) { + it.value()->markObjects(); + } else if (it.key().flags == Transition::ProtoChange) { Q_ASSERT(it.value()->prototype); it.value()->prototype->mark(engine); } diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h index 9586637b32..621a6abc99 100644 --- a/src/qml/jsruntime/qv4internalclass_p.h +++ b/src/qml/jsruntime/qv4internalclass_p.h @@ -53,6 +53,7 @@ struct String; struct ExecutionEngine; struct Object; struct Identifier; +struct ManagedVTable; struct PropertyHashData; struct PropertyHash @@ -198,9 +199,14 @@ struct InternalClassTransition union { Identifier *id; Object *prototype; + const ManagedVTable *vtable; }; int flags; - enum { ProtoChange = 0x100 }; + enum { + // range 0-0xff is reserved for attribute changes + ProtoChange = 0x100, + VTableChange = 0x200 + }; bool operator==(const InternalClassTransition &other) const { return id == other.id && flags == other.flags; } @@ -210,6 +216,8 @@ uint qHash(const QV4::InternalClassTransition &t, uint = 0); struct InternalClass { ExecutionEngine *engine; Object *prototype; + const ManagedVTable *vtable; + PropertyHash propertyTable; // id to valueIndex SharedInternalClassData nameMap; SharedInternalClassData propertyData; @@ -223,6 +231,7 @@ struct InternalClass { uint size; InternalClass *changePrototype(Object *proto); + InternalClass *changeVTable(const ManagedVTable *vt); InternalClass *addMember(StringRef string, PropertyAttributes data, uint *index = 0); InternalClass *addMember(String *string, PropertyAttributes data, uint *index = 0); InternalClass *changeMember(String *string, PropertyAttributes data, uint *index = 0); @@ -238,7 +247,7 @@ struct InternalClass { private: friend struct ExecutionEngine; - InternalClass(ExecutionEngine *engine) : engine(engine), prototype(0), m_sealed(0), m_frozen(0), size(0) {} + InternalClass(ExecutionEngine *engine); InternalClass(const InternalClass &other); }; diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp index 895ae8d91b..9b52abb9ac 100644 --- a/src/qml/jsruntime/qv4managed.cpp +++ b/src/qml/jsruntime/qv4managed.cpp @@ -81,7 +81,6 @@ void Managed::operator delete(void *ptr) return; Managed *m = static_cast(ptr); - m->vtbl = 0; m->_data = 0; m->markBit = 0; m->~Managed(); @@ -177,6 +176,12 @@ QString Managed::className() const return QString::fromLatin1(s); } +void Managed::setVTable(const ManagedVTable *vt) +{ + Q_ASSERT(internalClass); + internalClass = internalClass->changeVTable(vt); +} + ReturnedValue Managed::construct(Managed *m, CallData *) { return m->engine()->current->throwTypeError(); @@ -204,40 +209,40 @@ bool Managed::isEqualTo(Managed *, Managed *) ReturnedValue Managed::get(const StringRef name, bool *hasProperty) { - return vtbl->get(this, name, hasProperty); + return internalClass->vtable->get(this, name, hasProperty); } ReturnedValue Managed::getIndexed(uint index, bool *hasProperty) { - return vtbl->getIndexed(this, index, hasProperty); + return internalClass->vtable->getIndexed(this, index, hasProperty); } void Managed::put(const StringRef name, const ValueRef value) { - vtbl->put(this, name, value); + internalClass->vtable->put(this, name, value); } void Managed::setLookup(Lookup *l, const ValueRef v) { - vtbl->setLookup(this, l, v); + internalClass->vtable->setLookup(this, l, v); } void Managed::putIndexed(uint index, const ValueRef value) { - vtbl->putIndexed(this, index, value); + internalClass->vtable->putIndexed(this, index, value); } PropertyAttributes Managed::query(StringRef name) const { - return vtbl->query(this, name); + return internalClass->vtable->query(this, name); } bool Managed::deleteProperty(const StringRef name) { - return vtbl->deleteProperty(this, name); + return internalClass->vtable->deleteProperty(this, name); } Property *Managed::advanceIterator(ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes) { - return vtbl->advanceIterator(this, it, name, index, attributes); + return internalClass->vtable->advanceIterator(this, it, name, index, attributes); } diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index 220363efff..79316ba40f 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -46,6 +46,7 @@ #include #include "qv4global_p.h" #include "qv4value_def_p.h" +#include "qv4internalclass_p.h" QT_BEGIN_NAMESPACE @@ -155,11 +156,12 @@ private: protected: Managed(InternalClass *internal) - : _data(0), vtbl(&static_vtbl), internalClass(internal) + : _data(0), internalClass(internal) { inUse = 1; extensible = 1; } public: void *operator new(size_t size, MemoryManager *mm); + void *operator new(size_t, Managed *m) { return m; } void operator delete(void *ptr); void operator delete(void *ptr, MemoryManager *mm); @@ -191,12 +193,12 @@ public: template T *as() { // ### FIXME: - if (!this) + if (!this || !internalClass) return 0; #if !defined(QT_NO_QOBJECT_CHECK) reinterpret_cast(this)->qt_check_for_QMANAGED_macro(*reinterpret_cast(this)); #endif - return vtbl == &T::static_vtbl ? static_cast(this) : 0; + return internalClass->vtable == &T::static_vtbl ? static_cast(this) : 0; } template const T *as() const { @@ -206,7 +208,7 @@ public: #if !defined(QT_NO_QOBJECT_CHECK) reinterpret_cast(this)->qt_check_for_QMANAGED_macro(*reinterpret_cast(const_cast(this))); #endif - return vtbl == &T::static_vtbl ? static_cast(this) : 0; + return internalClass->vtable == &T::static_vtbl ? static_cast(this) : 0; } String *asString() { return type == Type_String ? reinterpret_cast(this) : 0; } @@ -237,6 +239,8 @@ public: *reinterpret_cast(this) = m; } + void setVTable(const ManagedVTable *vt); + ReturnedValue construct(CallData *d); ReturnedValue call(CallData *d); ReturnedValue get(const StringRef name, bool *hasProperty = 0); @@ -245,17 +249,17 @@ public: void putIndexed(uint index, const ValueRef value); PropertyAttributes query(StringRef name) const; PropertyAttributes queryIndexed(uint index) const - { return vtbl->queryIndexed(this, index); } + { return internalClass->vtable->queryIndexed(this, index); } bool deleteProperty(const StringRef name); bool deleteIndexedProperty(uint index) - { return vtbl->deleteIndexedProperty(this, index); } + { return internalClass->vtable->deleteIndexedProperty(this, index); } ReturnedValue getLookup(Lookup *l) - { return vtbl->getLookup(this, l); } + { return internalClass->vtable->getLookup(this, l); } void setLookup(Lookup *l, const ValueRef v); bool isEqualTo(Managed *other) - { return vtbl->isEqualTo(this, other); } + { return internalClass->vtable->isEqualTo(this, other); } Property *advanceIterator(ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes); static void destroy(Managed *that) { that->_data = 0; } @@ -292,8 +296,6 @@ public: }; }; -protected: - const ManagedVTable *vtbl; public: InternalClass *internalClass; @@ -332,10 +334,10 @@ inline FunctionObject *managed_cast(Managed *m) inline ReturnedValue Managed::construct(CallData *d) { - return vtbl->construct(this, d); + return internalClass->vtable->construct(this, d); } inline ReturnedValue Managed::call(CallData *d) { - return vtbl->call(this, d); + return internalClass->vtable->call(this, d); } } diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp index 0b15588ed4..f67efaffb9 100644 --- a/src/qml/jsruntime/qv4mm.cpp +++ b/src/qml/jsruntime/qv4mm.cpp @@ -424,8 +424,8 @@ void MemoryManager::mark() // now that we marked all roots, start marking recursively and popping from the mark stack while (m_d->engine->jsStackTop > markBase) { Managed *m = m_d->engine->popForGC(); - Q_ASSERT (m->vtbl->markObjects); - m->vtbl->markObjects(m, m_d->engine); + Q_ASSERT (m->internalClass->vtable->markObjects); + m->internalClass->vtable->markObjects(m, m_d->engine); } } @@ -516,9 +516,9 @@ void MemoryManager::sweep(char *chunkStart, std::size_t chunkSize, size_t size, #ifdef V4_USE_VALGRIND VALGRIND_ENABLE_ERROR_REPORTING; #endif - if (m->vtbl->collectDeletables) - m->vtbl->collectDeletables(m, deletable); - m->vtbl->destroy(m); + if (m->internalClass->vtable->collectDeletables) + m->internalClass->vtable->collectDeletables(m, deletable); + m->internalClass->vtable->destroy(m); m->setNextFree(*f); #ifdef V4_USE_VALGRIND diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp index 039b790aed..a363a06242 100644 --- a/src/qml/jsruntime/qv4numberobject.cpp +++ b/src/qml/jsruntime/qv4numberobject.cpp @@ -54,7 +54,7 @@ DEFINE_MANAGED_VTABLE(NumberObject); NumberCtor::NumberCtor(ExecutionContext *scope) : FunctionObject(scope, QStringLiteral("Number")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue NumberCtor::construct(Managed *m, CallData *callData) diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 743d35fa69..d122eff8a5 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -74,18 +74,20 @@ Object::Object(ExecutionEngine *engine) , memberDataAlloc(InlinePropertySize), memberData(inlineProperties) , arrayOffset(0), arrayDataLen(0), arrayAlloc(0), arrayAttributes(0), arrayData(0), sparseArray(0) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); + type = Type_Object; flags = SimpleArray; memset(memberData, 0, sizeof(Property)*memberDataAlloc); } -Object::Object(InternalClass *internalClass) - : Managed(internalClass) +Object::Object(InternalClass *ic) + : Managed(ic) , memberDataAlloc(InlinePropertySize), memberData(inlineProperties) , arrayOffset(0), arrayDataLen(0), arrayAlloc(0), arrayAttributes(0), arrayData(0), sparseArray(0) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); + type = Type_Object; flags = SimpleArray; diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index daef18d4e2..a155a7b54a 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -280,13 +280,13 @@ public: void ensureMemberIndex(uint idx); inline ReturnedValue get(const StringRef name, bool *hasProperty = 0) - { return vtbl->get(this, name, hasProperty); } + { return internalClass->vtable->get(this, name, hasProperty); } inline ReturnedValue getIndexed(uint idx, bool *hasProperty = 0) - { return vtbl->getIndexed(this, idx, hasProperty); } + { return internalClass->vtable->getIndexed(this, idx, hasProperty); } inline void put(const StringRef name, const ValueRef v) - { vtbl->put(this, name, v); } + { internalClass->vtable->put(this, name, v); } inline void putIndexed(uint idx, const ValueRef v) - { vtbl->putIndexed(this, idx, v); } + { internalClass->vtable->putIndexed(this, idx, v); } using Managed::get; using Managed::getIndexed; using Managed::put; @@ -331,14 +331,14 @@ struct BooleanObject: Object { SafeValue value; BooleanObject(ExecutionEngine *engine, const ValueRef val) : Object(engine->booleanClass) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_BooleanObject; value = val; } protected: BooleanObject(InternalClass *ic) : Object(ic) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_BooleanObject; value = Encode(false); } @@ -349,14 +349,14 @@ struct NumberObject: Object { SafeValue value; NumberObject(ExecutionEngine *engine, const ValueRef val) : Object(engine->numberClass) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_NumberObject; value = val; } protected: NumberObject(InternalClass *ic) : Object(ic) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_NumberObject; value = Encode((int)0); } diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h index 19aedf3766..6c333b328c 100644 --- a/src/qml/jsruntime/qv4objectiterator_p.h +++ b/src/qml/jsruntime/qv4objectiterator_p.h @@ -89,7 +89,7 @@ struct ForEachIteratorObject: Object { ObjectIterator it; ForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o) : Object(ctx->engine), it(workArea, workArea + 1, o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_ForeachIteratorObject; } diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index f17bd7d5ba..a39b3d91e0 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -77,7 +77,7 @@ DEFINE_MANAGED_VTABLE(ObjectCtor); ObjectCtor::ObjectCtor(ExecutionContext *scope) : FunctionObject(scope, QStringLiteral("Object")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue ObjectCtor::construct(Managed *that, CallData *callData) diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 85e6878f7b..6696be94e3 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -241,7 +241,7 @@ QObjectWrapper::QObjectWrapper(ExecutionEngine *engine, QObject *object) : Object(engine) , m_object(object) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); Scope scope(engine); ScopedObject protectThis(scope, this); @@ -1726,7 +1726,7 @@ QObjectMethod::QObjectMethod(ExecutionContext *scope, QObject *object, int index , m_object(object) , m_index(index) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); subtype = WrappedQtMethod; m_qmlGlobal = qmlGlobal; } @@ -1847,7 +1847,7 @@ QmlSignalHandler::QmlSignalHandler(ExecutionEngine *engine, QObject *object, int , m_object(object) , m_signalIndex(signalIndex) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } DEFINE_MANAGED_VTABLE(QmlSignalHandler); diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp index 5ec63061dc..1a6d4c8f03 100644 --- a/src/qml/jsruntime/qv4regexp.cpp +++ b/src/qml/jsruntime/qv4regexp.cpp @@ -99,7 +99,7 @@ RegExp::RegExp(ExecutionEngine* engine, const QString &pattern, bool ignoreCase, , m_ignoreCase(ignoreCase) , m_multiLine(multiline) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_RegExpObject; if (!engine) diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index a8597229c4..3b69c92c3e 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -142,7 +142,7 @@ RegExpObject::RegExpObject(ExecutionEngine *engine, const QRegExp &re) void RegExpObject::init(ExecutionEngine *engine) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_RegExpObject; Scope scope(engine); @@ -237,7 +237,7 @@ DEFINE_MANAGED_VTABLE(RegExpCtor); RegExpCtor::RegExpCtor(ExecutionContext *scope) : FunctionObject(scope, QStringLiteral("RegExp")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData) diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index 17a19b5201..d56e705eb5 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -41,7 +41,7 @@ #ifndef QV4SCOPEDVALUE_P_H #define QV4SCOPEDVALUE_P_H -#include "qv4engine_p.h" +#include "qv4context_p.h" #include "qv4value_def_p.h" QT_BEGIN_NAMESPACE diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index c65f1baf2b..c1f86f9c83 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -67,7 +67,7 @@ QmlBindingWrapper::QmlBindingWrapper(ExecutionContext *scope, Function *f, Objec { Q_ASSERT(scope->inUse); - vtbl = &static_vtbl; + setVTable(&static_vtbl); function = f; function->compilationUnit->ref(); needsActivation = function->needsActivation(); @@ -88,7 +88,7 @@ QmlBindingWrapper::QmlBindingWrapper(ExecutionContext *scope, ObjectRef qml) { Q_ASSERT(scope->inUse); - vtbl = &static_vtbl; + setVTable(&static_vtbl); function = 0; needsActivation = false; @@ -140,7 +140,7 @@ struct CompilationUnitHolder : public QV4::Object , unit(unit) { unit->ref(); - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ~CompilationUnitHolder() { diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index 26e4dcb8a2..3b3bff44f3 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -174,7 +174,7 @@ public: , m_isReference(false) { type = Type_QmlSequence; - vtbl = &static_vtbl; + setVTable(&static_vtbl); flags &= ~SimpleArray; QV4::Scope scope(engine); QV4::ScopedObject protectThis(scope, this); @@ -189,7 +189,7 @@ public: , m_isReference(true) { type = Type_QmlSequence; - vtbl = &static_vtbl; + setVTable(&static_vtbl); flags &= ~SimpleArray; QV4::Scope scope(engine); QV4::ScopedObject protectThis(scope, this); diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index 37508e79f6..18ffde2eea 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -257,7 +257,8 @@ String::String(ExecutionEngine *engine, const QString &text) { _text->ref.ref(); len = _text->size; - vtbl = &static_vtbl; + if (engine) + setVTable(&static_vtbl); type = Type_String; subtype = StringType_Unknown; } @@ -268,7 +269,7 @@ String::String(ExecutionEngine *engine, String *l, String *r) , stringHash(UINT_MAX), largestSubLength(qMax(l->largestSubLength, r->largestSubLength)) , len(l->len + r->len) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_String; subtype = StringType_Unknown; diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h index 545e08de78..a420dc1589 100644 --- a/src/qml/jsruntime/qv4string_p.h +++ b/src/qml/jsruntime/qv4string_p.h @@ -63,7 +63,7 @@ struct Q_QML_EXPORT String : public Managed { String() : Managed(0), _text(QStringData::sharedNull()), identifier(0) , stringHash(UINT_MAX), largestSubLength(0), len(0) - { vtbl = &static_vtbl; type = Type_String; subtype = StringType_Unknown; } + { setVTable(&static_vtbl); type = Type_String; subtype = StringType_Unknown; } String(ExecutionEngine *engine, const QString &text); String(ExecutionEngine *engine, String *l, String *n); ~String() { diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index bff8f1f9cd..6ad0a7c572 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -80,7 +80,7 @@ DEFINE_MANAGED_VTABLE(StringObject); StringObject::StringObject(InternalClass *ic) : Object(ic) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_StringObject; Scope scope(engine()); @@ -96,7 +96,7 @@ StringObject::StringObject(InternalClass *ic) StringObject::StringObject(ExecutionEngine *engine, const ValueRef val) : Object(engine->stringClass) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_StringObject; Scope scope(engine); @@ -172,7 +172,7 @@ DEFINE_MANAGED_VTABLE(StringCtor); StringCtor::StringCtor(ExecutionContext *scope) : FunctionObject(scope, QStringLiteral("String")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue StringCtor::construct(Managed *m, CallData *callData) diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp index 470e8e206b..e3aa0c987b 100644 --- a/src/qml/jsruntime/qv4variantobject.cpp +++ b/src/qml/jsruntime/qv4variantobject.cpp @@ -56,7 +56,7 @@ VariantObject::VariantObject(InternalClass *ic) , ExecutionEngine::ScarceResourceData(QVariant()) , m_vmePropertyReferenceCount(0) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } VariantObject::VariantObject(ExecutionEngine *engine, const QVariant &value) @@ -64,7 +64,7 @@ VariantObject::VariantObject(ExecutionEngine *engine, const QVariant &value) , ExecutionEngine::ScarceResourceData(value) , m_vmePropertyReferenceCount(0) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); if (isScarce()) engine->scarceResources.insert(this); } diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index ae246f5cd4..ffdc808e32 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1491,7 +1491,7 @@ QmlIncubatorObject::QmlIncubatorObject(QV8Engine *engine, QQmlIncubator::Incubat { incubator.reset(new QQmlComponentIncubator(this, m)); v8 = engine; - vtbl = &static_vtbl; + setVTable(&static_vtbl); valuemap = QV4::Primitive::undefinedValue(); qmlGlobal = QV4::Primitive::undefinedValue(); diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index 54b540bb4c..2814b2bbcf 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -66,7 +66,7 @@ QmlContextWrapper::QmlContextWrapper(QV8Engine *engine, QQmlContextData *context v8(engine), readOnly(true), ownsContext(ownsContext), isNullWrapper(false), context(context), scopeObject(scopeObject), idObjectsWrapper(0) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } QmlContextWrapper::~QmlContextWrapper() @@ -439,7 +439,7 @@ QQmlIdObjectsArray::QQmlIdObjectsArray(ExecutionEngine *engine, QmlContextWrappe : Object(engine) , contextWrapper(contextWrapper) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ReturnedValue QQmlIdObjectsArray::getIndexed(Managed *m, uint index, bool *hasProperty) diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp index 73dc3192aa..2b3fcd8349 100644 --- a/src/qml/qml/qqmllistwrapper.cpp +++ b/src/qml/qml/qqmllistwrapper.cpp @@ -56,7 +56,7 @@ QmlListWrapper::QmlListWrapper(QV8Engine *engine) : Object(QV8Engine::getV4(engine)), v8(engine) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); flags &= ~SimpleArray; } diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 5e8130f407..c8a92190cc 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -61,7 +61,7 @@ public: QQmlLocaleData(QV4::ExecutionEngine *engine) : QV4::Object(engine) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); type = Type_Object; } diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 258442bc1d..db594e1b5b 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -60,7 +60,7 @@ QmlTypeWrapper::QmlTypeWrapper(QV8Engine *engine) : Object(QV8Engine::getV4(engine)), v8(engine), mode(IncludeEnums), type(0), typeNamespace(0), importNamespace(0) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } QmlTypeWrapper::~QmlTypeWrapper() diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index d733694923..341daf2391 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -79,7 +79,7 @@ QmlValueTypeWrapper::QmlValueTypeWrapper(QV8Engine *engine, ObjectType objectTyp : Object(QV8Engine::getV4(engine)), objectType(objectType) { v8 = engine; - vtbl = &static_vtbl; + setVTable(&static_vtbl); } QmlValueTypeWrapper::~QmlValueTypeWrapper() diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 18e3e33c4b..e31b1c414a 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -192,7 +192,7 @@ public: , list(list) , d(data) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); if (d) d->addref(); @@ -226,7 +226,7 @@ public: : Object(engine) , d(data) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); if (d) d->addref(); @@ -258,7 +258,7 @@ public: NodePrototype(ExecutionEngine *engine) : Object(engine) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); Scope scope(engine); ScopedObject protectThis(scope, this); @@ -312,7 +312,7 @@ class Node : public Object : Object(engine) , d(data) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); if (d) d->addref(); @@ -1605,7 +1605,7 @@ struct QQmlXMLHttpRequestWrapper : public Object : Object(engine) , request(request) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } ~QQmlXMLHttpRequestWrapper() { delete request; @@ -1626,7 +1626,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject QQmlXMLHttpRequestCtor(ExecutionEngine *engine) : FunctionObject(engine->rootContext, QStringLiteral("XMLHttpRequest")) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); Scope scope(engine); ScopedValue protectThis(scope, this); diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index bbb07cf332..c79ffb7ff9 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -90,7 +90,7 @@ QV4::QtObject::QtObject(ExecutionEngine *v4, QQmlEngine *qmlEngine) , m_platform(0) , m_application(0) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); Scope scope(v4); ScopedObject protectThis(scope, this); @@ -1183,7 +1183,7 @@ struct BindingFunction : public QV4::FunctionObject : QV4::FunctionObject(originalFunction->scope, originalFunction->name) , originalFunction(originalFunction) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); bindingKeyFlag = true; } diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 754d008745..19e2a40d47 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -71,7 +71,7 @@ struct DelegateModelGroupFunction: QV4::FunctionObject , code(code) , flag(flag) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } static QV4::ReturnedValue construct(QV4::Managed *m, QV4::CallData *) @@ -3144,7 +3144,7 @@ struct QQmlDelegateModelGroupChange : QV4::Object QQmlDelegateModelGroupChange(QV4::ExecutionEngine *engine) : Object(engine) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); } static QV4::ReturnedValue method_get_index(QV4::CallContext *ctx) { @@ -3183,7 +3183,7 @@ public: QQmlDelegateModelGroupChangeArray(QV4::ExecutionEngine *engine) : Object(engine) { - vtbl = &static_vtbl; + setVTable(&static_vtbl); flags &= ~SimpleArray; } virtual ~QQmlDelegateModelGroupChangeArray() {} diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h index 066c8e70e5..f78cf38535 100644 --- a/src/qml/types/qqmldelegatemodel_p_p.h +++ b/src/qml/types/qqmldelegatemodel_p_p.h @@ -165,7 +165,7 @@ struct QQmlDelegateModelItemObject : QV4::Object QQmlDelegateModelItemObject(QV4::ExecutionEngine *engine, QQmlDelegateModelItem *item) : Object(engine) , item(item) - { vtbl = &static_vtbl; } + { setVTable(&static_vtbl); } ~QQmlDelegateModelItemObject(); static void destroy(Managed *that); -- cgit v1.2.3