diff options
Diffstat (limited to 'src/script/api')
-rw-r--r-- | src/script/api/qscriptengine.cpp | 30 | ||||
-rw-r--r-- | src/script/api/qscriptengine.h | 2 | ||||
-rw-r--r-- | src/script/api/qscriptengine_p.h | 2 | ||||
-rw-r--r-- | src/script/api/qscriptvalue.cpp | 5 |
4 files changed, 35 insertions, 4 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 2b60a46a89..216f325f6b 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -1093,6 +1093,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) @@ -1130,6 +1132,22 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack) markStack.append((*it)->prototype); } } + + { + QScriptContext *context = q->currentContext(); + + while (context) { + JSC::ScopeChainNode *node = frameForContext(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 @@ -2281,7 +2299,8 @@ QScriptContext *QScriptEngine::pushContext() return the new top frame. (might be the same as exec if a new stackframe was not needed) or 0 if stack overflow */ JSC::CallFrame *QScriptEnginePrivate::pushContext(JSC::CallFrame *exec, JSC::JSValue _thisObject, - const JSC::ArgList& args, JSC::JSObject *callee, bool calledAsConstructor) + const JSC::ArgList& args, JSC::JSObject *callee, bool calledAsConstructor, + bool clearScopeChain) { JSC::JSValue thisObject = _thisObject; if (calledAsConstructor) { @@ -2315,7 +2334,14 @@ JSC::CallFrame *QScriptEnginePrivate::pushContext(JSC::CallFrame *exec, JSC::JSV for (it = args.begin(); it != args.end(); ++it) newCallFrame[++dst] = *it; newCallFrame += argc + JSC::RegisterFile::CallFrameHeaderSize; - newCallFrame->init(0, /*vPC=*/0, exec->scopeChain(), exec, flags | ShouldRestoreCallFrame, argc, callee); + + if (!clearScopeChain) { + newCallFrame->init(0, /*vPC=*/0, exec->scopeChain(), exec, flags | ShouldRestoreCallFrame, argc, callee); + } else { + JSC::JSObject *jscObject = originalGlobalObject(); + JSC::ScopeChainNode *scn = new JSC::ScopeChainNode(0, jscObject, &exec->globalData(), jscObject); + newCallFrame->init(0, /*vPC=*/0, scn, exec, flags | ShouldRestoreCallFrame, argc, callee); + } } else { setContextFlags(newCallFrame, flags); #if ENABLE(JIT) diff --git a/src/script/api/qscriptengine.h b/src/script/api/qscriptengine.h index 3f438da142..7db61e19e6 100644 --- a/src/script/api/qscriptengine.h +++ b/src/script/api/qscriptengine.h @@ -56,6 +56,7 @@ #include <QtScript/qscriptvalue.h> #include <QtScript/qscriptcontext.h> #include <QtScript/qscriptstring.h> +#include <QtScript/qscriptprogram.h> QT_BEGIN_HEADER @@ -67,7 +68,6 @@ class QDateTime; class QScriptClass; class QScriptEngineAgent; class QScriptEnginePrivate; -class QScriptProgram; #ifndef QT_NO_QOBJECT diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index d12b0f4a59..e7cdcda640 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -174,7 +174,7 @@ public: static JSC::Register *thisRegisterForFrame(JSC::ExecState *frame); JSC::CallFrame *pushContext(JSC::CallFrame *exec, JSC::JSValue thisObject, const JSC::ArgList& args, - JSC::JSObject *callee, bool calledAsConstructor = false); + JSC::JSObject *callee, bool calledAsConstructor = false, bool clearScopeChain = false); void popContext(); void mark(JSC::MarkStack& markStack); diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 52a1e6d4c6..d6cbb417a8 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -71,6 +71,7 @@ #include "bridge/qscriptclassobject_p.h" #include "bridge/qscriptvariant_p.h" #include "bridge/qscriptqobject_p.h" +#include "bridge/qscriptdeclarativeclass_p.h" /*! \since 4.3 @@ -1496,6 +1497,8 @@ QVariant QScriptValue::toVariant() const #endif else if (isArray()) return QScriptEnginePrivate::variantListFromArray(*this); + else if (QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(*this)) + return dc->toVariant(QScriptDeclarativeClass::object(*this)); // try to convert to primitive JSC::ExecState *exec = d->engine->currentFrame; JSC::JSValue savedException; @@ -1586,6 +1589,8 @@ QObject *QScriptValue::toQObject() const if (isQObject()) { QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); return static_cast<QScript::QObjectDelegate*>(object->delegate())->value(); + } else if (QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(*this)) { + return dc->toQObject(QScriptDeclarativeClass::object(*this)); } else if (isVariant()) { QVariant var = toVariant(); int type = var.userType(); |