/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/


#include <QtTest/QtTest>

#include <QtScript/qscriptcontext.h>
#include <QtScript/qscriptengine.h>
#include <QtScript/qscriptvalueiterator.h>

Q_DECLARE_METATYPE(QScriptValueList)
Q_DECLARE_METATYPE(QScriptContext::Error)

QT_BEGIN_NAMESPACE
extern bool qt_script_isJITEnabled();
QT_END_NAMESPACE

class tst_QScriptContext : public QObject
{
    Q_OBJECT

public:
    tst_QScriptContext();
    virtual ~tst_QScriptContext();

private slots:
    void callee();
    void callee_implicitCall();
    void arguments();
    void argumentsInJS();
    void thisObject();
    void returnValue();
    void throwError_data();
    void throwError_fromEvaluate_data();
    void throwError_fromEvaluate();
    void throwError_fromCpp_data();
    void throwError_fromCpp();
    void throwValue();
    void evaluateInFunction();
    void pushAndPopContext();
    void pushAndPopContext_variablesInActivation();
    void pushAndPopContext_setThisObject();
    void pushAndPopContext_throwException();
    void lineNumber();
    void backtrace_data();
    void backtrace();
    void scopeChain_globalContext();
    void scopeChain_closure();
    void scopeChain_withStatement();
    void pushAndPopScope_globalContext();
    void pushAndPopScope_globalContext2();
    void getSetActivationObject_globalContext();
    void pushScopeEvaluate();
    void pushScopeCall();
    void popScopeSimple();
    void pushAndPopGlobalObjectSimple();
    void pushAndPopIterative();
    void getSetActivationObject_customContext();
    void inheritActivationAndThisObject();
    void toString();
    void calledAsConstructor_fromCpp();
    void calledAsConstructor_fromJS();
    void calledAsConstructor_parentContext();
    void argumentsObjectInNative();
    void jsActivationObject();
    void qobjectAsActivationObject();
    void parentContextCallee_QT2270();
    void popNativeContextScope();
    void throwErrorInGlobalContext();
    void throwErrorWithTypeInGlobalContext_data();
    void throwErrorWithTypeInGlobalContext();
    void throwValueInGlobalContext();
};

tst_QScriptContext::tst_QScriptContext()
{
}

tst_QScriptContext::~tst_QScriptContext()
{
}

static QScriptValue get_callee(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->callee();
}

static QScriptValue store_callee_and_return_primitive(QScriptContext *ctx, QScriptEngine *eng)
{
    ctx->thisObject().setProperty("callee", ctx->callee());
    return QScriptValue(eng, 123);
}

void tst_QScriptContext::callee()
{
    QScriptEngine eng;

    QScriptValue fun = eng.newFunction(get_callee);
    fun.setProperty("foo", QScriptValue(&eng, "bar"));
    eng.globalObject().setProperty("get_callee", fun);

    QScriptValue result = eng.evaluate("get_callee()");
    QCOMPARE(result.isFunction(), true);
    QCOMPARE(result.property("foo").toString(), QString("bar"));
}

void tst_QScriptContext::callee_implicitCall()
{
    QScriptEngine eng;
    // callee when toPrimitive() is called internally
    QScriptValue fun = eng.newFunction(store_callee_and_return_primitive);
    QScriptValue obj = eng.newObject();
    obj.setProperty("toString", fun);
    QVERIFY(!obj.property("callee").isValid());
    (void)obj.toString();
    QVERIFY(obj.property("callee").isFunction());
    QVERIFY(obj.property("callee").strictlyEquals(fun));

    obj.setProperty("callee", QScriptValue());
    QVERIFY(!obj.property("callee").isValid());
    obj.setProperty("valueOf", fun);
    (void)obj.toNumber();
    QVERIFY(obj.property("callee").isFunction());
    QVERIFY(obj.property("callee").strictlyEquals(fun));
}

static QScriptValue get_arguments(QScriptContext *ctx, QScriptEngine *eng)
{
    QScriptValue array = eng->newArray();
    for (int i = 0; i < ctx->argumentCount(); ++i)
        array.setProperty(QString::number(i), ctx->argument(i));
    return array;
}

static QScriptValue get_argumentsObject(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->argumentsObject();
}

