summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-07-30 14:57:15 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-07-30 14:57:15 (GMT)
commit34e6fb628673cfa7b56cad95b765ef3a0fc24f66 (patch)
treeaa96b993020d3e734a99024615b88b7ceedca48f
parent3963331128f8af4dc1008a7efbbd1ccf292df567 (diff)
downloadQt-34e6fb628673cfa7b56cad95b765ef3a0fc24f66.zip
Qt-34e6fb628673cfa7b56cad95b765ef3a0fc24f66.tar.gz
Qt-34e6fb628673cfa7b56cad95b765ef3a0fc24f66.tar.bz2
implement QScriptContext::activationObject()
-rw-r--r--src/script/api/qscriptcontext.cpp47
-rw-r--r--tests/auto/qscriptcontext/tst_qscriptcontext.cpp17
-rw-r--r--tests/auto/qscriptengine/tst_qscriptengine.cpp7
3 files changed, 47 insertions, 24 deletions
diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp
index e820596..15e4efe 100644
--- a/src/script/api/qscriptcontext.cpp
+++ b/src/script/api/qscriptcontext.cpp
@@ -47,6 +47,7 @@
#include "qscriptcontextinfo.h"
#include "qscriptengine.h"
#include "qscriptengine_p.h"
+#include "../bridge/qscriptactivationobject_p.h"
#include "Arguments.h"
#include "CodeBlock.h"
@@ -432,14 +433,34 @@ void QScriptContext::setReturnValue(const QScriptValue &result)
QScriptValue QScriptContext::activationObject() const
{
Q_D(const QScriptContext);
- JSC::CodeBlock *codeBlock = d->frame->codeBlock();
- if (!codeBlock) {
- qWarning("QScriptContext::activationObject() not implemented for native functions");
- return QScriptValue();
- }
// ### this is still a bit shaky
- JSC::FunctionBodyNode *body = static_cast<JSC::FunctionBodyNode*>(codeBlock->ownerNode());
- return d->engine->scriptValueFromJSCValue(new (&d->frame->globalData())JSC::JSActivation(d->frame, body));
+ // if properties of the activation are accessed after this context is
+ // popped, we CRASH.
+ // Ideally we should be able to store the activation object in the callframe
+ // and JSC would clean it up for us.
+ JSC::JSObject *result = 0;
+ // look in scope chain
+ {
+ JSC::ScopeChainNode *node = d->frame->scopeChain();
+ JSC::ScopeChainIterator it(node);
+ for (it = node->begin(); it != node->end(); ++it) {
+ if ((*it)->isVariableObject()) {
+ result = *it;
+ break;
+ }
+ }
+ }
+ if (!result) {
+ JSC::CodeBlock *codeBlock = d->frame->codeBlock();
+ if (!codeBlock) {
+ // native function
+ result = new (d->frame)QScript::QScriptActivationObject(d->frame);
+ } else {
+ JSC::FunctionBodyNode *body = static_cast<JSC::FunctionBodyNode*>(codeBlock->ownerNode());
+ result = new (d->frame)JSC::JSActivation(d->frame, body);
+ }
+ }
+ return d->engine->scriptValueFromJSCValue(result);
}
/*!
@@ -450,8 +471,16 @@ QScriptValue QScriptContext::activationObject() const
*/
void QScriptContext::setActivationObject(const QScriptValue &activation)
{
- Q_ASSERT_X(false, Q_FUNC_INFO, "not implemented");
- Q_UNUSED(activation);
+ Q_D(QScriptContext);
+ if (!activation.isObject())
+ return;
+ JSC::JSObject *object = JSC::asObject(d->engine->scriptValueToJSCValue(activation));
+ if (!object->isVariableObject()) {
+ qWarning("QScriptContext::setActivationObject(): not an activation object");
+ return;
+ }
+// ### look for variableObject in d->frame->scopeChain, replace by object
+ qWarning("QScriptContext::setActivationObject() not implemented");
}
/*!
diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
index 3e32230..4726815 100644
--- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
+++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
@@ -302,10 +302,10 @@ void tst_QScriptContext::returnValue()
{
QScriptEngine eng;
eng.evaluate("123");
- QEXPECT_FAIL("", "Doesn't work", Continue);
+ QEXPECT_FAIL("", "", Continue);
QCOMPARE(eng.currentContext()->returnValue().toNumber(), 123.0);
eng.evaluate("\"ciao\"");
- QEXPECT_FAIL("", "Doesn't work", Continue);
+ QEXPECT_FAIL("", "", Continue);
QCOMPARE(eng.currentContext()->returnValue().toString(), QString("ciao"));
}
@@ -473,7 +473,6 @@ void tst_QScriptContext::pushAndPopContext()
QCOMPARE(ctx->argument(0).isUndefined(), true);
QVERIFY(!ctx->argument(-1).isValid());
QCOMPARE(ctx->argumentsObject().isObject(), true);
- QEXPECT_FAIL("", "activationObject not yet implemented", Continue);
QCOMPARE(ctx->activationObject().isObject(), true);
QCOMPARE(ctx->callee().isValid(), false);
QCOMPARE(ctx->thisObject().strictlyEquals(eng.globalObject()), true);
@@ -499,10 +498,8 @@ void tst_QScriptContext::pushAndPopContext()
{
QScriptContext *ctx3 = eng.pushContext();
ctx3->activationObject().setProperty("foo", QScriptValue(&eng, 123));
- QEXPECT_FAIL("", "activationObject not yet implemented", Continue);
QVERIFY(eng.evaluate("foo").strictlyEquals(QScriptValue(&eng, 123)));
eng.evaluate("var bar = 'ciao'");
- QEXPECT_FAIL("", "activationObject not yet implemented", Continue);
QVERIFY(ctx3->activationObject().property("bar", QScriptValue::ResolveLocal).strictlyEquals(QScriptValue(&eng, "ciao")));
eng.popContext();
}
@@ -704,7 +701,6 @@ void tst_QScriptContext::getSetActivationObject()
{
QScriptEngine eng;
QScriptContext *ctx = eng.currentContext();
- QEXPECT_FAIL("", "", Abort);
QVERIFY(ctx->activationObject().equals(eng.globalObject()));
ctx->setActivationObject(QScriptValue());
@@ -713,6 +709,7 @@ void tst_QScriptContext::getSetActivationObject()
QScriptValue obj = eng.newObject();
ctx->setActivationObject(obj);
+ QEXPECT_FAIL("", "", Abort);
QVERIFY(ctx->activationObject().equals(obj));
{
@@ -729,8 +726,12 @@ void tst_QScriptContext::getSetActivationObject()
{
QScriptValue ret = eng.evaluate("get_activationObject(1, 2, 3)");
QVERIFY(ret.isObject());
- QVERIFY(ret.property("arguments").isObject());
- QCOMPARE(ret.property("arguments").property("length").toInt32(), 3);
+ QScriptValue arguments = ret.property("arguments");
+ QVERIFY(arguments.isObject());
+ QCOMPARE(arguments.property("length").toInt32(), 3);
+ QCOMPARE(arguments.property("0").toInt32(), 1);
+ QCOMPARE(arguments.property("1").toInt32(), 1);
+ QCOMPARE(arguments.property("2").toInt32(), 1);
}
}
diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp
index 74368c5..9067005 100644
--- a/tests/auto/qscriptengine/tst_qscriptengine.cpp
+++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp
@@ -163,7 +163,6 @@ void tst_QScriptEngine::currentContext()
QVERIFY(!globalCtx->callee().isValid());
QCOMPARE(globalCtx->state(), QScriptContext::NormalState);
QVERIFY(globalCtx->thisObject().strictlyEquals(eng.globalObject()));
- QEXPECT_FAIL("", "", Continue);
QVERIFY(globalCtx->activationObject().strictlyEquals(eng.globalObject()));
QVERIFY(globalCtx->argumentsObject().isObject());
}
@@ -183,14 +182,12 @@ void tst_QScriptEngine::pushPopContext()
QCOMPARE(ctx->backtrace().size(), 2);
QCOMPARE(ctx->engine(), &eng);
QCOMPARE(ctx->state(), QScriptContext::NormalState);
- QEXPECT_FAIL("", "activationObject not implemented", Continue);
QVERIFY(ctx->activationObject().isObject());
QVERIFY(ctx->argumentsObject().isObject());
QScriptContext *ctx2 = eng.pushContext();
QVERIFY(ctx2 != 0);
QCOMPARE(ctx2->parentContext(), ctx);
- QEXPECT_FAIL("", "activationObject not implemented", Continue);
QVERIFY(!ctx2->activationObject().strictlyEquals(ctx->activationObject()));
QVERIFY(!ctx2->argumentsObject().strictlyEquals(ctx->argumentsObject()));
@@ -890,7 +887,6 @@ void tst_QScriptEngine::getSetGlobalObject()
QCOMPARE(glob.isObject(), true);
QVERIFY(!glob.isFunction());
QVERIFY(eng.currentContext()->thisObject().strictlyEquals(glob));
- QEXPECT_FAIL("", "Activation object for global context", Continue);
QVERIFY(eng.currentContext()->activationObject().strictlyEquals(glob));
QCOMPARE(glob.toString(), QString::fromLatin1("[object global]"));
// prototype should be Object.prototype
@@ -902,7 +898,6 @@ void tst_QScriptEngine::getSetGlobalObject()
eng.setGlobalObject(obj);
QVERIFY(eng.globalObject().strictlyEquals(obj));
QVERIFY(eng.currentContext()->thisObject().strictlyEquals(obj));
- QEXPECT_FAIL("", "this-object for global context", Continue);
QVERIFY(eng.currentContext()->activationObject().strictlyEquals(obj));
QVERIFY(eng.evaluate("this").strictlyEquals(obj));
QCOMPARE(eng.globalObject().toString(), QString::fromLatin1("[object Object]"));
@@ -913,13 +908,11 @@ void tst_QScriptEngine::getSetGlobalObject()
eng.setGlobalObject(obj);
QVERIFY(eng.globalObject().strictlyEquals(obj));
QVERIFY(eng.currentContext()->thisObject().strictlyEquals(obj));
- QEXPECT_FAIL("", "", Continue);
QVERIFY(eng.currentContext()->activationObject().strictlyEquals(obj));
eng.collectGarbage();
QVERIFY(eng.globalObject().strictlyEquals(obj));
QVERIFY(eng.currentContext()->thisObject().strictlyEquals(obj));
- QEXPECT_FAIL("", "", Continue);
QVERIFY(eng.currentContext()->activationObject().strictlyEquals(obj));
}