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);
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #5
0
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();
}
Пример #7
0
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);
}
Пример #8
0
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;
}
Пример #9
0
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();
    }
}