void tst_QScriptContext::arguments()
{
    QScriptEngine eng;

    // See section 10.6 ("Arguments Object") of ECMA-262.

    {
        QScriptValue args = eng.currentContext()->argumentsObject();
        QVERIFY(args.isObject());
        QCOMPARE(args.property("length").toInt32(), 0);
    }
    {
        QScriptValue fun = eng.newFunction(get_arguments);
        eng.globalObject().setProperty("get_arguments", fun);
    }

    for (int x = 0; x < 2; ++x) {
        // The expected arguments array should be the same regardless of
        // whether get_arguments() is called as a constructor.
        QString prefix;
        if (x == 0)
            prefix = "";
        else
            prefix = "new ";
        {
            QScriptValue result = eng.evaluate(prefix+"get_arguments()");
            QCOMPARE(result.isArray(), true);
            QCOMPARE(result.property("length").toUInt32(), quint32(0));
        }

        {
            QScriptValue result = eng.evaluate(prefix+"get_arguments(123)");
            QCOMPARE(result.isArray(), true);
            QCOMPARE(result.property("length").toUInt32(), quint32(1));
            QCOMPARE(result.property("0").isNumber(), true);
            QCOMPARE(result.property("0").toNumber(), 123.0);
        }

        {
            QScriptValue result = eng.evaluate(prefix+"get_arguments(\"ciao\", null, true, undefined)");
            QCOMPARE(result.isArray(), true);
            QCOMPARE(result.property("length").toUInt32(), quint32(4));
            QCOMPARE(result.property("0").isString(), true);
            QCOMPARE(result.property("0").toString(), QString("ciao"));
            QCOMPARE(result.property("1").isNull(), true);
            QCOMPARE(result.property("2").isBoolean(), true);
            QCOMPARE(result.property("2").toBoolean(), true);
            QCOMPARE(result.property("3").isUndefined(), true);
        }

        {
            QScriptValue fun = eng.newFunction(get_argumentsObject);
            eng.globalObject().setProperty("get_argumentsObject", fun);
        }

        {
            QScriptValue fun = eng.evaluate("get_argumentsObject");
            QCOMPARE(fun.isFunction(), true);
            QScriptValue result = eng.evaluate(prefix+"get_argumentsObject()");
            QCOMPARE(result.isArray(), false);
            QVERIFY(result.isObject());
            QCOMPARE(result.property("length").toUInt32(), quint32(0));
            QCOMPARE(result.propertyFlags("length"), QScriptValue::SkipInEnumeration);
            QCOMPARE(result.property("callee").strictlyEquals(fun), true);
            QCOMPARE(result.propertyFlags("callee"), QScriptValue::SkipInEnumeration);

            // callee and length properties should be writable.
            QScriptValue replacedCallee(&eng, 123);
            result.setProperty("callee", replacedCallee);
            QVERIFY(result.property("callee").equals(replacedCallee));
            QScriptValue replacedLength(&eng, 456);
            result.setProperty("length", replacedLength);

            // callee and length properties should be deletable.
            QVERIFY(result.property("length").equals(replacedLength));
            result.setProperty("callee", QScriptValue());
            QVERIFY(!result.property("callee").isValid());
            result.setProperty("length", QScriptValue());
            QVERIFY(!result.property("length").isValid());
        }

        {
            QScriptValue result = eng.evaluate(prefix+"get_argumentsObject(123)");
            eng.evaluate("function nestedArg(x,y,z) { var w = get_argumentsObject('ABC' , x+y+z); return w; }");
            QScriptValue result2 = eng.evaluate("nestedArg(1, 'a', 2)");
            QCOMPARE(result.isArray(), false);
            QVERIFY(result.isObject());
            QCOMPARE(result.property("length").toUInt32(), quint32(1));
            QCOMPARE(result.property("0").isNumber(), true);
            QCOMPARE(result.property("0").toNumber(), 123.0);
            QVERIFY(result2.isObject());
            QCOMPARE(result2.property("length").toUInt32(), quint32(2));
            QCOMPARE(result2.property("0").toString(), QString::fromLatin1("ABC"));
            QCOMPARE(result2.property("1").toString(), QString::fromLatin1("1a2"));
        }

        {
            QScriptValue result = eng.evaluate(prefix+"get_argumentsObject(\"ciao\", null, true, undefined)");
            QCOMPARE(result.isArray(), false);
            QCOMPARE(result.property("length").toUInt32(), quint32(4));
            QCOMPARE(result.property("0").isString(), true);
            QCOMPARE(result.property("0").toString(), QString("ciao"));
            QCOMPARE(result.property("1").isNull(), true);
            QCOMPARE(result.property("2").isBoolean(), true);
            QCOMPARE(result.property("2").toBoolean(), true);
            QCOMPARE(result.property("3").isUndefined(), true);
        }
    }
}

void tst_QScriptContext::argumentsInJS()
{
    QScriptEngine eng;
    {
        QScriptValue result = eng.evaluate("(function() { return arguments; })(123)");
        QCOMPARE(result.isArray(), false);
        QVERIFY(result.isObject());
        QCOMPARE(result.property("length").toUInt32(), quint32(1));
        QCOMPARE(result.property("0").isNumber(), true);
        QCOMPARE(result.property("0").toNumber(), 123.0);
    }

    {
        QScriptValue result = eng.evaluate("(function() { return arguments; })('ciao', null, true, undefined)");
        QCOMPARE(result.isArray(), false);
        QCOMPARE(result.property("length").toUInt32(), quint32(4));
        QCOMPARE(result.property("0").isString(), true);
        QCOMPARE(result.property("0").toString(), QString("ciao"));
        QCOMPARE(result.property("1").isNull(), true);
        QCOMPARE(result.property("2").isBoolean(), true);
        QCOMPARE(result.property("2").toBoolean(), true);
        QCOMPARE(result.property("3").isUndefined(), true);
    }
}

static QScriptValue get_thisObject(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->thisObject();
}

void tst_QScriptContext::thisObject()
{
    QScriptEngine eng;

    QScriptValue fun = eng.newFunction(get_thisObject);
    eng.globalObject().setProperty("get_thisObject", fun);

    {
        QScriptValue result = eng.evaluate("get_thisObject()");
        QCOMPARE(result.isObject(), true);
        QCOMPARE(result.toString(), QString("[object global]"));
    }

    {
        QScriptValue result = eng.evaluate("get_thisObject.apply(new Number(123))");
        QCOMPARE(result.isObject(), true);
        QCOMPARE(result.toNumber(), 123.0);
    }

    {
        QScriptValue obj = eng.newObject();
        eng.currentContext()->setThisObject(obj);
        QVERIFY(eng.currentContext()->thisObject().equals(obj));
        eng.currentContext()->setThisObject(QScriptValue());
        QVERIFY(eng.currentContext()->thisObject().equals(obj));

        QScriptEngine eng2;
        QScriptValue obj2 = eng2.newObject();
        QTest::ignoreMessage(QtWarningMsg, "QScriptContext::setThisObject() failed: cannot set an object created in a different engine");
        eng.currentContext()->setThisObject(obj2);
    }
}

void tst_QScriptContext::returnValue()
{
    QSKIP("Internal function not implemented in JSC-based back-end");
    QScriptEngine eng;
    eng.evaluate("123");
    QCOMPARE(eng.currentContext()->returnValue().toNumber(), 123.0);
    eng.evaluate("\"ciao\"");
    QCOMPARE(eng.currentContext()->returnValue().toString(), QString("ciao"));
}

static QScriptValue throw_Error(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->throwError(QScriptContext::UnknownError, "foo");
}

static QScriptValue throw_TypeError(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->throwError(QScriptContext::TypeError, "foo");
}

static QScriptValue throw_ReferenceError(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->throwError(QScriptContext::ReferenceError, "foo");
}

static QScriptValue throw_SyntaxError(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->throwError(QScriptContext::SyntaxError, "foo");
}

static QScriptValue throw_RangeError(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->throwError(QScriptContext::RangeError, "foo");
}

static QScriptValue throw_URIError(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->throwError(QScriptContext::URIError, "foo");
}

static QScriptValue throw_ErrorAndReturnUndefined(QScriptContext *ctx, QScriptEngine *eng)
{
    ctx->throwError(QScriptContext::UnknownError, "foo");
    return eng->undefinedValue();
}

static QScriptValue throw_ErrorAndReturnString(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->throwError(QScriptContext::UnknownError, "foo").toString();
}

static QScriptValue throw_ErrorAndReturnObject(QScriptContext *ctx, QScriptEngine *eng)
{
    ctx->throwError(QScriptContext::UnknownError, "foo");
    return eng->newObject();
}

