Return Heap::ExecutionContext for globalContext()
authorLars Knoll <lars.knoll@digia.com>
Fri, 28 Nov 2014 09:05:24 +0000 (10:05 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Fri, 19 Dec 2014 17:52:07 +0000 (18:52 +0100)
Change-Id: Ide7c81735be4662ff45bf268cfe750ff1f784453
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
17 files changed:
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4engine_p.h
src/qml/jsruntime/qv4functionobject.cpp
src/qml/jsruntime/qv4globalobject.cpp
src/qml/jsruntime/qv4object.cpp
src/qml/jsruntime/qv4objectproto.cpp
src/qml/jsruntime/qv4qobjectwrapper.cpp
src/qml/jsruntime/qv4script.cpp
src/qml/jsruntime/qv4script_p.h
src/qml/qml/qqmlobjectcreator.cpp
src/qml/qml/qqmlvaluetypewrapper.cpp
src/qml/types/qqmldelegatemodel.cpp
src/qml/types/qquickworkerscript.cpp
src/qml/util/qqmladaptormodel.cpp
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
tests/auto/qml/qv4debugger/tst_qv4debugger.cpp
tools/qmljs/qmljs.cpp

index fdcda17..170670f 100644 (file)
@@ -343,21 +343,22 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
 
     sequencePrototype = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass, arrayPrototype.asObject()));
 
-    objectCtor = memoryManager->alloc<ObjectCtor>(rootContext());
-    stringCtor = memoryManager->alloc<StringCtor>(rootContext());
-    numberCtor = memoryManager->alloc<NumberCtor>(rootContext());
-    booleanCtor = memoryManager->alloc<BooleanCtor>(rootContext());
-    arrayCtor = memoryManager->alloc<ArrayCtor>(rootContext());
-    functionCtor = memoryManager->alloc<FunctionCtor>(rootContext());
-    dateCtor = memoryManager->alloc<DateCtor>(rootContext());
-    regExpCtor = memoryManager->alloc<RegExpCtor>(rootContext());
-    errorCtor = memoryManager->alloc<ErrorCtor>(rootContext());
-    evalErrorCtor = memoryManager->alloc<EvalErrorCtor>(rootContext());
-    rangeErrorCtor = memoryManager->alloc<RangeErrorCtor>(rootContext());
-    referenceErrorCtor = memoryManager->alloc<ReferenceErrorCtor>(rootContext());
-    syntaxErrorCtor = memoryManager->alloc<SyntaxErrorCtor>(rootContext());
-    typeErrorCtor = memoryManager->alloc<TypeErrorCtor>(rootContext());
-    uRIErrorCtor = memoryManager->alloc<URIErrorCtor>(rootContext());
+    ScopedContext global(scope, rootContext());
+    objectCtor = memoryManager->alloc<ObjectCtor>(global);
+    stringCtor = memoryManager->alloc<StringCtor>(global);
+    numberCtor = memoryManager->alloc<NumberCtor>(global);
+    booleanCtor = memoryManager->alloc<BooleanCtor>(global);
+    arrayCtor = memoryManager->alloc<ArrayCtor>(global);
+    functionCtor = memoryManager->alloc<FunctionCtor>(global);
+    dateCtor = memoryManager->alloc<DateCtor>(global);
+    regExpCtor = memoryManager->alloc<RegExpCtor>(global);
+    errorCtor = memoryManager->alloc<ErrorCtor>(global);
+    evalErrorCtor = memoryManager->alloc<EvalErrorCtor>(global);
+    rangeErrorCtor = memoryManager->alloc<RangeErrorCtor>(global);
+    referenceErrorCtor = memoryManager->alloc<ReferenceErrorCtor>(global);
+    syntaxErrorCtor = memoryManager->alloc<SyntaxErrorCtor>(global);
+    typeErrorCtor = memoryManager->alloc<TypeErrorCtor>(global);
+    uRIErrorCtor = memoryManager->alloc<URIErrorCtor>(global);
 
     static_cast<ObjectPrototype *>(objectPrototype.asObject())->init(this, objectCtor.asObject());
     static_cast<StringPrototype *>(stringPrototype.asObject())->init(this, stringCtor.asObject());
@@ -381,18 +382,18 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
 
     // typed arrays
 
-    arrayBufferCtor = memoryManager->alloc<ArrayBufferCtor>(rootContext());
+    arrayBufferCtor = memoryManager->alloc<ArrayBufferCtor>(global);
     arrayBufferPrototype = memoryManager->alloc<ArrayBufferPrototype>(objectClass, objectPrototype.asObject());
     static_cast<ArrayBufferPrototype *>(arrayBufferPrototype.asObject())->init(this, arrayBufferCtor.asObject());
     arrayBufferClass = InternalClass::create(this, ArrayBuffer::staticVTable());
 
