aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@theqtcompany.com>2015-08-24 15:31:46 +0200
committerLars Knoll <lars.knoll@theqtcompany.com>2015-09-15 07:37:16 +0000
commit3a8d6123d1947d18db15bf8b30f59cdea7e31380 (patch)
tree7ad4ca820c395099e938fd9dacffbe27728d24d7
parentfb059f697a128f87ceecf5ddff1dd735ae78db20 (diff)
Store the stack of executioncontext's on the JS stack
This saves one pointer per allocated execution context. Now every execution context that is pushed, allocates two Values on the js stack. One contains the context itself, the other one the offset to the parent context. Things are a bit tricky for with and catch scopes, as those are called from the generated code, and can't open a Scope anymore. In addition, all methods iterating over the js stack frames need to work with ExecutionContext pointers, not ScopedContext's. Change-Id: I6f3013749d4e73d2fac37973b976ba6029686b82 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp19
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h2
-rw-r--r--src/qml/jsruntime/qv4context.cpp16
-rw-r--r--src/qml/jsruntime/qv4context_p.h21
-rw-r--r--src/qml/jsruntime/qv4debugging.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp45
-rw-r--r--src/qml/jsruntime/qv4engine_p.h36
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp29
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h13
-rw-r--r--src/qml/memory/qv4mm.cpp6
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp8
11 files changed, 100 insertions, 97 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index 2ef7713ac7..49dde9e8bf 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -43,13 +43,9 @@
QT_BEGIN_NAMESPACE
-QV4::Heap::CallContext *QV4DataCollector::findContext(QV4::Heap::ExecutionContext *ctxt, int frame)
+QV4::Heap::CallContext *QV4DataCollector::findContext(QV4::ExecutionEngine *engine, int frame)
{
- if (!ctxt)
- return 0;
-
- QV4::Scope scope(ctxt->engine);
- QV4::ScopedContext ctx(scope, ctxt);
+ QV4::ExecutionContext *ctx = engine->currentExecutionContext;
while (ctx) {
QV4::CallContext *cCtxt = ctx->asCallContext();
if (cCtxt && cCtxt->d()->function) {
@@ -57,7 +53,7 @@ QV4::Heap::CallContext *QV4DataCollector::findContext(QV4::Heap::ExecutionContex
return cCtxt->d();
--frame;
}
- ctx = ctx->d()->parent;
+ ctx = engine->parentContext(ctx);
}
return 0;
@@ -82,7 +78,7 @@ QVector<QV4::Heap::ExecutionContext::ContextType> QV4DataCollector::getScopeType
QVector<QV4::Heap::ExecutionContext::ContextType> types;
QV4::Scope scope(engine);
- QV4::Scoped<QV4::CallContext> sctxt(scope, findContext(engine->currentContext(), frame));
+ QV4::Scoped<QV4::CallContext> sctxt(scope, findContext(engine, frame));
if (!sctxt || sctxt->d()->type < QV4::Heap::ExecutionContext::Type_QmlContext)
return types;
@@ -384,7 +380,7 @@ void ArgumentCollectJob::run()
QV4::Scope scope(engine);
QV4::Scoped<QV4::CallContext> ctxt(
scope, QV4DataCollector::findScope(
- QV4DataCollector::findContext(engine->currentContext(), frameNr), scopeNr));
+ QV4DataCollector::findContext(engine, frameNr), scopeNr));
if (!ctxt)
return;
@@ -417,7 +413,7 @@ void LocalCollectJob::run()
QV4::Scope scope(engine);
QV4::Scoped<QV4::CallContext> ctxt(
scope, QV4DataCollector::findScope(
- QV4DataCollector::findContext(engine->currentContext(), frameNr), scopeNr));
+ QV4DataCollector::findContext(engine, frameNr), scopeNr));
if (!ctxt)
return;
@@ -448,8 +444,7 @@ void ThisCollectJob::run()
bool ThisCollectJob::myRun()
{
QV4::Scope scope(engine);
- QV4::ScopedContext ctxt(scope, QV4DataCollector::findContext(engine->currentContext(),
- frameNr));
+ QV4::ScopedContext ctxt(scope, QV4DataCollector::findContext(engine, frameNr));
while (ctxt) {
if (QV4::CallContext *cCtxt = ctxt->asCallContext())
if (cCtxt->d()->activation)
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
index 7d26d71bdf..f8cd0c1508 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
@@ -45,7 +45,7 @@ public:
typedef uint Ref;
typedef QVector<uint> Refs;
- static QV4::Heap::CallContext *findContext(QV4::Heap::ExecutionContext *ctxt, int frame);
+ static QV4::Heap::CallContext *findContext(QV4::ExecutionEngine *engine, int frame);
static QV4::Heap::CallContext *findScope(QV4::Heap::ExecutionContext *ctxt, int scope);
static QVector<QV4::Heap::ExecutionContext::ContextType> getScopeTypes(
QV4::ExecutionEngine *engine, int frame);
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 57c791e6a8..22dd0b17b9 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -83,14 +83,16 @@ Heap::CallContext *ExecutionContext::newCallContext(const FunctionObject *functi
return c;
}
-Heap::WithContext *ExecutionContext::newWithContext(Object *with)
+Heap::WithContext *ExecutionContext::newWithContext(Heap::Object *with)
{
return d()->engine->memoryManager->alloc<WithContext>(d(), with);
}
-Heap::CatchContext *ExecutionContext::newCatchContext(String *exceptionVarName, const Value &exceptionValue)
+Heap::CatchContext *ExecutionContext::newCatchContext(Heap::String *exceptionVarName, ReturnedValue exceptionValue)
{
- return d()->engine->memoryManager->alloc<CatchContext>(d(), exceptionVarName, exceptionValue);
+ Scope scope(this);
+ ScopedValue e(scope, exceptionValue);
+ return d()->engine->memoryManager->alloc<CatchContext>(d(), exceptionVarName, e);
}
Heap::QmlContext *ExecutionContext::newQmlContext(QmlContextWrapper *qml)
@@ -150,7 +152,7 @@ Heap::GlobalContext::GlobalContext(ExecutionEngine *eng)
global = eng->globalObject->d();
}
-Heap::WithContext::WithContext(ExecutionContext *outerContext, QV4::Object *with)
+Heap::WithContext::WithContext(ExecutionContext *outerContext, Object *with)
: Heap::ExecutionContext(outerContext->engine, Heap::ExecutionContext::Type_WithContext)
{
outer = outerContext;
@@ -158,10 +160,10 @@ Heap::WithContext::WithContext(ExecutionContext *outerContext, QV4::Object *with
lookups = outer->lookups;
compilationUnit = outer->compilationUnit;
- withObject = with ? with->d() : 0;
+ withObject = with;
}
-Heap::CatchContext::CatchContext(ExecutionContext *outerContext, QV4::String *exceptionVarName, const Value &exceptionValue)
+Heap::CatchContext::CatchContext(ExecutionContext *outerContext, String *exceptionVarName, const Value &exceptionValue)
: Heap::ExecutionContext(outerContext->engine, Heap::ExecutionContext::Type_CatchContext)
{
outer = outerContext;
@@ -170,7 +172,7 @@ Heap::CatchContext::CatchContext(ExecutionContext *outerContext, QV4::String *ex
lookups = outer->lookups;
compilationUnit = outer->compilationUnit;
- this->exceptionVarName = exceptionVarName->d();
+ this->exceptionVarName = exceptionVarName;
this->exceptionValue = exceptionValue;
}
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index cccca8a4fd..2807d1e29c 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -89,7 +89,6 @@ struct ExecutionContext : Base {
CallData *callData;
ExecutionEngine *engine;
- Pointer<ExecutionContext> parent;
Pointer<ExecutionContext> outer;
Lookup *lookups;
CompiledData::CompilationUnit *compilationUnit;
@@ -99,6 +98,18 @@ struct ExecutionContext : Base {
int lineNumber;
};
+inline
+ExecutionContext::ExecutionContext(ExecutionEngine *engine, ContextType t)
+ : engine(engine)
+ , outer(0)
+ , lookups(0)
+ , compilationUnit(0)
+ , type(t)
+ , strictMode(false)
+ , lineNumber(-1)
+{}
+
+
struct CallContext : ExecutionContext {
CallContext(ExecutionEngine *engine, ContextType t = Type_SimpleCallContext)
: ExecutionContext(engine, t)
@@ -119,13 +130,13 @@ struct GlobalContext : ExecutionContext {
};
struct CatchContext : ExecutionContext {
- CatchContext(ExecutionContext *outerContext, QV4::String *exceptionVarName, const Value &exceptionValue);
+ CatchContext(ExecutionContext *outerContext, String *exceptionVarName, const Value &exceptionValue);
Pointer<String> exceptionVarName;
Value exceptionValue;
};
struct WithContext : ExecutionContext {
- WithContext(ExecutionContext *outerContext, QV4::Object *with);
+ WithContext(ExecutionContext *outerContext, Object *with);
Pointer<Object> withObject;
};
@@ -150,8 +161,8 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
ExecutionEngine *engine() const { return d()->engine; }
Heap::CallContext *newCallContext(const FunctionObject *f, CallData *callData);
- Heap::WithContext *newWithContext(Object *with);
- Heap::CatchContext *newCatchContext(String *exceptionVarName, const Value &exceptionValue);
+ Heap::WithContext *newWithContext(Heap::Object *with);
+ Heap::CatchContext *newCatchContext(Heap::String *exceptionVarName, ReturnedValue exceptionValue);
Heap::QmlContext *newQmlContext(QmlContextWrapper *qml);
Heap::QmlContext *newQmlContext(QQmlContextData *context, QObject *scopeObject);
diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp
index 1833215c42..8a60a81b93 100644
--- a/src/qml/jsruntime/qv4debugging.cpp
+++ b/src/qml/jsruntime/qv4debugging.cpp
@@ -249,7 +249,7 @@ void Debugger::leavingFunction(const ReturnedValue &retVal)
QMutexLocker locker(&m_lock);
if (m_stepping != NotStepping && m_currentContext.asManaged()->d() == m_engine->currentContext()) {
- m_currentContext.set(m_engine, m_engine->currentContext()->parent);
+ m_currentContext.set(m_engine, *m_engine->parentContext(m_engine->currentExecutionContext));
m_stepping = StepOver;
m_returnedValue.set(m_engine, retVal);
}
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index d6448f7030..5ea8205fad 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -200,6 +200,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
, memoryManager(new QV4::MemoryManager(this))
, executableAllocator(new QV4::ExecutableAllocator)
, regExpAllocator(new QV4::ExecutableAllocator)
+ , currentExecutionContext(0)
, bumperPointerAllocator(new WTF::BumpPointerAllocator)
, jsStack(new WTF::PageAllocation)
, debugger(0)
@@ -508,9 +509,11 @@ void ExecutionEngine::initRootContext()
r->d()->callData->argc = 0;
r->d()->callData->thisObject = globalObject;
r->d()->callData->args[0] = Encode::undefined();
- current = r->d();
-
jsObjects[RootContect] = r;
+ jsObjects[IntegerNull] = Encode((int)0);
+
+ currentExecutionContext = static_cast<ExecutionContext *>(jsObjects + RootContect);
+ current = currentExecutionContext->d();
}
InternalClass *ExecutionEngine::newClass(const InternalClass &other)
@@ -520,13 +523,18 @@ InternalClass *ExecutionEngine::newClass(const InternalClass &other)
Heap::ExecutionContext *ExecutionEngine::pushGlobalContext()
{
- Scope scope(this);
- Scoped<GlobalContext> g(scope, memoryManager->alloc<GlobalContext>(this));
- g->d()->callData = rootContext()->d()->callData;
- pushContext(g->d());
+ pushContext(rootContext()->d());
- Q_ASSERT(currentContext() == g->d());
- return g->d();
+ Q_ASSERT(currentContext() == rootContext()->d());
+ return currentContext();
+}
+
+ExecutionContext *ExecutionEngine::parentContext(ExecutionContext *context) const
+{
+ Value *offset = static_cast<Value *>(context) + 1;
+ Q_ASSERT(offset->isInteger());
+ int o = offset->integerValue();
+ return o ? context - o : 0;
}
@@ -733,7 +741,7 @@ Heap::QmlContext *ExecutionEngine::qmlContext() const
// get the correct context when we're within a builtin function
if (ctx->type == Heap::ExecutionContext::Type_SimpleCallContext && !ctx->outer)
- ctx = ctx->parent;
+ ctx = parentContext(currentExecutionContext)->d();
if (!ctx->outer)
return 0;
@@ -793,7 +801,7 @@ QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const
ScopedString name(scope);
QVector<StackFrame> stack;
- ScopedContext c(scope, currentContext());
+ ExecutionContext *c = currentExecutionContext;
ScopedFunctionObject function(scope);
while (c && frameLimit) {
function = c->getFunctionObject();
@@ -813,7 +821,7 @@ QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const
stack.append(frame);
--frameLimit;
}
- c = c->d()->parent;
+ c = parentContext(c);
}
if (frameLimit && globalCode) {
@@ -881,8 +889,7 @@ QUrl ExecutionEngine::resolvedUrl(const QString &file)
return src;
QUrl base;
- Scope scope(this);
- ScopedContext c(scope, currentContext());
+ ExecutionContext *c = currentExecutionContext;
while (c) {
CallContext *callCtx = c->asCallContext();
if (callCtx && callCtx->d()->function) {
@@ -890,7 +897,7 @@ QUrl ExecutionEngine::resolvedUrl(const QString &file)
base.setUrl(callCtx->d()->function->function->sourceFile());
break;
}
- c = c->d()->parent;
+ c = parentContext(c);
}
if (base.isEmpty() && globalCode)
@@ -940,16 +947,6 @@ void ExecutionEngine::markObjects()
setter->mark(this);
}
- Heap::ExecutionContext *c = currentContext();
- while (c) {
- Q_ASSERT(c->inUse());
- if (!c->isMarked()) {
- c->setMarkBit();
- c->vtable()->markObjects(c, this);
- }
- c = c->parent;
- }
-
classPool->markObjects(this);
for (QSet<CompiledData::CompilationUnit*>::ConstIterator it = compilationUnits.constBegin(), end = compilationUnits.constEnd();
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 968c9d5df0..e9d505c858 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -88,6 +88,7 @@ public:
ExecutableAllocator *regExpAllocator;
QScopedPointer<EvalISelFactory> iselFactory;
+ ExecutionContext *currentExecutionContext;
Value *jsStackLimit;
quintptr cStackLimit;
@@ -128,6 +129,7 @@ public:
enum JSObjects {
RootContect,
+ IntegerNull, // Has to come after the RootContext to make the context stack safe
ObjectProto,
ArrayProto,
StringProto,
@@ -351,6 +353,7 @@ public:
void pushContext(Heap::ExecutionContext *context);
void pushContext(CallContext *context);
Heap::ExecutionContext *popContext();
+ ExecutionContext *parentContext(ExecutionContext *context) const;
Heap::Object *newObject();
Heap::Object *newObject(InternalClass *internalClass, Object *prototype);
@@ -444,9 +447,12 @@ public:
inline void ExecutionEngine::pushContext(Heap::ExecutionContext *context)
{
- Q_ASSERT(current && context);
- context->parent = current;
- current = context;
+ Q_ASSERT(currentExecutionContext && context);
+ Value *v = jsAlloca(2);
+ v[0] = Encode(context);
+ v[1] = Encode((int)(v - static_cast<Value *>(currentExecutionContext)));
+ currentExecutionContext = static_cast<ExecutionContext *>(v);
+ current = currentExecutionContext->d();
}
inline void ExecutionEngine::pushContext(CallContext *context)
@@ -457,27 +463,17 @@ inline void ExecutionEngine::pushContext(CallContext *context)
inline Heap::ExecutionContext *ExecutionEngine::popContext()
{
- Q_ASSERT(current->parent);
- current = current->parent;
- Q_ASSERT(current);
+ Q_ASSERT(jsStackTop > currentExecutionContext);
+ QV4::Value *offset = (currentExecutionContext + 1);
+ Q_ASSERT(offset->isInteger());
+ int o = offset->integerValue();
+ Q_ASSERT(o);
+ currentExecutionContext -= o;
+ current = currentExecutionContext->d();
return current;
}
inline
-Heap::ExecutionContext::ExecutionContext(ExecutionEngine *engine, ContextType t)
- : engine(engine)
- , parent(engine->currentContext())
- , outer(0)
- , lookups(0)
- , compilationUnit(0)
- , type(t)
- , strictMode(false)
- , lineNumber(-1)
-{
-}
-
-
-inline
void Heap::Base::mark(QV4::ExecutionEngine *engine)
{
Q_ASSERT(inUse());
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 5cc47aacd8..ca3195b405 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1175,14 +1175,6 @@ QV4::ReturnedValue Runtime::typeofElement(ExecutionEngine *engine, const Value &
return Runtime::typeofValue(engine, prop);
}
-void Runtime::pushWithScope(const Value &o, ExecutionEngine *engine)
-{
- Scope scope(engine);
- ScopedObject obj(scope, o.toObject(engine));
- ScopedContext ctx(scope, engine->currentContext());
- engine->pushContext(ctx->newWithContext(obj));
-}
-
ReturnedValue Runtime::unwindException(ExecutionEngine *engine)
{
if (!engine->hasException)
@@ -1190,18 +1182,29 @@ ReturnedValue Runtime::unwindException(ExecutionEngine *engine)
return engine->catchException(0);
}
+/* The next three methods are a bit tricky. They can't open up a Scope, as that
+ * would mess up the pushing of the context.
+ *
+ * Instead the push/pop pair acts as a non local scope.
+ */
+void Runtime::pushWithScope(const Value &o, ExecutionEngine *engine)
+{
+ engine->pushContext(engine->currentExecutionContext->newWithContext(o.toObject(engine)));
+ Q_ASSERT(engine->jsStackTop = engine->currentExecutionContext + 2);
+}
+
void Runtime::pushCatchScope(NoThrowEngine *engine, int exceptionVarNameIndex)
{
- Scope scope(engine);
- ScopedValue v(scope, engine->catchException(0));
- ScopedString exceptionVarName(scope, engine->currentContext()->compilationUnit->runtimeStrings[exceptionVarNameIndex]);
- ScopedContext ctx(scope, engine->currentContext());
- engine->pushContext(ctx->newCatchContext(exceptionVarName, v));
+ ExecutionContext *c = engine->currentExecutionContext;
+ engine->pushContext(c->newCatchContext(c->d()->compilationUnit->runtimeStrings[exceptionVarNameIndex], engine->catchException(0)));
+ Q_ASSERT(engine->jsStackTop = engine->currentExecutionContext + 2);
}
void Runtime::popScope(ExecutionEngine *engine)
{
+ Q_ASSERT(engine->jsStackTop = engine->currentExecutionContext + 2);
engine->popContext();
+ engine->jsStackTop -= 2;
}
void Runtime::declareVar(ExecutionEngine *engine, bool deletable, int nameIndex)
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 563b8b0e93..0f0d50bdee 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -73,6 +73,7 @@ struct Scope {
~Scope() {
#ifndef QT_NO_DEBUG
Q_ASSERT(engine->jsStackTop >= mark);
+ Q_ASSERT(engine->currentExecutionContext < mark);
memset(mark, 0, (engine->jsStackTop - mark)*sizeof(Value));
#endif
#ifdef V4_USE_VALGRIND
@@ -414,20 +415,18 @@ struct ScopedProperty
struct ExecutionContextSaver
{
ExecutionEngine *engine;
- Value *savedContext;
+ ExecutionContext *savedContext;
ExecutionContextSaver(Scope &scope)
: engine(scope.engine)
- , savedContext(scope.alloc(1))
{
- savedContext->setM(scope.engine->currentContext());
-#if QT_POINTER_SIZE == 4
- savedContext->setTag(QV4::Value::Managed_Type);
-#endif
+ savedContext = engine->currentExecutionContext;
}
~ExecutionContextSaver()
{
- engine->current = static_cast<Heap::ExecutionContext *>(savedContext->heapObject());
+ Q_ASSERT(engine->jsStackTop > engine->currentExecutionContext);
+ engine->currentExecutionContext = savedContext;
+ engine->current = savedContext->d();
}
};
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 5a7953679b..26a705961b 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -483,10 +483,10 @@ void MemoryManager::sweep(bool lastSweep)
// some execution contexts are allocated on the stack, make sure we clear their markBit as well
if (!lastSweep) {
- Heap::ExecutionContext *ctx = engine()->currentContext();
+ QV4::ExecutionContext *ctx = engine()->currentExecutionContext;
while (ctx) {
- ctx->clearMarkBit();
- ctx = ctx->parent;
+ ctx->d()->clearMarkBit();
+ ctx = engine()->parentContext(ctx);
}
}
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index ce86fd3923..f2f743a6cb 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1737,10 +1737,10 @@ 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 (ctx->d()->parent) {
- ScopedContext parentCtx(scope, ctx->d()->parent);
+ } else {
+ ExecutionContext *parentCtx = scope.engine->parentContext(ctx);
// The first non-empty source URL in the call stack determines the translation context.
- while (parentCtx && context.isEmpty()) {
+ while (!!parentCtx && context.isEmpty()) {
if (QV4::CompiledData::CompilationUnit *unit = parentCtx->d()->compilationUnit) {
QString fileName = unit->fileName();
QUrl url(unit->fileName());
@@ -1753,7 +1753,7 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx)
}
context = QFileInfo(context).baseName();
}
- parentCtx = parentCtx->d()->parent;
+ parentCtx = scope.engine->parentContext(parentCtx);
}
}