QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, bool *isUndefined) { if (!expressionFunctionValid) { QDeclarativeEngine *engine = context()->engine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); expressionContext = ep->contextClass->newContext(context(), scopeObject); scriptContext->pushScope(expressionContext); scriptContext->pushScope(ep->globalClass->staticGlobalObject()); QDeclarativeRewrite::RewriteBinding rewriteBinding; rewriteBinding.setName(name); bool ok = true; const QString code = rewriteBinding(expression, &ok); if (ok) expressionFunction = scriptEngine->evaluate(code, url, line); scriptEngine->popContext(); expressionFunctionMode = ExplicitContext; expressionFunctionValid = true; } return QDeclarativeQtScriptExpression::scriptValue(secondaryScope, isUndefined); }
bool ConditionalTransition::eventTest(QEvent* e) { if (e->type() != NamedEvent::type) { return false; } NamedEvent* namedEvent = static_cast<NamedEvent*>(e); if (namedEvent->getEventName() != eventName) { return false; } if (!condition.isEmpty()) { QScriptEngine* scriptEngine = stateMachine->getScriptEngine(); QScriptContext* context = scriptEngine->pushContext(); context->activationObject().setProperty("input", ValueScriptBinding::create(scriptEngine, &sourceState->getInput())); // TODO performance? context->activationObject().setProperty("output", ValueScriptBinding::create(scriptEngine, &sourceState->getOutput())); // TODO performance? bool result = scriptEngine->evaluate(condition).toBool(); scriptEngine->popContext(); return result; } return true; }
void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *expr, QDeclarativeRefCount *rc, QObject *me, const QString &url, int lineNumber) { data->url = url; data->line = lineNumber; if (data->dataRef) data->dataRef->release(); data->dataRef = rc; if (data->dataRef) data->dataRef->addref(); quint32 *exprData = (quint32 *)expr; QDeclarativeCompiledData *dd = (QDeclarativeCompiledData *)rc; data->expressionRewritten = true; data->expression = QString::fromRawData((QChar *)(exprData + 2), exprData[1]); int progIdx = *(exprData); bool isShared = progIdx & 0x80000000; progIdx &= 0x7FFFFFFF; QDeclarativeEngine *engine = ctxt->engine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); if (isShared) { if (!dd->cachedClosures.at(progIdx)) { QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); scriptContext->pushScope(ep->contextClass->newSharedContext()); scriptContext->pushScope(ep->globalClass->globalObject()); dd->cachedClosures[progIdx] = new QScriptValue(scriptEngine->evaluate(data->expression, data->url, data->line)); scriptEngine->popContext(); } data->expressionFunction = *dd->cachedClosures.at(progIdx); data->isShared = true; data->expressionFunctionValid = true; } else { #if !defined(Q_OS_SYMBIAN) //XXX Why doesn't this work? if (!dd->cachedPrograms.at(progIdx)) { dd->cachedPrograms[progIdx] = new QScriptProgram(data->expression, data->url, data->line); } data->expressionFunction = evalInObjectScope(ctxt, me, *dd->cachedPrograms.at(progIdx), &data->expressionContext); #else data->expressionFunction = evalInObjectScope(ctxt, me, data->expression, &data->expressionContext); #endif data->expressionFunctionValid = true; } data->QDeclarativeAbstractExpression::setContext(ctxt); data->me = me; }
void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *expr, QDeclarativeRefCount *rc, QObject *me, const QString &srcUrl, int lineNumber) { url = srcUrl; line = lineNumber; if (dataRef) dataRef->release(); dataRef = rc; if (dataRef) dataRef->addref(); quint32 *exprData = (quint32 *)expr; QDeclarativeCompiledData *dd = (QDeclarativeCompiledData *)rc; expression = QString::fromRawData((QChar *)(exprData + 2), exprData[1]); int progIdx = *(exprData); bool isSharedProgram = progIdx & 0x80000000; progIdx &= 0x7FFFFFFF; QDeclarativeEngine *engine = ctxt->engine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); if (isSharedProgram) { if (!dd->cachedClosures.at(progIdx)) { QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); scriptContext->pushScope(ep->contextClass->newSharedContext()); scriptContext->pushScope(ep->globalClass->staticGlobalObject()); dd->cachedClosures[progIdx] = new QScriptValue(scriptEngine->evaluate(expression, url, line)); scriptEngine->popContext(); } expressionFunction = *dd->cachedClosures.at(progIdx); expressionFunctionMode = SharedContext; expressionFunctionValid = true; } else { if (!dd->cachedPrograms.at(progIdx)) { dd->cachedPrograms[progIdx] = new QScriptProgram(expression, url, line); } expressionFunction = evalInObjectScope(ctxt, me, *dd->cachedPrograms.at(progIdx), &expressionContext); expressionFunctionMode = ExplicitContext; expressionFunctionValid = true; } QDeclarativeAbstractExpression::setContext(ctxt); scopeObject = me; }
void Cluster::setup () { QScriptEngine* engine = scene->scriptEngine(); QScriptContext* ctx = engine->pushContext(); QScriptValue ao = ctx->activationObject(); prepGlobalObject(ao); ao.setProperty("emit", engine->newFunction(emitFun)); /// @todo is this the best way to get access to the cluster? QVariant var = qVariantFromValue(this); ao.setProperty("self", engine->newVariant(var)); engine->evaluate(d->shellProgram); engine->popContext(); }
void tst_QScriptContext::popNativeContextScope() { QScriptEngine eng; QScriptContext *ctx = eng.pushContext(); QVERIFY(ctx->popScope().isObject()); // the activation object QCOMPARE(ctx->scopeChain().size(), 1); QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject())); // This was different in 4.5: scope and activation were decoupled QVERIFY(ctx->activationObject().strictlyEquals(eng.globalObject())); QVERIFY(!eng.evaluate("var foo = 123; function bar() {}").isError()); QVERIFY(eng.globalObject().property("foo").isNumber()); QVERIFY(eng.globalObject().property("bar").isFunction()); QScriptValue customScope = eng.newObject(); ctx->pushScope(customScope); QCOMPARE(ctx->scopeChain().size(), 2); QVERIFY(ctx->scopeChain().at(0).strictlyEquals(customScope)); QVERIFY(ctx->scopeChain().at(1).strictlyEquals(eng.globalObject())); QVERIFY(ctx->activationObject().strictlyEquals(eng.globalObject())); ctx->setActivationObject(customScope); QVERIFY(ctx->activationObject().strictlyEquals(customScope)); QCOMPARE(ctx->scopeChain().size(), 2); QVERIFY(ctx->scopeChain().at(0).strictlyEquals(customScope)); QEXPECT_FAIL("", "QTBUG-11012", Continue); QVERIFY(ctx->scopeChain().at(1).strictlyEquals(eng.globalObject())); QVERIFY(!eng.evaluate("baz = 456; var foo = 789; function barbar() {}").isError()); QEXPECT_FAIL("", "QTBUG-11012", Continue); QVERIFY(eng.globalObject().property("baz").isNumber()); QVERIFY(customScope.property("foo").isNumber()); QVERIFY(customScope.property("barbar").isFunction()); QVERIFY(ctx->popScope().strictlyEquals(customScope)); QCOMPARE(ctx->scopeChain().size(), 1); QEXPECT_FAIL("", "QTBUG-11012", Continue); QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject())); // Need to push another object, otherwise we crash in popContext() (QTBUG-11012) ctx->pushScope(customScope); eng.popContext(); }
bool HttpHandlerQtScriptFile::handleRequest(Pillow::HttpConnection *request) { if (!_lastModified.isValid() || (_autoReload && QFileInfo(_fileName).lastModified() > _lastModified)) { // Time to (re)load the script. qDebug() << "HttpHandlerQtScriptFile::handleRequest: (re)loading" << _fileName; QFile file(_fileName); if (!file.open(QIODevice::ReadOnly)) { request->writeResponseString(500, HttpHeaderCollection(), QString("HttpHandlerQtScriptFile::handleRequest: Could not read file %1").arg(_fileName)); return true; } QScriptEngine* engine = _scriptObject.engine(); _scriptObject = engine->newObject(); QScriptContext* context = engine->pushContext(); context->setActivationObject(_scriptObject); context->setThisObject(_scriptObject); QScriptValue result = engine->evaluate(file.readAll(), _fileName); engine->popContext(); if (result.isError()) { request->writeResponseString(500, HttpHeaderCollection(), QString("HttpHandlerQtScriptFile::handleRequest: Error while evaluating script %1: %2").arg(_fileName).arg(objectToString(result))); return true; } QScriptValue scriptFunction = _scriptObject.property(_functionName); if (!scriptFunction.isFunction()) { request->writeResponseString(500, HttpHeaderCollection(), QString("HttpHandlerQtScriptFile::handleRequest: Error while evaluating script %1: '%2' is not a function defined in the script").arg(_fileName).arg(_functionName)); return true; } _lastModified = QFileInfo(_fileName).lastModified(); setScriptFunction(scriptFunction); } return HttpHandlerQtScript::handleRequest(request); }
QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUndefined) { QDeclarativeExpressionData *data = this->data; QDeclarativeEngine *engine = data->context()->engine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); if (!data->expressionFunctionValid) { QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); data->expressionContext = ep->contextClass->newContext(data->context(), data->me); scriptContext->pushScope(data->expressionContext); scriptContext->pushScope(ep->globalClass->globalObject()); if (data->expressionRewritten) { data->expressionFunction = scriptEngine->evaluate(data->expression, data->url, data->line); } else { QDeclarativeRewrite::RewriteBinding rewriteBinding; bool ok = true; const QString code = rewriteBinding(data->expression, &ok); if (!ok) { scriptEngine->popContext(); return QVariant(); } data->expressionFunction = scriptEngine->evaluate(code, data->url, data->line); } scriptEngine->popContext(); data->expressionFunctionValid = true; } QDeclarativeContextData *oldSharedContext = 0; QObject *oldSharedScope = 0; QObject *oldOverride = 0; if (data->isShared) { oldSharedContext = ep->sharedContext; oldSharedScope = ep->sharedScope; ep->sharedContext = data->context(); ep->sharedScope = data->me; } else { oldOverride = ep->contextClass->setOverrideObject(data->expressionContext, secondaryScope); } QScriptValue svalue = data->expressionFunction.call(); if (data->isShared) { ep->sharedContext = oldSharedContext; ep->sharedScope = oldSharedScope; } else { ep->contextClass->setOverrideObject(data->expressionContext, oldOverride); } if (isUndefined) *isUndefined = svalue.isUndefined() || scriptEngine->hasUncaughtException(); // Handle exception if (scriptEngine->hasUncaughtException()) { exceptionToError(scriptEngine, data->error); scriptEngine->clearExceptions(); return QVariant(); } else { data->error = QDeclarativeError(); } QVariant rv; if (svalue.isArray()) { int length = svalue.property(QLatin1String("length")).toInt32(); if (length && svalue.property(0).isObject()) { QList<QObject *> list; for (int ii = 0; ii < length; ++ii) { QScriptValue arrayItem = svalue.property(ii); QObject *d = arrayItem.toQObject(); list << d; } rv = QVariant::fromValue(list); } } else if (svalue.isObject() && ep->objectClass->scriptClass(svalue) == ep->objectClass) { QObject *o = svalue.toQObject(); int type = QMetaType::QObjectStar; // If the object is null, we extract the predicted type. While this isn't // 100% reliable, in many cases it gives us better error messages if we // assign this null-object to an incompatible property if (!o) type = ep->objectClass->objectType(svalue); return QVariant(type, &o); } if (rv.isNull()) rv = svalue.toVariant(); return rv; }
void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script) { if (!engine) return; QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); const QString &code = script.code; const QString &url = script.file; const QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = script.pragmas; Q_ASSERT(!url.isEmpty()); if (pragmas & QDeclarativeParser::Object::ScriptBlock::Shared) { QHash<QString, QScriptValue>::Iterator iter = enginePriv->m_sharedScriptImports.find(url); if (iter == enginePriv->m_sharedScriptImports.end()) { QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); scriptContext->pushScope(enginePriv->contextClass->newUrlContext(url)); scriptContext->pushScope(enginePriv->globalClass->staticGlobalObject()); QScriptValue scope = QScriptDeclarativeClass::newStaticScopeObject(scriptEngine); scriptContext->pushScope(scope); scriptEngine->evaluate(code, url, 1); if (scriptEngine->hasUncaughtException()) { QDeclarativeError error; QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); enginePriv->warning(error); } scriptEngine->popContext(); iter = enginePriv->m_sharedScriptImports.insert(url, scope); } importedScripts.append(*iter); } else { QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); scriptContext->pushScope(enginePriv->contextClass->newUrlContext(this, 0, url)); scriptContext->pushScope(enginePriv->globalClass->staticGlobalObject()); QScriptValue scope = QScriptDeclarativeClass::newStaticScopeObject(scriptEngine); scriptContext->pushScope(scope); scriptEngine->evaluate(code, url, 1); if (scriptEngine->hasUncaughtException()) { QDeclarativeError error; QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); enginePriv->warning(error); } scriptEngine->popContext(); importedScripts.append(scope); } }
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(); } }