-    dataViewCtor = memoryManager->alloc<DataViewCtor>(rootContext());
+    dataViewCtor = memoryManager->alloc<DataViewCtor>(global);
     dataViewPrototype = memoryManager->alloc<DataViewPrototype>(objectClass, objectPrototype.asObject());
     static_cast<DataViewPrototype *>(dataViewPrototype.asObject())->init(this, dataViewCtor.asObject());
     dataViewClass = InternalClass::create(this, DataView::staticVTable());
 
     for (int i = 0; i < Heap::TypedArray::NTypes; ++i) {
-        typedArrayCtors[i] = memoryManager->alloc<TypedArrayCtor>(rootContext(), Heap::TypedArray::Type(i));
+        typedArrayCtors[i] = memoryManager->alloc<TypedArrayCtor>(global, Heap::TypedArray::Type(i));
         typedArrayPrototype[i] = memoryManager->alloc<TypedArrayPrototype>(this, Heap::TypedArray::Type(i));
         typedArrayPrototype[i].as<TypedArrayPrototype>()->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].asObject()));
         typedArrayClasses[i] = InternalClass::create(this, TypedArray::staticVTable());
@@ -401,8 +402,8 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     //
     // set up the global object
     //
-    rootContext()->d()->global = globalObject()->d();
-    rootContext()->d()->callData->thisObject = globalObject();
+    rootContext()->global = globalObject()->d();
+    rootContext()->callData->thisObject = globalObject();
     Q_ASSERT(globalObject()->internalClass()->vtable);
 
     globalObject()->defineDefaultProperty(QStringLiteral("Object"), objectCtor);
@@ -435,7 +436,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     globalObject()->defineReadonlyProperty(QStringLiteral("Infinity"), Primitive::fromDouble(Q_INFINITY));
 
 
-    evalFunction = Scoped<EvalFunction>(scope, memoryManager->alloc<EvalFunction>(rootContext()));
+    evalFunction = Scoped<EvalFunction>(scope, memoryManager->alloc<EvalFunction>(global));
     globalObject()->defineDefaultProperty(QStringLiteral("eval"), (o = evalFunction));
 
     globalObject()->defineDefaultProperty(QStringLiteral("parseInt"), GlobalFunctions::method_parseInt, 2);
@@ -450,7 +451,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     globalObject()->defineDefaultProperty(QStringLiteral("unescape"), GlobalFunctions::method_unescape, 1);
 
     Scoped<String> name(scope, newString(QStringLiteral("thrower")));
-    thrower = ScopedFunctionObject(scope, BuiltinFunction::create(rootContext(), name.getPointer(), ::throwTypeError)).getPointer();
+    thrower = ScopedFunctionObject(scope, BuiltinFunction::create(global, name.getPointer(), ::throwTypeError)).getPointer();
 }
 
 ExecutionEngine::~ExecutionEngine()
@@ -505,7 +506,7 @@ void ExecutionEngine::initRootContext()
     r->d()->callData->thisObject = globalObject();
     r->d()->callData->args[0] = Encode::undefined();
 
-    m_rootContext = r;
+    m_rootContext = r->d();
 }
 
 InternalClass *ExecutionEngine::newClass(const InternalClass &other)
@@ -513,14 +514,14 @@ InternalClass *ExecutionEngine::newClass(const InternalClass &other)
     return new (classPool) InternalClass(other);
 }
 
-ExecutionContext *ExecutionEngine::pushGlobalContext()
+Heap::ExecutionContext *ExecutionEngine::pushGlobalContext()
 {
     Scope scope(this);
     Scoped<GlobalContext> g(scope, memoryManager->alloc<GlobalContext>(this));
-    g->d()->callData = rootContext()->d()->callData;
+    g->d()->callData = rootContext()->callData;
 
     Q_ASSERT(currentContext() == g->d());
-    return g.getPointer();
+    return g->d();
 }
 
 
@@ -768,7 +769,7 @@ QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const
         StackFrame frame;
         frame.source = globalCode->sourceFile();
         frame.function = globalCode->name()->toQString();
-        frame.line = rootContext()->d()->lineNumber;
+        frame.line = rootContext()->lineNumber;
         frame.column = -1;
 
 
@@ -869,9 +870,10 @@ void ExecutionEngine::requireArgumentsAccessors(int n)
             memcpy(argumentsAccessors, oldAccessors, oldSize*sizeof(Property));
             delete [] oldAccessors;
         }