void tst_QScriptContext::throwError_data()
{
    QTest::addColumn<void*>("nativeFunctionPtr");
    QTest::addColumn<QString>("stringRepresentation");

    QTest::newRow("Error") << reinterpret_cast<void*>(throw_Error) << QString("Error: foo");
    QTest::newRow("TypeError") << reinterpret_cast<void*>(throw_TypeError) << QString("TypeError: foo");
    QTest::newRow("ReferenceError") << reinterpret_cast<void*>(throw_ReferenceError) << QString("ReferenceError: foo");
    QTest::newRow("SyntaxError") << reinterpret_cast<void*>(throw_SyntaxError) << QString("SyntaxError: foo");
    QTest::newRow("RangeError") << reinterpret_cast<void*>(throw_RangeError) << QString("RangeError: foo");
    QTest::newRow("URIError") << reinterpret_cast<void*>(throw_URIError) << QString("URIError: foo");
    QTest::newRow("ErrorAndReturnUndefined") << reinterpret_cast<void*>(throw_ErrorAndReturnUndefined) << QString("Error: foo");
    QTest::newRow("ErrorAndReturnString") << reinterpret_cast<void*>(throw_ErrorAndReturnString) << QString("Error: foo");
    QTest::newRow("ErrorAndReturnObject") << reinterpret_cast<void*>(throw_ErrorAndReturnObject) << QString("Error: foo");
}

void tst_QScriptContext::throwError_fromEvaluate_data()
{
    throwError_data();
}

void tst_QScriptContext::throwError_fromEvaluate()
{
    QFETCH(void*, nativeFunctionPtr);
    QScriptEngine::FunctionSignature nativeFunction = reinterpret_cast<QScriptEngine::FunctionSignature>(nativeFunctionPtr);
    QFETCH(QString, stringRepresentation);
    QScriptEngine engine;

    QScriptValue fun = engine.newFunction(nativeFunction);
    engine.globalObject().setProperty("throw_Error", fun);
    QScriptValue result = engine.evaluate("throw_Error()");
    QCOMPARE(engine.hasUncaughtException(), true);
    QCOMPARE(result.isError(), true);
    QCOMPARE(result.toString(), stringRepresentation);
}

void tst_QScriptContext::throwError_fromCpp_data()
{
    throwError_data();
}

void tst_QScriptContext::throwError_fromCpp()
{
    QFETCH(void*, nativeFunctionPtr);
    QScriptEngine::FunctionSignature nativeFunction = reinterpret_cast<QScriptEngine::FunctionSignature>(nativeFunctionPtr);
    QFETCH(QString, stringRepresentation);
    QScriptEngine engine;

    QScriptValue fun = engine.newFunction(nativeFunction);
    engine.globalObject().setProperty("throw_Error", fun);
    QScriptValue result = fun.call();
    QCOMPARE(engine.hasUncaughtException(), true);
    QCOMPARE(result.isError(), true);
    QCOMPARE(result.toString(), stringRepresentation);
}

static QScriptValue throw_value(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->throwValue(ctx->argument(0));
}

void tst_QScriptContext::throwValue()
{
    QScriptEngine eng;

    QScriptValue fun = eng.newFunction(throw_value);
    eng.globalObject().setProperty("throw_value", fun);

    {
        QScriptValue result = eng.evaluate("throw_value(123)");
        QCOMPARE(result.isError(), false);
        QCOMPARE(result.toNumber(), 123.0);
        QCOMPARE(eng.hasUncaughtException(), true);
    }
}

static QScriptValue evaluate(QScriptContext *, QScriptEngine *eng)
{
    return eng->evaluate("a = 123; a");
//    return eng->evaluate("a");
}

void tst_QScriptContext::evaluateInFunction()
{
    QScriptEngine eng;

    QScriptValue fun = eng.newFunction(evaluate);
    eng.globalObject().setProperty("evaluate", fun);

    QScriptValue result = eng.evaluate("evaluate()");
    QCOMPARE(result.isError(), false);
    QCOMPARE(result.isNumber(), true);
    QCOMPARE(result.toNumber(), 123.0);
    QCOMPARE(eng.hasUncaughtException(), false);

    QCOMPARE(eng.evaluate("a").toNumber(), 123.0);
}

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);
}

void tst_QScriptContext::pushAndPopContext_variablesInActivation()
{
    QScriptEngine eng;
    QScriptContext *ctx = eng.pushContext();
    ctx->activationObject().setProperty("foo", QScriptValue(&eng, 123));
    // evaluate() should use the current context.
    QVERIFY(eng.evaluate("foo").strictlyEquals(QScriptValue(&eng, 123)));
    QCOMPARE(ctx->activationObject().propertyFlags("foo"), QScriptValue::PropertyFlags(0));

    ctx->activationObject().setProperty(4, 456);
    QVERIFY(ctx->activationObject().property(4, QScriptValue::ResolveLocal).equals(456));

    // New JS variables should become properties of the current context's activation.
    eng.evaluate("var bar = 'ciao'");
    QVERIFY(ctx->activationObject().property("bar", QScriptValue::ResolveLocal).strictlyEquals(QScriptValue(&eng, "ciao")));

    ctx->activationObject().setProperty("baz", 789, QScriptValue::ReadOnly);
    QVERIFY(eng.evaluate("baz").equals(789));
    QCOMPARE(ctx->activationObject().propertyFlags("baz"), QScriptValue::ReadOnly);

    QSet<QString> activationPropertyNames;
    QScriptValueIterator it(ctx->activationObject());
    while (it.hasNext()) {
        it.next();
        activationPropertyNames.insert(it.name());
    }
    QCOMPARE(activationPropertyNames.size(), 4);
    QVERIFY(activationPropertyNames.contains("foo"));
    QVERIFY(activationPropertyNames.contains("4"));
    QVERIFY(activationPropertyNames.contains("bar"));
    QVERIFY(activationPropertyNames.contains("baz"));

    eng.popContext();
}

void tst_QScriptContext::pushAndPopContext_setThisObject()
{
    QScriptEngine eng;
    QScriptContext *ctx = eng.pushContext();
    QScriptValue obj = eng.newObject();
    obj.setProperty("prop", QScriptValue(&eng, 456));
    ctx->setThisObject(obj);
    QScriptValue ret = eng.evaluate("var tmp = this.prop; tmp + 1");
    QCOMPARE(eng.currentContext(), ctx);
    QVERIFY(ret.strictlyEquals(QScriptValue(&eng, 457)));
    eng.popContext();
}

