QScriptValue ScriptFunctionWrapper::callWith(const QScriptValue &val) { //qDebug() << "Call called" << d->name; QScriptEngine *eng = val.engine(); if (!eng) { qDebug() << "We cannot access the script-engine, fail!"; return QScriptValue(); } QScriptContext *ctx = eng->currentContext(); return d->object.property(d->name).call(QScriptValue(), ctx->argumentsObject()); }
QVariant TestClass::extension(Extension extension, const QVariant &argument) { m_lastExtensionType = extension; m_lastExtensionArgument = argument; if (extension == Callable) { Q_ASSERT(m_callableMode != NotCallable); QScriptContext *ctx = qvariant_cast<QScriptContext*>(argument); if (m_callableMode == CallableReturnsSum) { qsreal sum = 0; for (int i = 0; i < ctx->argumentCount(); ++i) sum += ctx->argument(i).toNumber(); QScriptValueIterator it(ctx->callee()); while (it.hasNext()) { it.next(); sum += it.value().toNumber(); } return sum; } else if (m_callableMode == CallableReturnsArgument) { return qVariantFromValue(ctx->argument(0)); } else if (m_callableMode == CallableReturnsInvalidVariant) { return QVariant(); } else if (m_callableMode == CallableReturnsGlobalObject) { return qVariantFromValue(engine()->globalObject()); } else if (m_callableMode == CallableReturnsThisObject) { return qVariantFromValue(ctx->thisObject()); } else if (m_callableMode == CallableReturnsCallee) { return qVariantFromValue(ctx->callee()); } else if (m_callableMode == CallableReturnsArgumentsObject) { return qVariantFromValue(ctx->argumentsObject()); } else if (m_callableMode == CallableInitializesThisObject) { engine()->newQObject(ctx->thisObject(), engine()); return QVariant(); } } else if (extension == HasInstance) { Q_ASSERT(m_hasInstance); QScriptValueList args = qvariant_cast<QScriptValueList>(argument); QScriptValue obj = args.at(0); QScriptValue value = args.at(1); return value.property("foo").equals(obj.property("foo")); } return QVariant(); }
void tst_QScriptContext::pushAndPopContext() { QScriptEngine eng; QScriptContext *topLevel = eng.currentContext(); QCOMPARE(topLevel->engine(), &eng); QScriptContext *ctx = eng.pushContext(); QVERIFY(ctx != 0); QCOMPARE(ctx->parentContext(), topLevel); QCOMPARE(eng.currentContext(), ctx); QCOMPARE(ctx->engine(), &eng); QCOMPARE(ctx->state(), QScriptContext::NormalState); QCOMPARE(ctx->isCalledAsConstructor(), false); QCOMPARE(ctx->argumentCount(), 0); QCOMPARE(ctx->argument(0).isUndefined(), true); QVERIFY(!ctx->argument(-1).isValid()); QCOMPARE(ctx->argumentsObject().isObject(), true); QCOMPARE(ctx->activationObject().isObject(), true); QCOMPARE(ctx->callee().isValid(), false); QCOMPARE(ctx->thisObject().strictlyEquals(eng.globalObject()), true); QCOMPARE(ctx->scopeChain().size(), 2); QVERIFY(ctx->scopeChain().at(0).equals(ctx->activationObject())); QVERIFY(ctx->scopeChain().at(1).equals(eng.globalObject())); QScriptContext *ctx2 = eng.pushContext(); QCOMPARE(ctx2->parentContext(), ctx); QCOMPARE(eng.currentContext(), ctx2); eng.popContext(); QCOMPARE(eng.currentContext(), ctx); eng.popContext(); QCOMPARE(eng.currentContext(), topLevel); // popping the top-level context is not allowed QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::popContext() doesn't match with pushContext()"); eng.popContext(); QCOMPARE(eng.currentContext(), topLevel); { QScriptContext *ctx3 = eng.pushContext(); ctx3->activationObject().setProperty("foo", QScriptValue(&eng, 123)); QVERIFY(eng.evaluate("foo").strictlyEquals(QScriptValue(&eng, 123))); eng.evaluate("var bar = 'ciao'"); QVERIFY(ctx3->activationObject().property("bar", QScriptValue::ResolveLocal).strictlyEquals(QScriptValue(&eng, "ciao"))); eng.popContext(); } { QScriptContext *ctx4 = eng.pushContext(); QScriptValue obj = eng.newObject(); obj.setProperty("prop", QScriptValue(&eng, 456)); ctx4->setThisObject(obj); QScriptValue ret = eng.evaluate("var tmp = this.prop; tmp + 1"); QCOMPARE(eng.currentContext(), ctx4); QVERIFY(ret.strictlyEquals(QScriptValue(&eng, 457))); eng.popContext(); } // throwing an exception { QScriptContext *ctx5 = eng.pushContext(); QScriptValue ret = eng.evaluate("throw new Error('oops')"); QVERIFY(ret.isError()); QVERIFY(eng.hasUncaughtException()); QCOMPARE(eng.currentContext(), ctx5); eng.popContext(); } }