+        ScopedContext global(scope, scope.engine->rootContext());
         for (int i = oldSize; i < nArgumentsAccessors; ++i) {
-            argumentsAccessors[i].value = ScopedValue(scope, memoryManager->alloc<ArgumentsGetterFunction>(rootContext(), i));
-            argumentsAccessors[i].set = ScopedValue(scope, memoryManager->alloc<ArgumentsSetterFunction>(rootContext(), i));
+            argumentsAccessors[i].value = ScopedValue(scope, memoryManager->alloc<ArgumentsGetterFunction>(global, i));
+            argumentsAccessors[i].set = ScopedValue(scope, memoryManager->alloc<ArgumentsSetterFunction>(global, i));
         }
     }
 }
index bb5d1c5..03d471b 100644 (file)
@@ -78,8 +78,8 @@ public:
 
     Value *jsStackTop;
     quint32 hasException;
-    GlobalContext *m_rootContext;
-    GlobalContext *rootContext() const { return m_rootContext; }
+    Heap::GlobalContext *m_rootContext;
+    Heap::GlobalContext *rootContext() const { return m_rootContext; }
 
     MemoryManager *memoryManager;
     ExecutableAllocator *executableAllocator;
@@ -270,7 +270,7 @@ public:
     void enableDebugger();
     void enableProfiler();
 
-    ExecutionContext *pushGlobalContext();
+    Heap::ExecutionContext *pushGlobalContext();
     void pushContext(CallContext *context);
     Heap::ExecutionContext *popContext();
 
index c3d7a65..8221840 100644 (file)
@@ -123,7 +123,7 @@ Heap::FunctionObject::FunctionObject(ExecutionContext *scope, const ReturnedValu
 
 Heap::FunctionObject::FunctionObject(InternalClass *ic, QV4::Object *prototype)
     : Heap::Object(ic, prototype)
-    , scope(ic->engine->rootContext()->d())
+    , scope(ic->engine->rootContext())
 {
     Scope scope(ic->engine);
     ScopedObject o(scope, this);
@@ -258,7 +258,8 @@ ReturnedValue FunctionCtor::construct(Managed *that, CallData *callData)
     QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = isel->compile();
     QV4::Function *vmf = compilationUnit->linkToEngine(v4);
 
-    return FunctionObject::createScriptFunction(v4->rootContext(), vmf)->asReturnedValue();
+    ScopedContext global(scope, scope.engine->rootContext());
+    return FunctionObject::createScriptFunction(global, vmf)->asReturnedValue();
 }
 
 // 15.3.1: This is equivalent to new Function(...)
@@ -373,7 +374,8 @@ ReturnedValue FunctionPrototype::method_bind(CallContext *ctx)
         memcpy(boundArgs->data(), ctx->d()->callData->args + 1, (ctx->d()->callData->argc - 1)*sizeof(Value));
     }
 
-    return BoundFunction::create(ctx->d()->engine->rootContext(), target, boundThis, boundArgs)->asReturnedValue();
+    ScopedContext global(scope, scope.engine->rootContext());
+    return BoundFunction::create(global, target, boundThis, boundArgs)->asReturnedValue();
 }
 
 DEFINE_OBJECT_VTABLE(ScriptFunction);
index 3424e9d..a6f1b43 100644 (file)
@@ -358,7 +358,7 @@ ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall)
     ScopedContext parentContext(scope, v4->currentContext());
     ExecutionContextSaver ctxSaver(scope, parentContext);
 
-    ExecutionContext *ctx = parentContext;
+    ScopedContext ctx(scope, parentContext.getPointer());
 
     if (!directCall) {
         // the context for eval should be the global scope, so we fake a root
@@ -394,7 +394,7 @@ ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall)
         return e->call(callData);
     }
 
-    ContextStateSaver stateSaver(ctx);
+    ContextStateSaver stateSaver(scope, ctx);
 
     // set the correct strict mode flag on the context
     ctx->d()->strictMode = strictMode();