void tst_QScriptContext::pushAndPopContext_throwException()
{
    QScriptEngine eng;
    QScriptContext *ctx = eng.pushContext();
    QScriptValue ret = eng.evaluate("throw new Error('oops')");
    QVERIFY(ret.isError());
    QVERIFY(eng.hasUncaughtException());
    QCOMPARE(eng.currentContext(), ctx);
    eng.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: Global object is replaced in scope chain", 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();
}

void tst_QScriptContext::lineNumber()
{
    QScriptEngine eng;

    QScriptValue result = eng.evaluate("try { eval(\"foo = 123;\\n this[is{a{syntax|error@#$%@#% \"); } catch (e) { e.lineNumber; }", "foo.qs", 123);
    QVERIFY(!eng.hasUncaughtException());
    QVERIFY(result.isNumber());
    QCOMPARE(result.toInt32(), 2);

    result = eng.evaluate("foo = 123;\n bar = 42\n0 = 0");
    QVERIFY(eng.hasUncaughtException());
    QCOMPARE(eng.uncaughtExceptionLineNumber(), 3);
    QCOMPARE(result.property("lineNumber").toInt32(), 3);
}

static QScriptValue getBacktrace(QScriptContext *ctx, QScriptEngine *eng)
{
    return qScriptValueFromValue(eng, ctx->backtrace());
}

static QScriptValue custom_eval(QScriptContext *ctx, QScriptEngine *eng)
{
    return eng->evaluate(ctx->argumentsObject().property(0).toString(), ctx->argumentsObject().property(1).toString());
}

static QScriptValue custom_call(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->argumentsObject().property(0).call(QScriptValue(), QScriptValueList() << ctx->argumentsObject().property(1));
}

static QScriptValue native_recurse(QScriptContext *ctx, QScriptEngine *eng)
{
    QScriptValue func = ctx->argumentsObject().property(0);
    QScriptValue n = ctx->argumentsObject().property(1);

    if(n.toUInt32() <= 1) {
        return func.call(QScriptValue(), QScriptValueList());
    } else {
        return eng->evaluate("native_recurse").call(QScriptValue(),
                                                    QScriptValueList() << func << QScriptValue(n.toUInt32() - 1));
    }
}

void tst_QScriptContext::backtrace_data()
{
    QTest::addColumn<QString>("code");
    QTest::addColumn<QStringList>("expectedbacktrace");

    {
        QString source(
                 "function foo() {\n"
                 "  return bt(123);\n"
                 "}\n"
                 "foo('hello', { })\n"
                 "var r = 0;");

        QStringList expected;
        expected << "<native>(123) at -1"
                 << "foo('hello', [object Object]) at testfile:2"
                 << "<global>() at testfile:4";


        QTest::newRow("simple") << source << expected;
    }

    {
        QStringList expected;
        QString source = QString(
            "function foo(arg1 , arg2) {\n"
            "  return eval(\"%1\");\n"
            "}\n"
            "foo('hello', 456)\n"
            "var a = 0;"
           ).arg("\\n \\n bt('hey'); \\n");

           expected << "<native>('hey') at -1"
                    << "<eval>() at 3"
                    << "foo(arg1 = 'hello', arg2 = 456) at testfile:2"
                    << "<global>() at testfile:4";

            QTest::newRow("eval") << source << expected;
    }

    {
        QString eval_code(
                "function bar(a) {\\n"
                "  return bt('m');\\n"
                "}\\n"
                "bar('b'); \\n");
        QString source = QString(
                "function foo() {\n"
                "  return custom_eval(\"%1\", 'eval.js');\n"
                "}\n"
                "foo()"
            ).arg(eval_code);

        QStringList expected;
        expected << "<native>('m') at -1"
                 << "bar(a = 'b') at eval.js:2"
                 << "<eval>() at eval.js:4"
                 << QString("<native>('%1', 'eval.js') at -1").arg(eval_code.replace("\\n", "\n"))
                 << "foo() at testfile:2"
                 << "<global>() at testfile:4";

        QTest::newRow("custom_eval") << source << expected;
    }
    {
        QString f("function (a) {\n return bt(a); \n  }");
        QString source = QString(
                "function foo(f) {\n"
                "  return f('b');\n"
                "}\n"
                "foo(%1)"
            ).arg(f);

        QStringList expected;
        expected << "<native>('b') at -1"
                 << "<anonymous>(a = 'b') at testfile:5"
                 << QString("foo(f = %1) at testfile:2").arg(f)
                 << "<global>() at testfile:6";

        QTest::newRow("closure") << source << expected;
    }

    {
        QStringList expected;
        QString source = QString(
            "var o = new Object;\n"
            "o.foo = function plop() {\n"
            "  return eval(\"%1\");\n"
            "}\n"
            "o.foo('hello', 456)\n"
           ).arg("\\n \\n bt('hey'); \\n");

           expected << "<native>('hey') at -1"
                    << "<eval>() at 3"
                    << "plop('hello', 456) at testfile:3"
                    << "<global>() at testfile:5";

            QTest::newRow("eval in member") << source << expected;
    }

    {
        QString source(
                 "function foo(a) {\n"
                 "  return bt(123);\n"
                 "}\n"
                 "function bar() {\n"
                 "  var v = foo('arg', 4);\n"
                 "  return v;\n"
                 "}\n"
                 "bar('hello', { });\n");

        QStringList expected;
        expected << "<native>(123) at -1"
                 << "foo(a = 'arg', 4) at testfile:2"
                 << "bar('hello', [object Object]) at testfile:5"
                 << "<global>() at testfile:8";


        QTest::newRow("two function") << source << expected;
    }

    {
        QString func("function foo(a, b) {\n"
                     "  return bt(a);\n"
                     "}");

        QString source = func + QString::fromLatin1("\n"
                 "custom_call(foo, 'hello');\n"
                 "var a = 1\n");

        QStringList expected;
        expected << "<native>('hello') at -1"
                 << "foo(a = 'hello') at testfile:2"
                 << QString("<native>(%1, 'hello') at -1").arg(func)
                 << "<global>() at testfile:4";

        QTest::newRow("call") << source << expected;
    }

    {
        QString source = QString::fromLatin1("\n"
        "custom_call(bt, 'hello_world');\n"
        "var a = 1\n");

        QStringList expected;
        expected << "<native>('hello_world') at -1"
        << "<native>(function () {\n    [native code]\n}, 'hello_world') at -1"
        << "<global>() at testfile:2";

        QTest::newRow("call native") << source << expected;
    }

    {
        QLatin1String func( "function f1() {\n"
            "    eval('var q = 4');\n"
            "    return custom_call(bt, 22);\n"
            "}");

        QString source = QString::fromLatin1("\n"
            "function f2() {\n"
            "    func = %1\n"
            "    return custom_call(func, 12);\n"
            "}\n"
            "f2();\n").arg(func);

        QStringList expected;
        expected << "<native>(22) at -1"
            << "<native>(function () {\n    [native code]\n}, 22) at -1"
            << "f1(12) at testfile:5"
            << QString::fromLatin1("<native>(%1, 12) at -1").arg(func)
            << "f2() at testfile:7"
            << "<global>() at testfile:9";


        QTest::newRow("calls with closures") << source << expected;
    }

    {
        QLatin1String func( "function js_bt() {\n"
            "    return bt();\n"
            "}");

        QString source = QString::fromLatin1("\n"
            "%1\n"
            "function f() {\n"
            "    return native_recurse(js_bt, 12);\n"
            "}\n"
            "f();\n").arg(func);

        QStringList expected;
        expected << "<native>() at -1" << "js_bt() at testfile:3";
        for(int n = 1; n <= 12; n++) {
            expected << QString::fromLatin1("<native>(%1, %2) at -1")
                .arg(func).arg(n);
        }
        expected << "f() at testfile:6";
        expected << "<global>() at testfile:8";

        QTest::newRow("native recursive") << source << expected;
    }

    {
        QString source = QString::fromLatin1("\n"
            "function finish() {\n"
            "    return bt();\n"
            "}\n"
            "function rec(n) {\n"
            "    if(n <= 1)\n"
            "        return finish();\n"
            "    else\n"
            "        return rec (n - 1);\n"
            "}\n"
            "function f() {\n"
            "    return rec(12);\n"
            "}\n"
            "f();\n");

        QStringList expected;
        expected << "<native>() at -1" << "finish() at testfile:3";
        for(int n = 1; n <= 12; n++) {
            expected << QString::fromLatin1("rec(n = %1) at testfile:%2")
                .arg(n).arg((n==1) ? 7 : 9);
        }
        expected << "f() at testfile:12";
        expected << "<global>() at testfile:14";

        QTest::newRow("js recursive") << source << expected;
    }

    {
        QString source = QString::fromLatin1(
            "[0].forEach(\n"
            "    function() {\n"
            "        result = bt();\n"
            "}); result");

        QStringList expected;
        expected << "<native>() at -1"
                 << "<anonymous>(0, 0, 0) at testfile:3"
                 << QString::fromLatin1("forEach(%0) at -1")
                    // Because the JIT doesn't store the arguments in the frame
                    // for built-in functions, arguments are not available.
                    // Will work when the copy of JavaScriptCore is updated
                    // (QTBUG-16568).
                    .arg(qt_script_isJITEnabled()
                         ? ""
                         : "function () {\n        result = bt();\n}")
                 << "<global>() at testfile:4";
        QTest::newRow("js callback from built-in") << source << expected;
    }

    {
        QString source = QString::fromLatin1(
            "[10,20].forEach(\n"
            "    function() {\n"
            "        result = bt();\n"
            "}); result");

        QStringList expected;
        expected << "<native>() at -1"
                 << "<anonymous>(20, 1, 10,20) at testfile:3"
                 << QString::fromLatin1("forEach(%0) at -1")
                    // Because the JIT doesn't store the arguments in the frame
                    // for built-in functions, arguments are not available.
                    // Will work when the copy of JavaScriptCore is updated
                    // (QTBUG-16568).
                    .arg(qt_script_isJITEnabled()
                         ? ""
                         : "function () {\n        result = bt();\n}")
                 << "<global>() at testfile:4";
        QTest::newRow("js callback from built-in") << source << expected;
    }
}


