diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-10-22 06:47:53 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-10-22 06:47:53 (GMT) |
commit | 1ec93e68c36902a14545fc02af80821131c52d57 (patch) | |
tree | da5b78e62a4fb439992a7db570d94591cebf1072 /src/script | |
parent | a3b3ba02f0eba2f435f552a9aa64fc9fceade972 (diff) | |
download | Qt-1ec93e68c36902a14545fc02af80821131c52d57.zip Qt-1ec93e68c36902a14545fc02af80821131c52d57.tar.gz Qt-1ec93e68c36902a14545fc02af80821131c52d57.tar.bz2 |
During a GC mark the scope chain of QScriptContexts
It appears that simply being in the scope chain of an existant frame
isn't sufficient to be marked. This can lead to a QScriptContext
scope chain that contains a JSObject that has been collected.
For example, this code:
QScriptContext *ctxt = engine->pushContext();
ctxt.pushScope(engine->newObject());
previouslyCreatedFunctionObject.call(); // causes a GC
can lead to the object added to the scope chain to have become
invalid. This leads to hilarity later on.
Diffstat (limited to 'src/script')
-rw-r--r-- | src/script/api/qscriptengine.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 880fcd7..12c8695 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -1141,6 +1141,8 @@ void QScriptEnginePrivate::setContextFlags(JSC::ExecState *exec, uint flags) void QScriptEnginePrivate::mark(JSC::MarkStack& markStack) { + Q_Q(QScriptEngine); + markStack.append(originalGlobalObject()); markStack.append(globalObject()); if (originalGlobalObjectProxy) @@ -1178,6 +1180,22 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack) markStack.append((*it)->prototype); } } + + { + QScriptContext *context = q->currentContext(); + + while (context) { + JSC::ScopeChainNode *node = ((JSC::ExecState *)context)->scopeChain(); + JSC::ScopeChainIterator it(node); + for (it = node->begin(); it != node->end(); ++it) { + JSC::JSObject *object = *it; + if (object) + markStack.append(object); + } + + context = context->parentContext(); + } + } } bool QScriptEnginePrivate::isCollecting() const |