index 9d077cf..25ea9e1 100644 (file)
@@ -135,7 +135,8 @@ void Object::defineDefaultProperty(const QString &name, ReturnedValue (*code)(Ca
     ExecutionEngine *e = engine();
     Scope scope(e);
     ScopedString s(scope, e->newIdentifier(name));
-    Scoped<FunctionObject> function(scope, BuiltinFunction::create(e->rootContext(), s.getPointer(), code));
+    ScopedContext global(scope, e->rootContext());
+    Scoped<FunctionObject> function(scope, BuiltinFunction::create(global, s.getPointer(), code));
     function->defineReadonlyProperty(e->id_length, Primitive::fromInt32(argumentCount));
     defineDefaultProperty(s.getPointer(), function);
 }
@@ -144,7 +145,8 @@ void Object::defineDefaultProperty(String *name, ReturnedValue (*code)(CallConte
 {
     ExecutionEngine *e = engine();
     Scope scope(e);
-    Scoped<FunctionObject> function(scope, BuiltinFunction::create(e->rootContext(), name, code));
+    ScopedContext global(scope, e->rootContext());
+    Scoped<FunctionObject> function(scope, BuiltinFunction::create(global, name, code));
     function->defineReadonlyProperty(e->id_length, Primitive::fromInt32(argumentCount));
     defineDefaultProperty(name, function);
 }
@@ -162,8 +164,9 @@ void Object::defineAccessorProperty(String *name, ReturnedValue (*getter)(CallCo
     ExecutionEngine *v4 = engine();
     QV4::Scope scope(v4);
     ScopedProperty p(scope);
-    p->setGetter(getter ? ScopedFunctionObject(scope, BuiltinFunction::create(v4->rootContext(), name, getter)).getPointer() : 0);
-    p->setSetter(setter ? ScopedFunctionObject(scope, BuiltinFunction::create(v4->rootContext(), name, setter)).getPointer() : 0);
+    ScopedContext global(scope, scope.engine->rootContext());
+    p->setGetter(getter ? ScopedFunctionObject(scope, BuiltinFunction::create(global, name, getter)).getPointer() : 0);
+    p->setSetter(setter ? ScopedFunctionObject(scope, BuiltinFunction::create(global, name, setter)).getPointer() : 0);
     insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
 }
 
index aad894b..1ebc9ef 100644 (file)
@@ -108,8 +108,9 @@ void ObjectPrototype::init(ExecutionEngine *v4, Object *ctor)
     defineDefaultProperty(QStringLiteral("__defineGetter__"), method_defineGetter, 2);
     defineDefaultProperty(QStringLiteral("__defineSetter__"), method_defineSetter, 2);
 
-    Property p(ScopedFunctionObject(scope, BuiltinFunction::create(v4->rootContext(), v4->id___proto__, method_get_proto)).getPointer(),
-               ScopedFunctionObject(scope, BuiltinFunction::create(v4->rootContext(), v4->id___proto__, method_set_proto)).getPointer());
+    ScopedContext global(scope, scope.engine->rootContext());
+    Property p(ScopedFunctionObject(scope, BuiltinFunction::create(global, v4->id___proto__, method_get_proto)).getPointer(),
+               ScopedFunctionObject(scope, BuiltinFunction::create(global, v4->id___proto__, method_set_proto)).getPointer());
     insertMember(v4->id___proto__, p, Attr_Accessor|Attr_NotEnumerable);
 }
 
index fc57daa..2e8eec1 100644 (file)
@@ -275,7 +275,8 @@ ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String
 
     if (name->equals(scope.engine->id_destroy) || name->equals(scope.engine->id_toString)) {
         int index = name->equals(scope.engine->id_destroy) ? QV4::QObjectMethod::DestroyMethod : QV4::QObjectMethod::ToStringMethod;
-        QV4::ScopedValue method(scope, QV4::QObjectMethod::create(scope.engine->rootContext(), d()->object, index));
+        ScopedContext global(scope, scope.engine->rootContext());
+        QV4::ScopedValue method(scope, QV4::QObjectMethod::create(global, d()->object, index));
         if (hasProperty)
             *hasProperty = true;
         return method.asReturnedValue();
@@ -340,7 +341,8 @@ ReturnedValue QObjectWrapper::getProperty(QObject *object, ExecutionContext *ctx
             return vmemo->vmeMethod(property->coreIndex);
         } else if (property->isV4Function()) {
             QV4::Scoped<QV4::Object> qmlcontextobject(scope, ctx->d()->engine->qmlContextObject());
-            return QV4::QObjectMethod::create(ctx->d()->engine->rootContext(), object, property->coreIndex, qmlcontextobject);
+            ScopedContext global(scope, scope.engine->rootContext());
+            return QV4::QObjectMethod::create(global, object, property->coreIndex, qmlcontextobject);
         } else if (property->isSignalHandler()) {
             QV4::Scoped<QV4::QmlSignalHandler> handler(scope, scope.engine->memoryManager->alloc<QV4::QmlSignalHandler>(ctx->d()->engine, object, property->coreIndex));
 
@@ -351,7 +353,8 @@ ReturnedValue QObjectWrapper::getProperty(QObject *object, ExecutionContext *ctx
 
             return handler.asReturnedValue();
         } else {
-            return QV4::QObjectMethod::create(ctx->d()->engine->rootContext(), object, property->coreIndex);
+            ScopedContext global(scope, scope.engine->rootContext());
+            return QV4::QObjectMethod::create(global, object, property->coreIndex);
         }
     }
 
index 0d41e52..d125f04 100644 (file)
@@ -170,7 +170,8 @@ Heap::FunctionObject *QmlBindingWrapper::createQmlCallableForFunction(QQmlContex
     ExecutionEngine *engine = QQmlEnginePrivate::getV4Engine(qmlContext->engine);
     QV4::Scope valueScope(engine);
     QV4::ScopedObject qmlScopeObject(valueScope, QV4::QmlContextWrapper::qmlScope(engine->v8Engine, qmlContext, scopeObject));
-    QV4::Scoped<QV4::QmlBindingWrapper> wrapper(valueScope, engine->memoryManager->alloc<QV4::QmlBindingWrapper>(engine->rootContext(), qmlScopeObject));
+    ScopedContext global(valueScope, valueScope.engine->rootContext());
+    QV4::Scoped<QV4::QmlBindingWrapper> wrapper(valueScope, engine->memoryManager->alloc<QV4::QmlBindingWrapper>(global, qmlScopeObject));
     QV4::Scoped<CallContext> wrapperContext(valueScope, wrapper->context());
 
     if (!signalParameters.isEmpty()) {
@@ -221,7 +222,7 @@ void Script::parse()
 
     parsed = true;
 
-    ExecutionEngine *v4 = scope->d()->engine;
+    ExecutionEngine *v4 = scope->engine;
     Scope valueScope(v4);
 
     MemoryManager::GCBlocker gcBlocker(v4->memoryManager);
@@ -237,7 +238,7 @@ void Script::parse()
 
     foreach (const QQmlJS::DiagnosticMessage &m, parser.diagnosticMessages()) {
         if (m.isError()) {
-            scope->engine()->throwSyntaxError(m.message, sourceFile, m.loc.startLine, m.loc.startColumn);
+            valueScope.engine->throwSyntaxError(m.message, sourceFile, m.loc.startLine, m.loc.startColumn);
             return;
         } else {
             qWarning() << sourceFile << ':' << m.loc.startLine << ':' << m.loc.startColumn
@@ -256,7 +257,7 @@ void Script::parse()
 
         QStringList inheritedLocals;
         if (inheritContext) {
-            CallContext *ctx = scope->asCallContext();
+            Scoped<CallContext> ctx(valueScope, scope);
             if (ctx) {
                 for (Identifier * const *i = ctx->variables(), * const *ei = i + ctx->variableCount(); i < ei; ++i)
                     inheritedLocals.append(*i ? (*i)->string : QString());
@@ -292,22 +293,23 @@ ReturnedValue Script::run()
     if (!vmFunction)
         return Encode::undefined();
 
-    QV4::ExecutionEngine *engine = scope->d()->engine;
+    QV4::ExecutionEngine *engine = scope->engine;
     QV4::Scope valueScope(engine);
 
     if (qml.isUndefined()) {
         TemporaryAssignment<Function*> savedGlobalCode(engine->globalCode, vmFunction);
 
         ExecutionContextSaver ctxSaver(valueScope, scope);
-        ContextStateSaver stateSaver(scope);
-        scope->d()->strictMode = vmFunction->isStrict();
-        scope->d()->lookups = vmFunction->compilationUnit->runtimeLookups;
-        scope->d()->compilationUnit = vmFunction->compilationUnit;
+        ContextStateSaver stateSaver(valueScope, scope);
+        scope->strictMode = vmFunction->isStrict();
+        scope->lookups = vmFunction->compilationUnit->runtimeLookups;
+        scope->compilationUnit = vmFunction->compilationUnit;
 
         return vmFunction->code(engine, vmFunction->codeData);
     } else {
         ScopedObject qmlObj(valueScope, qml.value());
-        ScopedFunctionObject f(valueScope, engine->memoryManager->alloc<QmlBindingWrapper>(scope, vmFunction, qmlObj));
+        ScopedContext ctx(valueScope, scope);
+        ScopedFunctionObject f(valueScope, engine->memoryManager->alloc<QmlBindingWrapper>(ctx, vmFunction, qmlObj));
         ScopedCallData callData(valueScope);
         callData->thisObject = Primitive::undefinedValue();
         return f->call(callData);
@@ -380,10 +382,11 @@ ReturnedValue Script::qmlBinding()
 {
     if (!parsed)
         parse();
-    ExecutionEngine *v4 = scope->d()->engine;
+    ExecutionEngine *v4 = scope->engine;
     Scope valueScope(v4);
     ScopedObject qmlObj(valueScope, qml.value());
-    ScopedObject v(valueScope, v4->memoryManager->alloc<QmlBindingWrapper>(scope, vmFunction, qmlObj));
+    ScopedContext ctx(valueScope, scope);
+    ScopedObject v(valueScope, v4->memoryManager->alloc<QmlBindingWrapper>(ctx, vmFunction, qmlObj));
     return v.asReturnedValue();
 }
 
index a3cbcf4..467e8af 100644 (file)
@@ -46,26 +46,38 @@ class QQmlContextData;
 namespace QV4 {
 
 struct ContextStateSaver {
-    ExecutionContext *savedContext;
+    Value *savedContext;
     bool strictMode;
     Lookup *lookups;
     CompiledData::CompilationUnit *compilationUnit;
     int lineNumber;
 
-    ContextStateSaver(ExecutionContext *context)
-        : savedContext(context)
+    ContextStateSaver(Scope &scope, ExecutionContext *context)
+        : savedContext(scope.alloc(1))
         , strictMode(context->d()->strictMode)
         , lookups(context->d()->lookups)
         , compilationUnit(context->d()->compilationUnit)
         , lineNumber(context->d()->lineNumber)
-    {}
+    {
+        savedContext->m = context->d();
+    }
+    ContextStateSaver(Scope &scope, Heap::ExecutionContext *context)
+        : savedContext(scope.alloc(1))
+        , strictMode(context->strictMode)
+        , lookups(context->lookups)
+        , compilationUnit(context->compilationUnit)
+        , lineNumber(context->lineNumber)
+    {
+        savedContext->m = context;
+    }
 
     ~ContextStateSaver()
     {
-        savedContext->d()->strictMode = strictMode;
-        savedContext->d()->lookups = lookups;
-        savedContext->d()->compilationUnit = compilationUnit;
-        savedContext->d()->lineNumber = lineNumber;
+        Heap::ExecutionContext *ctx = static_cast<Heap::ExecutionContext *>(savedContext->m);
+        ctx->strictMode = strictMode;
+        ctx->lookups = lookups;
+        ctx->compilationUnit = compilationUnit;
+        ctx->lineNumber = lineNumber;
     }
 };
 
@@ -97,7 +109,7 @@ private:
 struct Q_QML_EXPORT Script {
     Script(ExecutionContext *scope, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0)
         : sourceFile(source), line(line), column(column), sourceCode(sourceCode)
-        , scope(scope), strictMode(false), inheritContext(false), parsed(false)
+        , scope(scope->d()), strictMode(false), inheritContext(false), parsed(false)
         , vmFunction(0), parseAsBinding(false) {}
     Script(ExecutionEngine *engine, Object *qml, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0)
         : sourceFile(source), line(line), column(column), sourceCode(sourceCode)
@@ -109,7 +121,8 @@ struct Q_QML_EXPORT Script {
     int line;
     int column;
     QString sourceCode;
-    ExecutionContext *scope;
+    // ### GC
+    Heap::ExecutionContext *scope;
     bool strictMode;
     bool inheritContext;
     bool parsed;
index 2e98fd3..be38b86 100644 (file)
@@ -265,7 +265,8 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance)
     sharedState->allJavaScriptObjects = valueScope.alloc(compiledData->totalObjectCount);
 
     QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _scopeObject));
-    QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, v4->memoryManager->alloc<QV4::QmlBindingWrapper>(v4->rootContext(), qmlScope));
+    QV4::ScopedContext global(valueScope, valueScope.engine->rootContext());
+    QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, v4->memoryManager->alloc<QV4::QmlBindingWrapper>(global, qmlScope));
     // ### GC
     QV4::ExecutionContext *qmlContext = QV4::ScopedContext(valueScope, qmlBindingWrapper->context()).getPointer();
 
@@ -1176,7 +1177,8 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
 
     QV4::Scope valueScope(v4);
     QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _scopeObject));
-    QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, v4->memoryManager->alloc<QV4::QmlBindingWrapper>(v4->rootContext(), qmlScope));
+    QV4::ScopedContext global(valueScope, valueScope.engine->rootContext());
+    QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, v4->memoryManager->alloc<QV4::QmlBindingWrapper>(global, qmlScope));
     // ### GC
     QV4::ExecutionContext *qmlContext = QV4::ScopedContext(valueScope, qmlBindingWrapper->context()).getPointer();
 
index 97da7eb..dba6004 100644 (file)
@@ -309,7 +309,9 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProper
 
     if (result->isFunction()) {
         // calling a Q_INVOKABLE function of a value type
-        return QV4::QObjectMethod::create(v4->rootContext(), r->d()->type, result->coreIndex);
+        Scope scope(v4);
+        ScopedContext c(scope, v4->rootContext());
+        return QV4::QObjectMethod::create(c, r->d()->type, result->coreIndex);
     }
 
 #define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \
index eb9354c..814c376 100644 (file)
@@ -1718,26 +1718,27 @@ void QQmlDelegateModelItemMetaType::initializePrototype()
 
     s = v4->newString(QStringLiteral("isUnresolved"));
     QV4::ScopedFunctionObject f(scope);
-    p->setGetter((f = QV4::DelegateModelGroupFunction::create(v4->rootContext(), 30, QQmlDelegateModelItem::get_member)));
+    QV4::ScopedContext global(scope, scope.engine->rootContext());
+    p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, 30, QQmlDelegateModelItem::get_member)));
     p->setSetter(0);
     proto->insertMember(s.getPointer(), p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
 
     s = v4->newString(QStringLiteral("inItems"));
-    p->setGetter((f = QV4::DelegateModelGroupFunction::create(v4->rootContext(), QQmlListCompositor::Default, QQmlDelegateModelItem::get_member)));
-    p->setSetter((f = QV4::DelegateModelGroupFunction::create(v4->rootContext(), QQmlListCompositor::Default, QQmlDelegateModelItem::set_member)));
+    p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Default, QQmlDelegateModelItem::get_member)));
+    p->setSetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Default, QQmlDelegateModelItem::set_member)));
     proto->insertMember(s.getPointer(), p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
 
     s = v4->newString(QStringLiteral("inPersistedItems"));
-    p->setGetter((f = QV4::DelegateModelGroupFunction::create(v4->rootContext(), QQmlListCompositor::Persisted, QQmlDelegateModelItem::get_member)));
-    p->setSetter((f = QV4::DelegateModelGroupFunction::create(v4->rootContext(), QQmlListCompositor::Persisted, QQmlDelegateModelItem::set_member)));
+    p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Persisted, QQmlDelegateModelItem::get_member)));
+    p->setSetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Persisted, QQmlDelegateModelItem::set_member)));
     proto->insertMember(s.getPointer(), p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
 
     s = v4->newString(QStringLiteral("itemsIndex"));
-    p->setGetter((f = QV4::DelegateModelGroupFunction::create(v4->rootContext(), QQmlListCompositor::Default, QQmlDelegateModelItem::get_index)));
+    p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Default, QQmlDelegateModelItem::get_index)));
     proto->insertMember(s.getPointer(), p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
 
     s = v4->newString(QStringLiteral("persistedItemsIndex"));
-    p->setGetter((f = QV4::DelegateModelGroupFunction::create(v4->rootContext(), QQmlListCompositor::Persisted, QQmlDelegateModelItem::get_index)));
+    p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Persisted, QQmlDelegateModelItem::get_index)));
     p->setSetter(0);
     proto->insertMember(s.getPointer(), p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
 
@@ -1745,14 +1746,14 @@ void QQmlDelegateModelItemMetaType::initializePrototype()
         QString propertyName = QStringLiteral("in") + groupNames.at(i);
         propertyName.replace(2, 1, propertyName.at(2).toUpper());
         s = v4->newString(propertyName);
-        p->setGetter((f = QV4::DelegateModelGroupFunction::create(v4->rootContext(), i + 1, QQmlDelegateModelItem::get_member)));
-        p->setSetter((f = QV4::DelegateModelGroupFunction::create(v4->rootContext(), i + 1, QQmlDelegateModelItem::set_member)));
+        p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, i + 1, QQmlDelegateModelItem::get_member)));
+        p->setSetter((f = QV4::DelegateModelGroupFunction::create(global, i + 1, QQmlDelegateModelItem::set_member)));
         proto->insertMember(s.getPointer(), p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
     }
     for (int i = 2; i < groupNames.count(); ++i) {
         const QString propertyName = groupNames.at(i) + QStringLiteral("Index");
         s = v4->newString(propertyName);
-        p->setGetter((f = QV4::DelegateModelGroupFunction::create(v4->rootContext(), i + 1, QQmlDelegateModelItem::get_index)));
+        p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, i + 1, QQmlDelegateModelItem::get_index)));
         p->setSetter(0);
         proto->insertMember(s.getPointer(), p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
     }