void tst_QScriptContext::backtrace()
{
    QFETCH(QString, code);
    QFETCH(QStringList, expectedbacktrace);

    QScriptEngine eng;
    eng.globalObject().setProperty("bt", eng.newFunction(getBacktrace));
    eng.globalObject().setProperty("custom_eval", eng.newFunction(custom_eval));
    eng.globalObject().setProperty("custom_call", eng.newFunction(custom_call));
    eng.globalObject().setProperty("native_recurse", eng.newFunction(native_recurse));

    QString fileName = "testfile";
    QScriptValue ret = eng.evaluate(code, fileName);
    QVERIFY(!eng.hasUncaughtException());
    QVERIFY(ret.isArray());
    QStringList slist = qscriptvalue_cast<QStringList>(ret);
    QEXPECT_FAIL("eval", "QTBUG-17842: Missing line number in backtrace when function calls eval()", Continue);
    QEXPECT_FAIL("eval in member", "QTBUG-17842: Missing line number in backtrace when function calls eval()", Continue);
    QCOMPARE(slist, expectedbacktrace);
}

static QScriptValue getScopeChain(QScriptContext *ctx, QScriptEngine *eng)
{
    return qScriptValueFromValue(eng, ctx->parentContext()->scopeChain());
}

void tst_QScriptContext::scopeChain_globalContext()
{
    QScriptEngine eng;
    {
        QScriptValueList ret = eng.currentContext()->scopeChain();
        QCOMPARE(ret.size(), 1);
        QVERIFY(ret.at(0).strictlyEquals(eng.globalObject()));
    }
    {
        eng.globalObject().setProperty("getScopeChain", eng.newFunction(getScopeChain));
        QScriptValueList ret = qscriptvalue_cast<QScriptValueList>(eng.evaluate("getScopeChain()"));
        QCOMPARE(ret.size(), 1);
        QVERIFY(ret.at(0).strictlyEquals(eng.globalObject()));
    }
}

