Convert ExecutionContext::parent/outer to use a heap object
authorLars Knoll <lars.knoll@theqtcompany.com>
Fri, 7 Nov 2014 04:46:20 +0000 (05:46 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Wed, 12 Nov 2014 11:13:03 +0000 (12:13 +0100)
Change-Id: I1b8ee831cfcdd5b1904ce24a341f5a796dce41cf
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/jsruntime/qv4context.cpp
src/qml/jsruntime/qv4context_p.h
src/qml/jsruntime/qv4debugging.cpp
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4functionobject.cpp
src/qml/jsruntime/qv4scopedvalue_p.h
src/qml/jsruntime/qv4script.cpp
src/qml/jsruntime/qv4vme_moth.cpp
src/qml/qml/v8/qqmlbuiltinfunctions.cpp

index 84a3ae2..5d65138 100644 (file)
@@ -59,7 +59,7 @@ Returned<CallContext> *ExecutionContext::newCallContext(FunctionObject *function
     c->realArgumentCount = callData->argc;
 
     c->strictMode = function->strictMode();
-    c->outer = function->scope();
+    c->outer = function->scope()->d();
 
     c->activation = 0;
 
@@ -107,10 +107,10 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable)
 
     // find the right context to create the binding on
     ScopedObject activation(scope, d()->engine->globalObject);
-    ExecutionContext *ctx = this;
+    Scoped<ExecutionContext> ctx(scope, this);
     while (ctx) {
         if (ctx->d()->type >= Heap::ExecutionContext::Type_CallContext) {
-            CallContext *c = static_cast<CallContext *>(ctx);
+            CallContext *c = static_cast<CallContext *>(ctx.getPointer());
             if (!c->d()->activation)
                 c->d()->activation = d()->engine->newObject()->getPointer()->d();
             activation = c->d()->activation;
@@ -137,10 +137,10 @@ Heap::GlobalContext::GlobalContext(ExecutionEngine *eng)
 Heap::WithContext::WithContext(ExecutionEngine *engine, QV4::Object *with)
     : Heap::ExecutionContext(engine, Heap::ExecutionContext::Type_WithContext)
 {
-    callData = parent->d()->callData;
+    callData = parent->callData;
     outer = parent;
-    lookups = parent->d()->lookups;
-    compilationUnit = parent->d()->compilationUnit;
+    lookups = parent->lookups;
+    compilationUnit = parent->compilationUnit;
 
     withObject = with->d();
 }
@@ -148,11 +148,11 @@ Heap::WithContext::WithContext(ExecutionEngine *engine, QV4::Object *with)
 Heap::CatchContext::CatchContext(ExecutionEngine *engine, QV4::String *exceptionVarName, const ValueRef exceptionValue)
     : Heap::ExecutionContext(engine, Heap::ExecutionContext::Type_CatchContext)
 {
-    strictMode = parent->d()->strictMode;
-    callData = parent->d()->callData;
+    strictMode = parent->strictMode;
+    callData = parent->callData;
     outer = parent;
-    lookups = parent->d()->lookups;
-    compilationUnit = parent->d()->compilationUnit;
+    lookups = parent->lookups;
+    compilationUnit = parent->compilationUnit;
 
     this->exceptionVarName = exceptionVarName;
     this->exceptionValue = exceptionValue;
@@ -168,7 +168,7 @@ Heap::CallContext::CallContext(ExecutionEngine *engine, QV4::Object *qml, QV4::F
     callData->thisObject = Primitive::undefinedValue();
 
     strictMode = true;
-    outer = function->scope();
+    outer = function->scope()->d();
 
     activation = qml->d();
 
@@ -208,18 +208,19 @@ bool ExecutionContext::deleteProperty(String *name)
 {
     Scope scope(this);
     bool hasWith = false;
-    for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) {
+    Scoped<ExecutionContext> ctx(scope, this);
+    for (; ctx; ctx = ctx->d()->outer) {
         if (ctx->d()->type == Heap::ExecutionContext::Type_WithContext) {
             hasWith = true;
-            ScopedObject withObject(scope, static_cast<WithContext *>(ctx)->d()->withObject);
+            ScopedObject withObject(scope, static_cast<WithContext *>(ctx.getPointer())->d()->withObject);
             if (withObject->hasProperty(name))
                 return withObject->deleteProperty(name);
         } else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext) {
-            CatchContext *c = static_cast<CatchContext *>(ctx);
+            CatchContext *c = static_cast<CatchContext *>(ctx.getPointer());
             if (c->d()->exceptionVarName->isEqualTo(name))
                 return false;
         } else if (ctx->d()->type >= Heap::ExecutionContext::Type_CallContext) {
-            CallContext *c = static_cast<CallContext *>(ctx);
+            CallContext *c = static_cast<CallContext *>(ctx.getPointer());
             ScopedFunctionObject f(scope, c->d()->function);
             if (f->needsActivation() || hasWith) {
                 uint index = f->function()->internalClass->find(name);
@@ -231,7 +232,7 @@ bool ExecutionContext::deleteProperty(String *name)
             if (activation && activation->hasProperty(name))
                 return activation->deleteProperty(name);
         } else if (ctx->d()->type == Heap::ExecutionContext::Type_GlobalContext) {
-            ScopedObject global(scope, static_cast<GlobalContext *>(ctx)->d()->global);
+            ScopedObject global(scope, static_cast<GlobalContext *>(ctx.getPointer())->d()->global);
             if (global->hasProperty(name))
                 return global->deleteProperty(name);
         }
@@ -282,20 +283,21 @@ void ExecutionContext::markObjects(Heap::Base *m, ExecutionEngine *engine)
 void ExecutionContext::setProperty(String *name, const ValueRef value)
 {
     Scope scope(this);
-    for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) {
+    Scoped<ExecutionContext> ctx(scope, this);
+    for (; ctx; ctx = ctx->d()->outer) {
         if (ctx->d()->type == Heap::ExecutionContext::Type_WithContext) {
-            ScopedObject w(scope, static_cast<WithContext *>(ctx)->d()->withObject);
+            ScopedObject w(scope, static_cast<WithContext *>(ctx.getPointer())->d()->withObject);
             if (w->hasProperty(name)) {
                 w->put(name, value);
                 return;
             }
-        } else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext && static_cast<CatchContext *>(ctx)->d()->exceptionVarName->isEqualTo(name)) {
-            static_cast<CatchContext *>(ctx)->d()->exceptionValue = *value;
+        } else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext && static_cast<CatchContext *>(ctx.getPointer())->d()->exceptionVarName->isEqualTo(name)) {
+            static_cast<CatchContext *>(ctx.getPointer())->d()->exceptionValue = *value;
             return;
         } else {
             ScopedObject activation(scope, (Object *)0);
             if (ctx->d()->type >= Heap::ExecutionContext::Type_CallContext) {
-                CallContext *c = static_cast<CallContext *>(ctx);
+                CallContext *c = static_cast<CallContext *>(ctx.getPointer());
                 if (c->d()->function->function) {
                     uint index = c->d()->function->function->internalClass->find(name);
                     if (index < UINT_MAX) {
@@ -310,7 +312,7 @@ void ExecutionContext::setProperty(String *name, const ValueRef value)
                 }
                 activation = c->d()->activation;
             } else if (ctx->d()->type == Heap::ExecutionContext::Type_GlobalContext) {
-                activation = static_cast<GlobalContext *>(ctx)->d()->global;
+                activation = static_cast<GlobalContext *>(ctx.getPointer())->d()->global;
             }
 
             if (activation) {
@@ -346,9 +348,10 @@ ReturnedValue ExecutionContext::getProperty(String *name)
 
     bool hasWith = false;
     bool hasCatchScope = false;
-    for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) {
+    Scoped<ExecutionContext> ctx(scope, this);
+    for (; ctx; ctx = ctx->d()->outer) {
         if (ctx->d()->type == Heap::ExecutionContext::Type_WithContext) {
-            ScopedObject w(scope, static_cast<WithContext *>(ctx)->d()->withObject);
+            ScopedObject w(scope, static_cast<WithContext *>(ctx.getPointer())->d()->withObject);
             hasWith = true;
             bool hasProperty = false;
             v = w->get(name, &hasProperty);
@@ -360,13 +363,13 @@ ReturnedValue ExecutionContext::getProperty(String *name)
 
         else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext) {
             hasCatchScope = true;
-            CatchContext *c = static_cast<CatchContext *>(ctx);
+            CatchContext *c = static_cast<CatchContext *>(ctx.getPointer());
             if (c->d()->exceptionVarName->isEqualTo(name))
                 return c->d()->exceptionValue.asReturnedValue();
         }
 
         else if (ctx->d()->type >= Heap::ExecutionContext::Type_CallContext) {
-            QV4::CallContext *c = static_cast<CallContext *>(ctx);
+            QV4::CallContext *c = static_cast<CallContext *>(ctx.getPointer());
             ScopedFunctionObject f(scope, c->d()->function);
             if (f->function() && (f->needsActivation() || hasWith || hasCatchScope)) {
                 uint index = f->function()->internalClass->find(name);
@@ -389,7 +392,7 @@ ReturnedValue ExecutionContext::getProperty(String *name)
         }
 
         else if (ctx->d()->type == Heap::ExecutionContext::Type_GlobalContext) {
-            ScopedObject global(scope, static_cast<GlobalContext *>(ctx)->d()->global);
+            ScopedObject global(scope, static_cast<GlobalContext *>(ctx.getPointer())->d()->global);
             bool hasProperty = false;
             v = global->get(name, &hasProperty);
             if (hasProperty)
@@ -412,9 +415,10 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object *&base)
 
     bool hasWith = false;
     bool hasCatchScope = false;
-    for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) {
+    Scoped<ExecutionContext> ctx(scope, this);
+    for (; ctx; ctx = ctx->d()->outer) {
         if (ctx->d()->type == Heap::ExecutionContext::Type_WithContext) {
-            ScopedObject w(scope, static_cast<WithContext *>(ctx)->d()->withObject);
+            ScopedObject w(scope, static_cast<WithContext *>(ctx.getPointer())->d()->withObject);
             hasWith = true;
             bool hasProperty = false;
             v = w->get(name, &hasProperty);
@@ -427,13 +431,13 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object *&base)
 
         else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext) {
             hasCatchScope = true;
-            CatchContext *c = static_cast<CatchContext *>(ctx);
+            CatchContext *c = static_cast<CatchContext *>(ctx.getPointer());
             if (c->d()->exceptionVarName->isEqualTo(name))
                 return c->d()->exceptionValue.asReturnedValue();
         }
 
         else if (ctx->d()->type >= Heap::ExecutionContext::Type_CallContext) {
-            QV4::CallContext *c = static_cast<CallContext *>(ctx);
+            QV4::CallContext *c = static_cast<CallContext *>(ctx.getPointer());
             ScopedFunctionObject f(scope, c->d()->function);
             if (f->function() && (f->needsActivation() || hasWith || hasCatchScope)) {
                 uint index = f->function()->internalClass->find(name);
@@ -459,7 +463,7 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object *&base)
         }
 
         else if (ctx->d()->type == Heap::ExecutionContext::Type_GlobalContext) {
-            ScopedObject global(scope, static_cast<GlobalContext *>(ctx)->d()->global);
+            ScopedObject global(scope, static_cast<GlobalContext *>(ctx.getPointer())->d()->global);
             bool hasProperty = false;
             v = global->get(name, &hasProperty);
             if (hasProperty)
index 601af5a..5b1abb5 100644 (file)
@@ -68,21 +68,7 @@ struct ExecutionContext : Base {
         EvalCode *next;
     };
 
-    ExecutionContext(ExecutionEngine *engine, ContextType t)
-        : Base(engine->executionContextClass)
-        , type(t)
-        , strictMode(false)
-        , engine(engine)
-        , parent(engine->currentContext())
-        , outer(0)
-        , lookups(0)
-        , compilationUnit(0)
-        , currentEvalCode(0)
-        , lineNumber(-1)
-    {
-        // ### GC
-        engine->current = reinterpret_cast<QV4::ExecutionContext *>(this);
-    }
+    inline ExecutionContext(ExecutionEngine *engine, ContextType t);
 
     ContextType type;
     bool strictMode;
@@ -90,9 +76,8 @@ struct ExecutionContext : Base {
     CallData *callData;
 
     ExecutionEngine *engine;
-    // ### GC
-    QV4::ExecutionContext *parent;
-    QV4::ExecutionContext *outer;
+    ExecutionContext *parent;
+    ExecutionContext *outer;
     Lookup *lookups;
     CompiledData::CompilationUnit *compilationUnit;
     EvalCode *currentEvalCode;
@@ -151,7 +136,7 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
         d()->type = t;
         d()->strictMode = false;
         d()->engine = engine;
-        d()->parent = engine->currentContext();
+        d()->parent = engine->currentContext()->d();
         d()->outer = 0;
         d()->lookups = 0;
         d()->compilationUnit = 0;
@@ -181,6 +166,24 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
     static void markObjects(Heap::Base *m, ExecutionEngine *e);
 };
 
+inline
+Heap::ExecutionContext::ExecutionContext(ExecutionEngine *engine, ContextType t)
+    : Heap::Base(engine->executionContextClass)
+    , type(t)
+    , strictMode(false)
+    , engine(engine)
+    , parent(engine->currentContext()->d())
+    , outer(0)
+    , lookups(0)
+    , compilationUnit(0)
+    , currentEvalCode(0)
+    , lineNumber(-1)
+{
+    // ### GC
+    engine->current = reinterpret_cast<QV4::ExecutionContext *>(this);
+}
+
+
 struct CallContext : public ExecutionContext
 {
     V4_MANAGED(CallContext, ExecutionContext)
@@ -228,7 +231,8 @@ inline const CallContext *ExecutionContext::asCallContext() const
 
 inline void ExecutionEngine::pushContext(CallContext *context)
 {
-    context->d()->parent = current;
+    Q_ASSERT(current && current->d() && context && context->d());
+    context->d()->parent = current->d();
     current = context;
     current->d()->currentEvalCode = 0;
 }
@@ -236,7 +240,9 @@ inline void ExecutionEngine::pushContext(CallContext *context)
 inline ExecutionContext *ExecutionEngine::popContext()
 {
     Q_ASSERT(current->d()->parent);
-    current = current->d()->parent;
+    // ### GC
+    current = reinterpret_cast<ExecutionContext *>(current->d()->parent);
+    Q_ASSERT(current && current->d());
     return current;
 }
 
index fdba6e3..7ef32a1 100644 (file)
@@ -261,14 +261,19 @@ QVector<StackFrame> Debugger::stackTrace(int frameLimit) const
 
 static inline CallContext *findContext(ExecutionContext *ctxt, int frame)
 {
-    while (ctxt) {
-        CallContext *cCtxt = ctxt->asCallContext();
+    if (!ctxt)
+        return 0;
+
+    Scope scope(ctxt);
+    Scoped<ExecutionContext> ctx(scope, ctxt);
+    while (ctx) {
+        CallContext *cCtxt = ctx->asCallContext();
         if (cCtxt && cCtxt->d()->function) {
             if (frame < 1)
                 return cCtxt;
             --frame;
         }
-        ctxt = ctxt->d()->parent;
+        ctx = ctx->d()->parent;
     }
 
     return 0;
@@ -276,10 +281,15 @@ static inline CallContext *findContext(ExecutionContext *ctxt, int frame)
 
 static inline CallContext *findScope(ExecutionContext *ctxt, int scope)
 {
-    for (; scope > 0 && ctxt; --scope)
-        ctxt = ctxt->d()->outer;
+    if (!ctxt)
+        return 0;
+
+    Scope s(ctxt);
+    Scoped<ExecutionContext> ctx(s, ctxt);
+    for (; scope > 0 && ctx; --scope)
+        ctx = ctx->d()->outer;
 
-    return ctxt ? ctxt->asCallContext() : 0;
+    return ctx ? ctx->asCallContext() : 0;
 }
 
 void Debugger::collectArgumentsInContext(Collector *collector, int frameNr, int scopeNr)
@@ -403,7 +413,8 @@ bool Debugger::collectThisInContext(Debugger::Collector *collector, int frame)
 
         bool myRun()
         {
-            ExecutionContext *ctxt = findContext(engine->currentContext(), frameNr);
+            Scope scope(engine);
+            Scoped<ExecutionContext> ctxt(scope, findContext(engine->currentContext(), frameNr));
             while (ctxt) {
                 if (CallContext *cCtxt = ctxt->asCallContext())
                     if (cCtxt->d()->activation)
@@ -414,7 +425,6 @@ bool Debugger::collectThisInContext(Debugger::Collector *collector, int frame)
             if (!ctxt)
                 return false;
 
-            Scope scope(engine);
             ScopedObject o(scope, ctxt->asCallContext()->d()->activation);
             collector->collect(o);
             return true;
@@ -477,7 +487,9 @@ QVector<Heap::ExecutionContext::ContextType> Debugger::getScopeTypes(int frame)
         return types;
     CallContext *ctxt = static_cast<CallContext *>(sctxt);
 
-    for (ExecutionContext *it = ctxt; it; it = it->d()->outer)
+    Scope scope(m_engine);
+    Scoped<ExecutionContext> it(scope, ctxt);
+    for (; it; it = it->d()->outer)
         types.append(it->d()->type);
 
     return types;
@@ -550,8 +562,9 @@ void Debugger::leavingFunction(const ReturnedValue &retVal)
 
     QMutexLocker locker(&m_lock);
 
+    Scope scope(m_engine);
     if (m_stepping != NotStepping && m_currentContext == m_engine->currentContext()) {
-        m_currentContext = m_engine->currentContext()->d()->parent;
+        m_currentContext = Scoped<ExecutionContext>(scope, m_engine->currentContext()->d()->parent).getPointer();
         m_stepping = StepOver;
         m_returnedValue = retVal;
     }
index 747f5b7..2225acf 100644 (file)
@@ -709,23 +709,24 @@ Returned<Object> *ExecutionEngine::newForEachIteratorObject(Object *o)
 
 Returned<Object> *ExecutionEngine::qmlContextObject() const
 {
-    ExecutionContext *ctx = currentContext();
+    Heap::ExecutionContext *ctx = currentContext()->d();
 
-    if (ctx->d()->type == Heap::ExecutionContext::Type_SimpleCallContext && !ctx->d()->outer)
-        ctx = ctx->d()->parent;
+    if (ctx->type == Heap::ExecutionContext::Type_SimpleCallContext && !ctx->outer)
+        ctx = ctx->parent;
 
-    if (!ctx->d()->outer)
+    if (!ctx->outer)
         return 0;
 
-    while (ctx->d()->outer && ctx->d()->outer->d()->type != Heap::ExecutionContext::Type_GlobalContext)
-        ctx = ctx->d()->outer;
+    while (ctx->outer && ctx->outer->type != Heap::ExecutionContext::Type_GlobalContext)
+        ctx = ctx->outer;
 
     Q_ASSERT(ctx);
-    if (ctx->d()->type != Heap::ExecutionContext::Type_QmlContext)
+    if (ctx->type != Heap::ExecutionContext::Type_QmlContext)
         return 0;
 
-    Scope scope(ctx);
-    ScopedObject activation(scope, static_cast<CallContext *>(ctx)->d()->activation);
+    Scope scope(currentContext());
+    ScopedObject activation(scope, static_cast<Heap::CallContext *>(ctx)->activation);
+    Q_ASSERT(activation);
 
     return activation->asReturned<Object>();
 }
@@ -736,7 +737,7 @@ QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const
     ScopedString name(scope);
     QVector<StackFrame> stack;
 
-    QV4::ExecutionContext *c = currentContext();
+    Scoped<ExecutionContext> c(scope, currentContext());
     while (c && frameLimit) {
         CallContext *callCtx = c->asCallContext();
         if (callCtx && callCtx->d()->function) {
@@ -825,7 +826,8 @@ QUrl ExecutionEngine::resolvedUrl(const QString &file)
         return src;
 
     QUrl base;
-    QV4::ExecutionContext *c = currentContext();
+    Scope scope(this);
+    Scoped<ExecutionContext> c(scope, currentContext());
     while (c) {
         CallContext *callCtx = c->asCallContext();
         if (callCtx && callCtx->d()->function) {
@@ -884,14 +886,15 @@ void ExecutionEngine::markObjects()
             setter->mark(this);
     }
 
-    ExecutionContext *c = currentContext();
+    Heap::ExecutionContext *c = currentContext()->d();
     while (c) {
-        Q_ASSERT(c->inUse());
-        if (!c->markBit()) {
-            c->d()->markBit = 1;
-            c->markObjects(c->d(), this);
+        Q_ASSERT(c->inUse);
+        if (!c->markBit) {
+            c->markBit = 1;
+            // ### GC
+            reinterpret_cast<ExecutionContext *>(c)->markObjects(c, this);
         }
-        c = c->d()->parent;
+        c = c->parent;
     }
 
     id_empty->mark(this);
index 1f37ea1..cc5d6ef 100644 (file)
@@ -460,7 +460,7 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData)
     ctx.function = f.getPointer()->d();
     ctx.compilationUnit = f->function()->compilationUnit;
     ctx.lookups = ctx.compilationUnit->runtimeLookups;
-    ctx.outer = f->scope();
+    ctx.outer = f->scope()->d();
     ctx.locals = v4->stackPush(f->varCount());
     while (callData->argc < (int)f->formalParameterCount()) {
         callData->args[callData->argc] = Encode::undefined();
@@ -497,7 +497,7 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData)
     ctx.function = f->d();
     ctx.compilationUnit = f->function()->compilationUnit;
     ctx.lookups = ctx.compilationUnit->runtimeLookups;
-    ctx.outer = f->scope();
+    ctx.outer = f->scope()->d();
     ctx.locals = v4->stackPush(f->varCount());
     while (callData->argc < (int)f->formalParameterCount()) {
         callData->args[callData->argc] = Encode::undefined();
index 0bb679a..85ffd81 100644 (file)
@@ -269,6 +269,14 @@ struct Scoped
         ++scope.size;
 #endif
     }
+    Scoped(const Scope &scope, typename T::Data *t)
+    {
+        ptr = scope.engine->jsStackTop++;
+        *ptr = Value::fromHeapObject(t);
+#ifndef QT_NO_DEBUG
+        ++scope.size;
+#endif
+    }
     template<typename X>
     Scoped(const Scope &scope, X *t, _Cast)
     {
@@ -325,6 +333,10 @@ struct Scoped
         setPointer(value_cast<T>(v));
         return *this;
     }
+    Scoped<T> &operator=(typename T::Data *t) {
+        *ptr = Value::fromHeapObject(t);
+        return *this;
+    }
     Scoped<T> &operator=(const Value &v) {
         setPointer(value_cast<T>(v));
         return *this;
index 7f2e44e..e262eaa 100644 (file)
@@ -162,8 +162,9 @@ void QmlBindingWrapper::markObjects(Heap::Base *m, ExecutionEngine *e)
 
 static ReturnedValue signalParameterGetter(QV4::CallContext *ctx, uint parameterIndex)
 {
-    QV4::CallContext *signalEmittingContext = ctx->d()->parent->asCallContext();
-    Q_ASSERT(signalEmittingContext);
+    QV4::Scope scope(ctx);
+    QV4::Scoped<CallContext> signalEmittingContext(scope, static_cast<Heap::CallContext *>(ctx->d()->parent));
+    Q_ASSERT(signalEmittingContext && signalEmittingContext->d()->type >= QV4::Heap::ExecutionContext::Type_SimpleCallContext);
     return signalEmittingContext->argument(parameterIndex);
 }
 
index af53847..bc711b4 100644 (file)
@@ -189,10 +189,10 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
     // setup lookup scopes
     int scopeDepth = 0;
     {
-        QV4::ExecutionContext *scope = context;
+        QV4::Heap::ExecutionContext *scope = context->d();
         while (scope) {
             ++scopeDepth;
-            scope = scope->d()->outer;
+            scope = scope->outer;
         }
     }
 
@@ -201,19 +201,19 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
         scopes[0] = const_cast<QV4::Value *>(context->d()->compilationUnit->data->constants());
         // stack gets setup in push instruction
         scopes[1] = 0;
-        QV4::ExecutionContext *scope = context;
+        QV4::Heap::ExecutionContext *scope = context->d();
         int i = 0;
         while (scope) {
-            if (scope->d()->type >= QV4::Heap::ExecutionContext::Type_SimpleCallContext) {
-                QV4::CallContext *cc = static_cast<QV4::CallContext *>(scope);
-                scopes[2*i + 2] = cc->d()->callData->args;
-                scopes[2*i + 3] = cc->d()->locals;
+            if (scope->type >= QV4::Heap::ExecutionContext::Type_SimpleCallContext) {
+                QV4::Heap::CallContext *cc = static_cast<QV4::Heap::CallContext *>(scope);
+                scopes[2*i + 2] = cc->callData->args;
+                scopes[2*i + 3] = cc->locals;
             } else {
                 scopes[2*i + 2] = 0;
                 scopes[2*i + 3] = 0;
             }
             ++i;
-            scope = scope->d()->outer;
+            scope = scope->outer;
         }
     }
 
index efcd557..c4bf9e4 100644 (file)
@@ -1699,6 +1699,7 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx)
     if ((ctx->d()->callData->argc > 2) && !ctx->d()->callData->args[2].isNumber())
         V4THROW_ERROR("qsTr(): third argument (n) must be a number");
 
+    Scope scope(ctx);
     QV8Engine *v8engine = ctx->d()->engine->v8Engine;
     QString context;
     if (QQmlContextData *ctxt = v8engine->callingContext()) {
@@ -1707,7 +1708,8 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx)
         int lastDot = path.lastIndexOf(QLatin1Char('.'));
         int length = lastDot - (lastSlash + 1);
         context = (lastSlash > -1) ? path.mid(lastSlash + 1, (length > -1) ? length : -1) : QString();
-    } else if (QV4::ExecutionContext *parentCtx = ctx->d()->parent) {
+    } else if (ctx->d()->parent) {
+        Scoped<ExecutionContext> parentCtx(scope, ctx->d()->parent);
         // The first non-empty source URL in the call stack determines the translation context.
         while (parentCtx && context.isEmpty()) {
             if (QV4::CompiledData::CompilationUnit *unit = parentCtx->d()->compilationUnit) {