diff options
-rw-r--r-- | src/script/api/qscriptcontext.cpp | 21 | ||||
-rw-r--r-- | tests/auto/qscriptcontext/tst_qscriptcontext.cpp | 53 |
2 files changed, 62 insertions, 12 deletions
diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp index 229c8ab..118b551 100644 --- a/src/script/api/qscriptcontext.cpp +++ b/src/script/api/qscriptcontext.cpp @@ -273,9 +273,8 @@ QScriptValue QScriptContext::argument(int index) const return QScriptValue(); if (index >= argumentCount()) return QScriptValue(QScriptValue::UndefinedValue); - JSC::Register* thisRegister = frame->registers() - JSC::RegisterFile::CallFrameHeaderSize - frame->argumentCount(); - ++index; //skip the 'this' object - return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(thisRegister[index].jsValue()); + QScriptValue v = argumentsObject().property(index); + return v; } /*! @@ -306,15 +305,23 @@ QScriptValue QScriptContext::callee() const QScriptValue QScriptContext::argumentsObject() const { JSC::CallFrame *frame = const_cast<JSC::ExecState*>(QScriptEnginePrivate::frameForContext(this)); - if (frame == frame->lexicalGlobalObject()->globalExec()) { - //global context doesn't have any argument, return an empty object + + if (frame == frame->lexicalGlobalObject()->globalExec() || frame->callerFrame()->hasHostCallFrameFlag()) { + // <global> or <eval> context doesn't have arguments. return an empty object return QScriptEnginePrivate::get(QScript::scriptEngineFromExec(frame))->newObject(); } - Q_ASSERT(frame->argumentCount() > 0); //we need at least 'this' otherwise we'll crash later + + //for a js function + if (frame->codeBlock() && frame->callee()) { + JSC::JSValue result = frame->interpreter()->retrieveArguments(frame, JSC::asFunction(frame->callee())); + return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(result); + } + + //for a native function if (!frame->optionalCalleeArguments()) { + Q_ASSERT(frame->argumentCount() > 0); //we need at least 'this' otherwise we'll crash later JSC::Arguments* arguments = new (&frame->globalData())JSC::Arguments(frame, JSC::Arguments::NoParameters); frame->setCalleeArguments(arguments); - frame[JSC::RegisterFile::ArgumentsRegister] = arguments; } return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(frame->optionalCalleeArguments()); } diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp index e5d26a3..a0c56ed 100644 --- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp +++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp @@ -565,11 +565,6 @@ void tst_QScriptContext::backtrace_data() QTest::addColumn<QStringList>("expectedbacktrace"); { - QStringList expected; - expected << "<native>(123) at -1" - << "foo([object Object], [object global]) at testfile:2" //### object instead of 'hello' - << "<global>() at testfile:4"; - QString source( "function foo() {\n" " return bt(123);\n" @@ -577,6 +572,12 @@ void tst_QScriptContext::backtrace_data() "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; } @@ -639,6 +640,48 @@ void tst_QScriptContext::backtrace_data() 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" + //### line number should be 3 but the line number information is not kept for eval call + << "plop('hello', 456) at testfile:-1" + << "<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; + } + + } |