void tst_QScriptContext::scopeChain_closure()
{
    QScriptEngine eng;
    eng.globalObject().setProperty("getScopeChain", eng.newFunction(getScopeChain));

    eng.evaluate("function foo() { function bar() { return getScopeChain(); } return bar() }");
    QScriptValueList ret = qscriptvalue_cast<QScriptValueList>(eng.evaluate("foo()"));
    // JSC will not create an activation for bar() unless we insert a call
    // to eval() in the function body; JSC has no way of knowing that the
    // native function will be asking for the activation, and we don't want
    // to needlessly create it.
    QEXPECT_FAIL("", "QTBUG-10313: JSC optimizes away the activation object", Abort);
    QCOMPARE(ret.size(), 3);
    QVERIFY(ret.at(2).strictlyEquals(eng.globalObject()));
    QCOMPARE(ret.at(1).toString(), QString::fromLatin1("activation"));
    QVERIFY(ret.at(1).property("arguments").isObject());
    QCOMPARE(ret.at(0).toString(), QString::fromLatin1("activation"));
    QVERIFY(ret.at(0).property("arguments").isObject());
}

void tst_QScriptContext::scopeChain_withStatement()
{
    QScriptEngine eng;
    eng.globalObject().setProperty("getScopeChain", eng.newFunction(getScopeChain));
    {
        QScriptValueList ret = qscriptvalue_cast<QScriptValueList>(eng.evaluate("o = { x: 123 }; with(o) getScopeChain();"));
        QEXPECT_FAIL("", "QTBUG-17131: with-scope isn't reflected by QScriptContext", Abort);
        QCOMPARE(ret.size(), 2);
        QVERIFY(ret.at(1).strictlyEquals(eng.globalObject()));
        QVERIFY(ret.at(0).isObject());
        QCOMPARE(ret.at(0).property("x").toInt32(), 123);
    }
    {
        QScriptValueList ret = qscriptvalue_cast<QScriptValueList>(
            eng.evaluate("o1 = { x: 123}; o2 = { y: 456 }; with(o1) { with(o2) { getScopeChain(); } }"));
        QCOMPARE(ret.size(), 3);
        QVERIFY(ret.at(2).strictlyEquals(eng.globalObject()));
        QVERIFY(ret.at(1).isObject());
        QCOMPARE(ret.at(1).property("x").toInt32(), 123);
        QVERIFY(ret.at(0).isObject());
        QCOMPARE(ret.at(0).property("y").toInt32(), 456);
    }
}

void tst_QScriptContext::pushScopeEvaluate()
{
    QScriptEngine engine;
    QScriptValue object = engine.newObject();
    object.setProperty("foo", 1234);
    object.setProperty(1, 1234);
    engine.currentContext()->pushScope(object);
    object.setProperty("bar", 4321);
    object.setProperty(2, 4321);
    QVERIFY(engine.evaluate("foo").equals(1234));
    QVERIFY(engine.evaluate("bar").equals(4321));
}

void tst_QScriptContext::pushScopeCall()
{
    QScriptEngine engine;
    QScriptValue object = engine.globalObject();
    QScriptValue thisObject = engine.newObject();
    QScriptValue function = engine.evaluate("(function(property){return this[property]; })");
    QVERIFY(function.isFunction());
    object.setProperty("foo", 1234);
    thisObject.setProperty("foo", "foo");
    engine.currentContext()->pushScope(object);
    object.setProperty("bar", 4321);
    thisObject.setProperty("bar", "bar");
    QVERIFY(function.call(QScriptValue(), QScriptValueList() << "foo").equals(1234));
    QVERIFY(function.call(QScriptValue(), QScriptValueList() << "bar").equals(4321));
    QVERIFY(function.call(thisObject, QScriptValueList() << "foo").equals("foo"));
    QVERIFY(function.call(thisObject, QScriptValueList() << "bar").equals("bar"));
}

void tst_QScriptContext::popScopeSimple()
{
    QScriptEngine engine;
    QScriptValue object = engine.newObject();
    QScriptValue globalObject = engine.globalObject();
    engine.currentContext()->pushScope(object);
    QVERIFY(engine.currentContext()->popScope().strictlyEquals(object));
    QVERIFY(engine.globalObject().strictlyEquals(globalObject));
}

void tst_QScriptContext::pushAndPopGlobalObjectSimple()
{
    QScriptEngine engine;
    QScriptValue globalObject = engine.globalObject();
    engine.currentContext()->pushScope(globalObject);
    QVERIFY(engine.currentContext()->popScope().strictlyEquals(globalObject));
    QVERIFY(engine.globalObject().strictlyEquals(globalObject));
}

void tst_QScriptContext::pushAndPopIterative()
{
    QScriptEngine engine;
    for (uint repeat = 0; repeat < 2; ++repeat) {
        for (uint i = 1; i < 11; ++i) {
            QScriptValue object = engine.newObject();
            object.setProperty("x", i + 10 * repeat);
            engine.currentContext()->pushScope(object);
        }
        for (uint i = 10; i > 0; --i) {
            QScriptValue object = engine.currentContext()->popScope();
            QVERIFY(object.property("x").equals(i + 10 * repeat));
        }
    }
}

void tst_QScriptContext::pushAndPopScope_globalContext()
{
    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);
}

void tst_QScriptContext::pushAndPopScope_globalContext2()
{
    QScriptEngine eng;
    QScriptContext *ctx = eng.currentContext();
    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(eng.newObject());
    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());
}

static QScriptValue get_activationObject(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->activationObject();
}

void tst_QScriptContext::getSetActivationObject_globalContext()
{
    QScriptEngine eng;
    QScriptContext *ctx = eng.currentContext();
    QVERIFY(ctx->activationObject().equals(eng.globalObject()));

    ctx->setActivationObject(QScriptValue());
    QVERIFY(ctx->activationObject().equals(eng.globalObject()));
    QCOMPARE(ctx->engine(), &eng);

    QScriptValue obj = eng.newObject();
    ctx->setActivationObject(obj);
    QVERIFY(ctx->activationObject().equals(obj));
    QCOMPARE(ctx->scopeChain().size(), 1);
    QVERIFY(ctx->scopeChain().at(0).equals(obj));

    {
        QScriptEngine eng2;
        QScriptValue obj2 = eng2.newObject();
        QTest::ignoreMessage(QtWarningMsg, "QScriptContext::setActivationObject() failed: cannot set an object created in a different engine");
        QScriptValue was = ctx->activationObject();
        ctx->setActivationObject(obj2);
        QVERIFY(ctx->activationObject().equals(was));
    }

    ctx->setActivationObject(eng.globalObject());
    QVERIFY(ctx->activationObject().equals(eng.globalObject()));
    QScriptValue fun = eng.newFunction(get_activationObject);
    eng.globalObject().setProperty("get_activationObject", fun);
    {
        QScriptValue ret = eng.evaluate("get_activationObject(1, 2, 3)");
        QVERIFY(ret.isObject());
        QScriptValue arguments = ret.property("arguments");
        QEXPECT_FAIL("", "QTBUG-17136: arguments property of activation object is missing", Abort);
        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);
    }
}

