From 336f0bf740842ab8defdbf482a7f043de95857e4 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 10 Aug 2009 17:59:55 +0200 Subject: implement QScriptContext::setActivationObject() --- src/script/api/qscriptcontext.cpp | 22 +++++++++++++++++++--- tests/auto/qscriptcontext/tst_qscriptcontext.cpp | 8 ++++++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp index 0d2f20c..d6440b0 100644 --- a/src/script/api/qscriptcontext.cpp +++ b/src/script/api/qscriptcontext.cpp @@ -468,15 +468,31 @@ void QScriptContext::setActivationObject(const QScriptValue &activation) { if (!activation.isObject()) return; + else if (activation.engine() != engine()) { + qWarning("QScriptContext::setActivationObject() failed: " + "cannot set an object created in " + "a different engine"); + return; + } JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); JSC::JSObject *object = JSC::asObject(engine->scriptValueToJSCValue(activation)); + if (object == engine->originalGlobalObjectProxy) + object = engine->originalGlobalObject(); if (!object->isVariableObject()) { - qWarning("QScriptContext::setActivationObject(): not an activation object"); + qWarning("QScriptContext::setActivationObject() failed: not an activation object"); return; } -// ### look for variableObject in d->frame->scopeChain, replace by object - qWarning("QScriptContext::setActivationObject() not implemented"); + + // replace the first activation object in the scope chain + JSC::ScopeChainNode *node = frame->scopeChain(); + while (node != 0) { + if (node->object->isVariableObject()) { + node->object = object; + break; + } + node = node->next; + } } /*! diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp index eed0cb1..1bc375a 100644 --- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp +++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp @@ -704,25 +704,29 @@ void tst_QScriptContext::getSetActivationObject() QCOMPARE(ctx->engine(), &eng); QScriptValue obj = eng.newObject(); + QTest::ignoreMessage(QtWarningMsg, "QScriptContext::setActivationObject() failed: not an activation object"); ctx->setActivationObject(obj); - QEXPECT_FAIL("", "", Abort); + QEXPECT_FAIL("", "Normal object cannot be set as activation object", Continue); QVERIFY(ctx->activationObject().equals(obj)); { QScriptEngine eng2; QScriptValue obj2 = eng2.newObject(); QTest::ignoreMessage(QtWarningMsg, "QScriptContext::setActivationObject() failed: cannot set an object created in a different engine"); + QScriptValue was = ctx->activationObject(); ctx->setActivationObject(obj2); - QVERIFY(ctx->activationObject().equals(obj)); + QVERIFY(ctx->activationObject().equals(was)); } ctx->setActivationObject(eng.globalObject()); + QVERIFY(ctx->activationObject().equals(eng.globalObject())); QScriptValue fun = eng.newFunction(get_activationObject); eng.globalObject().setProperty("get_activationObject", fun); { QScriptValue ret = eng.evaluate("get_activationObject(1, 2, 3)"); QVERIFY(ret.isObject()); QScriptValue arguments = ret.property("arguments"); + QEXPECT_FAIL("", "Getting arguments property of activation object doesn't work", Abort); QVERIFY(arguments.isObject()); QCOMPARE(arguments.property("length").toInt32(), 3); QCOMPARE(arguments.property("0").toInt32(), 1); -- cgit v0.12