summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@trolltech.com>2009-08-11 07:35:50 (GMT)
committerOlivier Goffart <ogoffart@trolltech.com>2009-08-11 07:44:24 (GMT)
commit81d8292e486bce768d9af27e3510520a769c4fa8 (patch)
treef2925d15dc89a6bb64b34ecf162d6ac9fa5e312d
parent62281ca6f9e74a5c8b66204d74ceec0215ecab92 (diff)
downloadQt-81d8292e486bce768d9af27e3510520a769c4fa8.zip
Qt-81d8292e486bce768d9af27e3510520a769c4fa8.tar.gz
Qt-81d8292e486bce768d9af27e3510520a769c4fa8.tar.bz2
Fix line number and arguments in QScriptContext::toString
For arguments, we always need to skip the implicit 'this' argument For line number, we walk thought the stack frames from the top to find the one above the requested one, which contains the returnPC we need. Also fixed a crash because QScriptContext::parentContext would have returned a pointer with flags inside. Reviewed-by: Kent Hansen
-rw-r--r--src/script/api/qscriptcontext.cpp7
-rw-r--r--src/script/api/qscriptcontextinfo.cpp20
-rw-r--r--tests/auto/qscriptcontext/tst_qscriptcontext.cpp1
-rw-r--r--tests/auto/qscriptcontextinfo/tst_qscriptcontextinfo.cpp1
4 files changed, 20 insertions, 9 deletions
diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp
index 669002d..f4b8af6 100644
--- a/src/script/api/qscriptcontext.cpp
+++ b/src/script/api/qscriptcontext.cpp
@@ -273,8 +273,7 @@ QScriptValue QScriptContext::argument(int index) const
if (index >= argumentCount())
return QScriptValue(QScriptValue::UndefinedValue);
JSC::Register* thisRegister = frame->registers() - JSC::RegisterFile::CallFrameHeaderSize - frame->argumentCount();
- if (frame->codeBlock() == 0)
- ++index; // ### off-by-one issue with native functions
+ ++index; //skip the 'this' object
return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(thisRegister[index].jsValue());
}
@@ -370,9 +369,7 @@ bool QScriptContext::isCalledAsConstructor() const
QScriptContext *QScriptContext::parentContext() const
{
const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
- JSC::CallFrame *callerFrame = frame->callerFrame();
- if (callerFrame == (JSC::CallFrame*)(1)) // ### CallFrame::noCaller() is private
- return 0;
+ JSC::CallFrame *callerFrame = frame->callerFrame()->removeHostCallFrameFlag();
return reinterpret_cast<QScriptContext *>(callerFrame);
}
diff --git a/src/script/api/qscriptcontextinfo.cpp b/src/script/api/qscriptcontextinfo.cpp
index 52776e2..20b77f0 100644
--- a/src/script/api/qscriptcontextinfo.cpp
+++ b/src/script/api/qscriptcontextinfo.cpp
@@ -174,8 +174,6 @@ QScriptContextInfoPrivate::QScriptContextInfoPrivate(const QScriptContext *conte
for (size_t i = 0; i < body->parameterCount(); ++i)
parameterNames.append(QScript::qtStringFromJSCUString(params[i].ustring()));
// ### get the function name from the AST
- // ### don't know the PC, since it's not stored in the frame
- // lineNumber = codeBlock->expressionRangeForBytecodeOffset(...);
} else if (callee && callee->isObject(&QScript::QtFunction::info)) {
functionType = QScriptContextInfo::QtFunction;
// ### the slot can be overloaded -- need to get the particular overload from the context
@@ -192,6 +190,24 @@ QScriptContextInfoPrivate::QScriptContextInfoPrivate(const QScriptContext *conte
functionType = QScriptContextInfo::QtPropertyFunction;
functionMetaIndex = static_cast<QScript::QtPropertyFunction*>(callee)->propertyIndex();
}
+
+ // get the lineNumber:
+ QScriptContext *rewindContext = context->engine()->currentContext();
+ if (rewindContext == context) {
+ //ignore native function
+ } else {
+ // rewind the stack from the top in order to find the frame from the caller where the returnPC is stored
+ while (rewindContext && rewindContext->parentContext() != context)
+ rewindContext = rewindContext->parentContext();
+ if (rewindContext) {
+ JSC::Instruction *returnPC = QScriptEnginePrivate::frameForContext(rewindContext)->returnPC();
+ JSC::CodeBlock *codeBlock = frame->codeBlock();
+ if (returnPC && codeBlock) {
+ lineNumber = codeBlock->lineNumberForBytecodeOffset(const_cast<JSC::ExecState *>(frame),
+ returnPC - codeBlock->instructions().begin());
+ }
+ }
+ }
}
/*!
diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
index a278d2c..be0b2b7 100644
--- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
+++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
@@ -791,7 +791,6 @@ void tst_QScriptContext::toString()
" return parentContextToString();\n"
"}; foo(1, 2, 3)", "script.qs");
QVERIFY(ret.isString());
- QEXPECT_FAIL("", "", Continue);
QCOMPARE(ret.toString(), QString::fromLatin1("foo (first=1, second=2, third=3) at script.qs:2"));
}
diff --git a/tests/auto/qscriptcontextinfo/tst_qscriptcontextinfo.cpp b/tests/auto/qscriptcontextinfo/tst_qscriptcontextinfo.cpp
index 0877717..921cbd8 100644
--- a/tests/auto/qscriptcontextinfo/tst_qscriptcontextinfo.cpp
+++ b/tests/auto/qscriptcontextinfo/tst_qscriptcontextinfo.cpp
@@ -185,7 +185,6 @@ void tst_QScriptContextInfo::scriptFunction()
QCOMPARE(info.functionType(), QScriptContextInfo::ScriptFunction);
QVERIFY(info.scriptId() != -1);
QCOMPARE(info.fileName(), fileName);
- QEXPECT_FAIL("", "lineNumber doesn't work", Continue);
QCOMPARE(info.lineNumber(), lineNumber + 1);
QEXPECT_FAIL("", "columnNumber doesn't work", Continue);
QCOMPARE(info.columnNumber(), 2);