void tst_QScriptContext::getSetActivationObject_customContext()
{
    QScriptEngine eng;
    QScriptContext *ctx = eng.pushContext();
    QVERIFY(ctx->activationObject().isObject());
    QScriptValue act = eng.newObject();
    ctx->setActivationObject(act);
    QVERIFY(ctx->activationObject().equals(act));
    eng.evaluate("var foo = 123");
    QCOMPARE(act.property("foo").toInt32(), 123);
    eng.popContext();
    QCOMPARE(act.property("foo").toInt32(), 123);
}

// Helper function that's intended to have the same behavior
// as the built-in eval() function.
static QScriptValue myEval(QScriptContext *ctx, QScriptEngine *eng)
{
     QString code = ctx->argument(0).toString();
     ctx->setActivationObject(ctx->parentContext()->activationObject());
     ctx->setThisObject(ctx->parentContext()->thisObject());
     return eng->evaluate(code);
}

void tst_QScriptContext::inheritActivationAndThisObject()
{
    QScriptEngine eng;
    eng.globalObject().setProperty("myEval", eng.newFunction(myEval));
    {
        QScriptValue ret = eng.evaluate("var a = 123; myEval('a')");
        QVERIFY(ret.isNumber());
        QCOMPARE(ret.toInt32(), 123);
    }
    {
        QScriptValue ret = eng.evaluate("(function() { return myEval('this'); }).call(Number)");
        QVERIFY(ret.isFunction());
        QVERIFY(ret.equals(eng.globalObject().property("Number")));
    }
    {
        QScriptValue ret = eng.evaluate("(function(a) { return myEval('a'); })(123)");
        QVERIFY(ret.isNumber());
        QCOMPARE(ret.toInt32(), 123);
    }

    {
        eng.globalObject().setProperty("a", 123);
        QScriptValue ret = eng.evaluate("(function() { myEval('var a = 456'); return a; })()");
        QVERIFY(ret.isNumber());
        QCOMPARE(ret.toInt32(), 456);
        // Since JSC doesn't create an activation object for the anonymous function call,
        // myEval() will use the global object as the activation, which is wrong.
        QEXPECT_FAIL("", "QTBUG-10313: Wrong activation object is returned from native function's parent context", Continue);
        QVERIFY(eng.globalObject().property("a").strictlyEquals(123));
    }
}

static QScriptValue parentContextToString(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->parentContext()->toString();
}

void tst_QScriptContext::toString()
{
    QScriptEngine eng;
    eng.globalObject().setProperty("parentContextToString", eng.newFunction(parentContextToString));
    QScriptValue ret = eng.evaluate("function foo(first, second, third) {\n"
                                    "    return parentContextToString();\n"
                                    "}; foo(1, 2, 3)", "script.qs");
    QVERIFY(ret.isString());
    QCOMPARE(ret.toString(), QString::fromLatin1("foo(first = 1, second = 2, third = 3) at script.qs:2"));
}

static QScriptValue storeCalledAsConstructor(QScriptContext *ctx, QScriptEngine *eng)
{
    ctx->callee().setProperty("calledAsConstructor", ctx->isCalledAsConstructor());
    return eng->undefinedValue();
}

static QScriptValue storeCalledAsConstructorV2(QScriptContext *ctx, QScriptEngine *eng, void *)
{
    ctx->callee().setProperty("calledAsConstructor", ctx->isCalledAsConstructor());
    return eng->undefinedValue();
}

static QScriptValue storeCalledAsConstructorV3(QScriptContext *ctx, QScriptEngine *eng)
{
    ctx->callee().setProperty("calledAsConstructor", ctx->parentContext()->isCalledAsConstructor());
    return eng->undefinedValue();
}

void tst_QScriptContext::calledAsConstructor_fromCpp()
{
    QScriptEngine eng;
    {
        QScriptValue fun1 = eng.newFunction(storeCalledAsConstructor);
        fun1.call();
        QVERIFY(!fun1.property("calledAsConstructor").toBool());
        fun1.construct();
        QVERIFY(fun1.property("calledAsConstructor").toBool());
    }
    {
        QScriptValue fun = eng.newFunction(storeCalledAsConstructorV2, (void*)0);
        fun.call();
        QVERIFY(!fun.property("calledAsConstructor").toBool());
        fun.construct();
        QVERIFY(fun.property("calledAsConstructor").toBool());
    }
}

void tst_QScriptContext::calledAsConstructor_fromJS()
{
    QScriptEngine eng;
    QScriptValue fun1 = eng.newFunction(storeCalledAsConstructor);
    eng.globalObject().setProperty("fun1", fun1);
    eng.evaluate("fun1();");
    QVERIFY(!fun1.property("calledAsConstructor").toBool());
    eng.evaluate("new fun1();");
    QVERIFY(fun1.property("calledAsConstructor").toBool());
}

void tst_QScriptContext::calledAsConstructor_parentContext()
{
    QScriptEngine eng;
    QScriptValue fun3 = eng.newFunction(storeCalledAsConstructorV3);
    eng.globalObject().setProperty("fun3", fun3);
    eng.evaluate("function test() { fun3() }");
    eng.evaluate("test();");
    QVERIFY(!fun3.property("calledAsConstructor").toBool());
    eng.evaluate("new test();");
    if (qt_script_isJITEnabled())
        QEXPECT_FAIL("", "QTBUG-6132: calledAsConstructor is not correctly set for JS functions when JIT is enabled", Continue);
    QVERIFY(fun3.property("calledAsConstructor").toBool());
}

static QScriptValue argumentsObjectInNative_test1(QScriptContext *ctx, QScriptEngine *eng)
{
#define VERIFY(statement) \
    do {\
        if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__))\
            return QString::fromLatin1("Failed "  #statement);\
    } while (0)

    QScriptValue obj = ctx->argumentsObject();
    VERIFY(obj.isObject());
    VERIFY(obj.property(0).toUInt32() == 123);
    VERIFY(obj.property(1).toString() == QString::fromLatin1("456"));

    obj.setProperty(0, "abc");
    VERIFY(eng->evaluate("arguments[0]").toString() == QString::fromLatin1("abc") );

    return QString::fromLatin1("success");
#undef VERIFY
}