index 9d89c5e..8bc677f 100644 (file)
@@ -221,13 +221,14 @@ void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
     "})"
 
     QV4::Scope scope(m_v4Engine);
-    onmessage = QV4::Script(m_v4Engine->rootContext(), QString::fromUtf8(CALL_ONMESSAGE_SCRIPT)).run(); // do not use QStringLiteral here, MSVC2012 cannot apply this cleanly to the macro
+    QV4::ScopedContext globalContext(scope, scope.engine->rootContext());
+    onmessage = QV4::Script(globalContext, QString::fromUtf8(CALL_ONMESSAGE_SCRIPT)).run(); // do not use QStringLiteral here, MSVC2012 cannot apply this cleanly to the macro
     Q_ASSERT(!scope.engine->hasException);
-    QV4::Script createsendscript(m_v4Engine->rootContext(), QString::fromUtf8(SEND_MESSAGE_CREATE_SCRIPT)); // do not use QStringLiteral here, MSVC2012 cannot apply this cleanly to the macro
+    QV4::Script createsendscript(globalContext, QString::fromUtf8(SEND_MESSAGE_CREATE_SCRIPT)); // do not use QStringLiteral here, MSVC2012 cannot apply this cleanly to the macro
     QV4::Scoped<QV4::FunctionObject> createsendconstructor(scope, createsendscript.run());
     Q_ASSERT(!scope.engine->hasException);
     QV4::ScopedString name(scope, m_v4Engine->newString(QStringLiteral("sendMessage")));
