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);
}
Exemple #2
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;
}
QScriptValue QDeclarativeInclude::worker_include(QScriptContext *ctxt, QScriptEngine *engine)
{
    if (ctxt->argumentCount() == 0)
        return engine->undefinedValue();

    QString urlString = ctxt->argument(0).toString();
    QUrl url(ctxt->argument(0).toString());
    if (url.isRelative()) {
        QString contextUrl = QScriptDeclarativeClass::scopeChainValue(ctxt, -3).data().toString();
        Q_ASSERT(!contextUrl.isEmpty());

        url = QUrl(contextUrl).resolved(url);
        urlString = url.toString();
    }

    QString localFile = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);

    QScriptValue func = ctxt->argument(1);
    if (!func.isFunction())
        func = QScriptValue();

    QScriptValue result;
    if (!localFile.isEmpty()) {

        QFile f(localFile);
        if (f.open(QIODevice::ReadOnly)) {
            QByteArray data = f.readAll();
            QString code = QString::fromUtf8(data);

            QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(engine);
            QScriptValue urlContext = engine->newObject();
            urlContext.setData(QScriptValue(engine, urlString));
            scriptContext->pushScope(urlContext);

            QScriptValue scope = QScriptDeclarativeClass::scopeChainValue(ctxt, -4);
            scriptContext->pushScope(scope);
            scriptContext->setActivationObject(scope);
            QDeclarativeScriptParser::extractPragmas(code);

            engine->evaluate(code, urlString, 1);

            engine->popContext();

            if (engine->hasUncaughtException()) {
                result = resultValue(engine, Exception);
                result.setProperty(QLatin1String("exception"), engine->uncaughtException());
                engine->clearExceptions();
            } else {
                result = resultValue(engine, Ok);
            }
            callback(engine, func, result);
        } else {
            result = resultValue(engine, NetworkError);
            callback(engine, func, result);
        }
    }

    return result;
}
void QDeclarativeInclude::finished()
{
    m_redirectCount++;

    if (m_redirectCount < INCLUDE_MAXIMUM_REDIRECT_RECURSION) {
        QVariant redirect = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
        if (redirect.isValid()) {
            m_url = m_url.resolved(redirect.toUrl());
            delete m_reply; 
            
            QNetworkRequest request;
            request.setUrl(m_url);

            m_reply = m_network->get(request);
            QObject::connect(m_reply, SIGNAL(finished()), this, SLOT(finished()));
            return;
        }
    }

    if (m_reply->error() == QNetworkReply::NoError) {
        QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(m_engine);

        QByteArray data = m_reply->readAll();

        QString code = QString::fromUtf8(data);

        QString urlString = m_url.toString();
        QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(m_scriptEngine);
        scriptContext->pushScope(ep->contextClass->newUrlContext(m_context, 0, urlString));
        scriptContext->pushScope(m_scope[0]);

        scriptContext->pushScope(m_scope[1]);
        scriptContext->setActivationObject(m_scope[1]);
        QDeclarativeScriptParser::extractPragmas(code);

        m_scriptEngine->evaluate(code, urlString, 1);

        m_scriptEngine->popContext();

        if (m_scriptEngine->hasUncaughtException()) {
            m_result.setProperty(QLatin1String("status"), QScriptValue(m_scriptEngine, Exception));
            m_result.setProperty(QLatin1String("exception"), m_scriptEngine->uncaughtException());
            m_scriptEngine->clearExceptions();
        } else {
            m_result.setProperty(QLatin1String("status"), QScriptValue(m_scriptEngine, Ok));
        }
    } else {
        m_result.setProperty(QLatin1String("status"), QScriptValue(m_scriptEngine, NetworkError));
    }

    callback(m_scriptEngine, m_callback, m_result);

    disconnect();
    deleteLater();
}
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;
}
Exemple #6
0
QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object, 
                                                              const QString &program, QScriptValue *contextObject)
{
    QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
    QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine);
    if (contextObject) {
        *contextObject = ep->contextClass->newContext(context, object);
        scriptContext->pushScope(*contextObject);
    } else {
        scriptContext->pushScope(ep->contextClass->newContext(context, object));
    }
    scriptContext->pushScope(ep->globalClass->globalObject());
    QScriptValue rv = ep->scriptEngine.evaluate(program);
    ep->scriptEngine.popContext();
    return rv;
}
Exemple #7
0
    void doStart(const JavaScriptCommand *cmd, Transformer *transformer)
    {
        m_result.success = true;
        m_result.errorMessage.clear();
        ScriptEngine * const scriptEngine = provideScriptEngine();
        QScriptValue scope = scriptEngine->newObject();
        PrepareScriptObserver observer(scriptEngine);
        setupScriptEngineForFile(scriptEngine, transformer->rule->prepareScript->fileContext, scope);
        setupScriptEngineForProduct(scriptEngine, transformer->product(), transformer->rule->module, scope,
                                    &observer);
        transformer->setupInputs(scope);
        transformer->setupOutputs(scriptEngine, scope);

        for (QVariantMap::const_iterator it = cmd->properties().constBegin();
                it != cmd->properties().constEnd(); ++it) {
            scope.setProperty(it.key(), scriptEngine->toScriptValue(it.value()));
        }

        QScriptContext *ctx = scriptEngine->currentContext();
        ctx->pushScope(scope);
        scriptEngine->evaluate(cmd->sourceCode());
        ctx->popScope();
        transformer->propertiesRequestedInCommands
                += scriptEngine->propertiesRequestedInScript();
        scriptEngine->clearRequestedProperties();
        if (scriptEngine->hasUncaughtException()) {
            // ### We don't know the line number of the command's sourceCode property assignment.
            setError(scriptEngine->uncaughtException().toString(), cmd->codeLocation());
        }
    }
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();
}
Exemple #9
0
/*!
  Executes the pending evaluate, if any.
*/
void QScriptDebuggerBackend::doPendingEvaluate(bool postEvent)
{
    Q_D(QScriptDebuggerBackend);
    QString program = d->pendingEvaluateProgram;
    if (program.isEmpty())
        return;
    int contextIndex = d->pendingEvaluateContextIndex;
    QScriptContext *ctx = context(contextIndex);
    Q_ASSERT(ctx != 0);
    QString fileName = d->pendingEvaluateFileName;
    int lineNumber = d->pendingEvaluateLineNumber;
    d->pendingEvaluateProgram = QString();
    d->pendingEvaluateFileName = QString();
    d->pendingEvaluateLineNumber = -1;
    d->pendingEvaluateContextIndex = -1;

    // push a new context and initialize its scope chain etc.
    {
        QScriptContext *evalContext = engine()->pushContext();
        QScriptValueList scopeChain = ctx->scopeChain();
        if (scopeChain.isEmpty())
            scopeChain.append(engine()->globalObject());
        while (!scopeChain.isEmpty())
            evalContext->pushScope(scopeChain.takeLast());
        evalContext->setActivationObject(ctx->activationObject());
        evalContext->setThisObject(ctx->thisObject());
    }

    d->agent->enterContinueMode();
    // set a flag so that any exception that happens in
    // the evaluate() is not sent to the debugger
    d->ignoreExceptions = true;
    bool hadException = engine()->hasUncaughtException();
    QScriptValue ret = engine()->evaluate(program, fileName, lineNumber);
    d->ignoreExceptions = false;
    if (!hadException && engine()->hasUncaughtException())
        engine()->clearExceptions();
    engine()->popContext();

    QScriptDebuggerValue retret(ret);
    QScriptDebuggerEvent e(QScriptDebuggerEvent::InlineEvalFinished);
    e.setScriptValue(retret);
    if (!ret.isUndefined())
        e.setMessage(ret.toString()); // for convenience -- we always need it

    e.setNestedEvaluate(engine()->isEvaluating());

    if (postEvent) {
        QScriptDebuggerEventEvent *de = new QScriptDebuggerEventEvent(e);
        d->postEvent(de);
    } else {
        event(e);
    }
}
Exemple #10
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;
}
Exemple #11
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::pushAndPopScope()
{
    QScriptEngine eng;
    QScriptContext *ctx = eng.currentContext();
    QCOMPARE(ctx->scopeChain().size(), 1);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject()));

    QVERIFY(ctx->popScope().strictlyEquals(eng.globalObject()));
    ctx->pushScope(eng.globalObject());
    QCOMPARE(ctx->scopeChain().size(), 1);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject()));

    QScriptValue obj = eng.newObject();
    ctx->pushScope(obj);
    QCOMPARE(ctx->scopeChain().size(), 2);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(obj));
    QVERIFY(ctx->scopeChain().at(1).strictlyEquals(eng.globalObject()));

    QVERIFY(ctx->popScope().strictlyEquals(obj));
    QCOMPARE(ctx->scopeChain().size(), 1);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject()));

    {
        QScriptValue ret = eng.evaluate("x");
        QVERIFY(ret.isError());
        eng.clearExceptions();
    }
    QCOMPARE(ctx->scopeChain().size(), 1);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject()));

    // task 236685
    QScriptValue qobj = eng.newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::AutoCreateDynamicProperties);
    ctx->pushScope(qobj);
    QCOMPARE(ctx->scopeChain().size(), 2);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(qobj));
    QVERIFY(ctx->scopeChain().at(1).strictlyEquals(eng.globalObject()));
    {
        QScriptValue ret = eng.evaluate("print");
        QVERIFY(ret.isFunction());
    }
    ctx->popScope();

    ctx->pushScope(obj);
    QCOMPARE(ctx->scopeChain().size(), 2);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(obj));
    obj.setProperty("x", 123);
    {
        QScriptValue ret = eng.evaluate("x");
        QVERIFY(ret.isNumber());
        QCOMPARE(ret.toInt32(), 123);
    }
    QVERIFY(ctx->popScope().strictlyEquals(obj));
    QCOMPARE(ctx->scopeChain().size(), 1);
    QVERIFY(ctx->scopeChain().at(0).strictlyEquals(eng.globalObject()));

    ctx->pushScope(QScriptValue());
    QCOMPARE(ctx->scopeChain().size(), 1);

    QVERIFY(ctx->popScope().strictlyEquals(eng.globalObject()));
    QVERIFY(ctx->scopeChain().isEmpty());

    // Used to work with old back-end, doesn't with new one because JSC requires that the last object in
    // a scope chain is the Global Object.
    QTest::ignoreMessage(QtWarningMsg, "QScriptContext::pushScope() failed: initial object in scope chain has to be the Global Object");
    ctx->pushScope(obj);
    QCOMPARE(ctx->scopeChain().size(), 0);

    QScriptEngine eng2;
    QScriptValue obj2 = eng2.newObject();
    QTest::ignoreMessage(QtWarningMsg, "QScriptContext::pushScope() failed: cannot push an object created in a different engine");
    ctx->pushScope(obj2);
    QVERIFY(ctx->scopeChain().isEmpty());

    QVERIFY(!ctx->popScope().isValid());
}
/*
    Documented in qdeclarativeengine.cpp
*/
QScriptValue QDeclarativeInclude::include(QScriptContext *ctxt, QScriptEngine *engine)
{
    if (ctxt->argumentCount() == 0)
        return engine->undefinedValue();

    QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);

    QUrl contextUrl = ep->contextClass->urlFromValue(QScriptDeclarativeClass::scopeChainValue(ctxt, -3));
    if (contextUrl.isEmpty()) 
        return ctxt->throwError(QLatin1String("Qt.include(): Can only be called from JavaScript files"));

    QString urlString = ctxt->argument(0).toString();
    QUrl url(urlString);
    if (url.isRelative()) {
        url = QUrl(contextUrl).resolved(url);
        urlString = url.toString();
    }

    QString localFile = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);

    QScriptValue func = ctxt->argument(1);
    if (!func.isFunction())
        func = QScriptValue();

    QScriptValue result;
    if (localFile.isEmpty()) {
        QDeclarativeInclude *i = 
            new QDeclarativeInclude(url, QDeclarativeEnginePrivate::getEngine(engine), ctxt);

        if (func.isValid())
            i->setCallback(func);

        result = i->result();
    } else {

        QFile f(localFile);
        if (f.open(QIODevice::ReadOnly)) {
            QByteArray data = f.readAll();
            QString code = QString::fromUtf8(data);

            QDeclarativeContextData *context = 
                ep->contextClass->contextFromValue(QScriptDeclarativeClass::scopeChainValue(ctxt, -3));

            QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(engine);
            scriptContext->pushScope(ep->contextClass->newUrlContext(context, 0, urlString));
            scriptContext->pushScope(ep->globalClass->staticGlobalObject());
            QScriptValue scope = QScriptDeclarativeClass::scopeChainValue(ctxt, -5);
            scriptContext->pushScope(scope);
            scriptContext->setActivationObject(scope);
            QDeclarativeScriptParser::extractPragmas(code);

            engine->evaluate(code, urlString, 1);

            engine->popContext();

            if (engine->hasUncaughtException()) {
                result = resultValue(engine, Exception);
                result.setProperty(QLatin1String("exception"), engine->uncaughtException());
                engine->clearExceptions();
            } else {
                result = resultValue(engine, Ok);
            }
            callback(engine, func, result);
        } else {
            result = resultValue(engine, NetworkError);
            callback(engine, func, result);
        }
    }

    return result;
}