void tst_QScriptContext::argumentsObjectInNative()
{
    {
        QScriptEngine eng;
        QScriptValue fun = eng.newFunction(argumentsObjectInNative_test1);
        QScriptValueList args;
        args << QScriptValue(&eng, 123.0);
        args << QScriptValue(&eng, QString::fromLatin1("456"));
        QScriptValue result = fun.call(eng.undefinedValue(), args);
        QVERIFY(!eng.hasUncaughtException());
        QCOMPARE(result.toString(), QString::fromLatin1("success"));
    }
    {
        QScriptEngine eng;
        QScriptValue fun = eng.newFunction(argumentsObjectInNative_test1);
        eng.globalObject().setProperty("func", fun);
        QScriptValue result = eng.evaluate("func(123.0 , 456);");
        QVERIFY(!eng.hasUncaughtException());
        QCOMPARE(result.toString(), QString::fromLatin1("success"));
    }
}

static QScriptValue get_jsActivationObject(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->parentContext()->parentContext()->activationObject();
}

void tst_QScriptContext::jsActivationObject()
{
    QScriptEngine eng;
    eng.globalObject().setProperty("get_jsActivationObject", eng.newFunction(get_jsActivationObject));
    eng.evaluate("function f1() { var w = get_jsActivationObject('arg1');  return w; }");
    eng.evaluate("function f2(x,y,z) { var v1 = 42;\n"
                        //   "function foo() {};\n" //this would avoid JSC to optimize
                        "var v2 = f1(); return v2; }");
    eng.evaluate("function f3() { var v1 = 'nothing'; return f2(1,2,3); }");
    QScriptValue result1 = eng.evaluate("f2('hello', 'useless', 'world')");
    QScriptValue result2 = eng.evaluate("f3()");
    QVERIFY(result1.isObject());
    QEXPECT_FAIL("", "QTBUG-10313: JSC optimizes away the activation object", Abort);
    QCOMPARE(result1.property("v1").toInt32() , 42);
    QCOMPARE(result1.property("arguments").property(1).toString() , QString::fromLatin1("useless"));
    QVERIFY(result2.isObject());
    QCOMPARE(result2.property("v1").toInt32() , 42);
    QCOMPARE(result2.property("arguments").property(1).toString() , QString::fromLatin1("2"));
}

void tst_QScriptContext::qobjectAsActivationObject()
{
    QScriptEngine eng;
    QObject object;
    QScriptValue scriptObject = eng.newQObject(&object);
    QScriptContext *ctx = eng.pushContext();
    ctx->setActivationObject(scriptObject);
    QVERIFY(ctx->activationObject().equals(scriptObject));

    QVERIFY(!scriptObject.property("foo").isValid());
    eng.evaluate("function foo() { return 123; }");
    {
        QScriptValue val = scriptObject.property("foo");
        QVERIFY(val.isValid());
        QVERIFY(val.isFunction());
    }
    QVERIFY(!eng.globalObject().property("foo").isValid());

    QVERIFY(!scriptObject.property("bar").isValid());
    eng.evaluate("var bar = 123");
    {
        QScriptValue val = scriptObject.property("bar");
        QVERIFY(val.isValid());
        QVERIFY(val.isNumber());
        QCOMPARE(val.toInt32(), 123);
    }
    QVERIFY(!eng.globalObject().property("bar").isValid());

    {
        QScriptValue val = eng.evaluate("delete foo");
        QVERIFY(val.isBool());
        QVERIFY(val.toBool());
        QVERIFY(!scriptObject.property("foo").isValid());
    }
}

static QScriptValue getParentContextCallee(QScriptContext *ctx, QScriptEngine *)
{
    return ctx->parentContext()->callee();
}

void tst_QScriptContext::parentContextCallee_QT2270()
{
    QScriptEngine engine;
    engine.globalObject().setProperty("getParentContextCallee", engine.newFunction(getParentContextCallee));
    QScriptValue fun = engine.evaluate("(function() { return getParentContextCallee(); })");
    QVERIFY(fun.isFunction());
    QScriptValue callee = fun.call();
    QVERIFY(callee.equals(fun));
}

void tst_QScriptContext::throwErrorInGlobalContext()
{
    QScriptEngine eng;
    QScriptValue ret = eng.currentContext()->throwError("foo");
    QVERIFY(ret.isError());
    QVERIFY(eng.hasUncaughtException());
    QVERIFY(eng.uncaughtException().strictlyEquals(ret));
    QCOMPARE(ret.toString(), QString::fromLatin1("Error: foo"));
}

void tst_QScriptContext::throwErrorWithTypeInGlobalContext_data()
{
    QTest::addColumn<QScriptContext::Error>("error");
    QTest::addColumn<QString>("stringRepresentation");
    QTest::newRow("ReferenceError") << QScriptContext::ReferenceError << QString::fromLatin1("ReferenceError: foo");
    QTest::newRow("SyntaxError") << QScriptContext::SyntaxError << QString::fromLatin1("SyntaxError: foo");
    QTest::newRow("TypeError") << QScriptContext::TypeError << QString::fromLatin1("TypeError: foo");
    QTest::newRow("RangeError") << QScriptContext::RangeError << QString::fromLatin1("RangeError: foo");
    QTest::newRow("URIError") << QScriptContext::URIError << QString::fromLatin1("URIError: foo");
    QTest::newRow("UnknownError") << QScriptContext::UnknownError << QString::fromLatin1("Error: foo");
}

void tst_QScriptContext::throwErrorWithTypeInGlobalContext()
{
    QFETCH(QScriptContext::Error, error);
    QFETCH(QString, stringRepresentation);
    QScriptEngine eng;
    QScriptValue ret = eng.currentContext()->throwError(error, "foo");
    QVERIFY(ret.isError());
    QVERIFY(eng.hasUncaughtException());
    QVERIFY(eng.uncaughtException().strictlyEquals(ret));
    QCOMPARE(ret.toString(), stringRepresentation);
}

void tst_QScriptContext::throwValueInGlobalContext()
{
    QScriptEngine eng;
    QScriptValue val(&eng, 123);
    QScriptValue ret = eng.currentContext()->throwValue(val);
    QVERIFY(ret.strictlyEquals(val));
    QVERIFY(eng.hasUncaughtException());
    QVERIFY(eng.uncaughtException().strictlyEquals(val));
}

QTEST_MAIN(tst_QScriptContext)
#include "tst_qscriptcontext.moc"