-    QV4::ScopedValue function(scope, QV4::BuiltinFunction::create(m_v4Engine->rootContext(), name.getPointer(),
+    QV4::ScopedValue function(scope, QV4::BuiltinFunction::create(globalContext, name.getPointer(),
                                                                     QQuickWorkerScriptEnginePrivate::method_sendMessage));
     QV4::ScopedCallData callData(scope, 1);
     callData->args[0] = function;
index 9f3b3be..355525a 100644 (file)
@@ -219,8 +219,9 @@ public:
             const QByteArray &propertyName = it.key();
 
             QV4::ScopedString name(scope, v4->newString(QString::fromUtf8(propertyName)));
-            QV4::ScopedFunctionObject g(scope, v4->memoryManager->alloc<QV4::IndexedBuiltinFunction>(v4->rootContext(), propertyId, QQmlDMCachedModelData::get_property));
-            QV4::ScopedFunctionObject s(scope, v4->memoryManager->alloc<QV4::IndexedBuiltinFunction>(v4->rootContext(), propertyId, QQmlDMCachedModelData::set_property));
+            QV4::ScopedContext global(scope, v4->rootContext());
+            QV4::ScopedFunctionObject g(scope, v4->memoryManager->alloc<QV4::IndexedBuiltinFunction>(global, propertyId, QQmlDMCachedModelData::get_property));
+            QV4::ScopedFunctionObject s(scope, v4->memoryManager->alloc<QV4::IndexedBuiltinFunction>(global, propertyId, QQmlDMCachedModelData::set_property));
             p->setGetter(g);
             p->setSetter(s);
             proto->insertMember(name.getPointer(), p, QV4::Attr_Accessor|QV4::Attr_NotEnumerable|QV4::Attr_NotConfigurable);
index e966052..b816edd 100644 (file)
@@ -2302,10 +2302,9 @@ static inline bool evaluate_error(QV8Engine *engine, const QV4::ValueRef o, cons
     QString functionSource = QLatin1String("(function(object) { return ") +
                              QLatin1String(source) + QLatin1String(" })");
 
-    QV4::Script program(QV8Engine::getV4(engine)->rootContext(), functionSource);
-    program.inheritContext = true;
-
     QV4::Scope scope(QV8Engine::getV4(engine));
+    QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), functionSource);
+    program.inheritContext = true;
 
     QV4::Scoped<QV4::FunctionObject> function(scope, program.run());
     if (scope.engine->hasException) {
@@ -2329,10 +2328,9 @@ static inline bool evaluate_value(QV8Engine *engine, const QV4::ValueRef o,
     QString functionSource = QLatin1String("(function(object) { return ") +
                              QLatin1String(source) + QLatin1String(" })");
 
-    QV4::Script program(QV8Engine::getV4(engine)->rootContext(), functionSource);
-    program.inheritContext = true;
-
     QV4::Scope scope(QV8Engine::getV4(engine));
+    QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), functionSource);
+    program.inheritContext = true;
 
     QV4::Scoped<QV4::FunctionObject> function(scope, program.run());
     if (scope.engine->hasException) {
@@ -2362,7 +2360,7 @@ static inline QV4::ReturnedValue evaluate(QV8Engine *engine, const QV4::ValueRef
 
     QV4::Scope scope(QV8Engine::getV4(engine));
 
-    QV4::Script program(scope.engine->rootContext(), functionSource);
+    QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), functionSource);
     program.inheritContext = true;
 
     QV4::Scoped<QV4::FunctionObject> function(scope, program.run());
index ea2911f..38024da 100644 (file)
@@ -83,7 +83,8 @@ public:
         QV4::Scope scope(v4);
 
         QV4::Scoped<QV4::String> name(scope, v4->newString(functionName));
-        QV4::ScopedValue function(scope, BuiltinFunction::create(v4->rootContext(), name, injectedFunction));
+        QV4::ScopedContext ctx(scope, v4->rootContext());
+        QV4::ScopedValue function(scope, BuiltinFunction::create(ctx, name, injectedFunction));
         v4->globalObject()->put(name, function);
     }
 
index 9dc40e8..0f5f955 100644 (file)
@@ -185,8 +185,8 @@ int main(int argc, char *argv[])
 
         QV4::ExecutionEngine vm(iSelFactory);
 
-        QV4::ExecutionContext *ctx = vm.rootContext();
-        QV4::Scope scope(ctx);
+        QV4::Scope scope(&vm);
+        QV4::ScopedContext ctx(scope, vm.rootContext());
 
         QV4::ScopedObject globalObject(scope, vm.globalObject());
         QV4::ScopedObject print(scope, vm.memoryManager->alloc<builtins::Print>(ctx));