summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <olivier.goffart@nokia.com>2010-07-23 14:06:08 (GMT)
committerOlivier Goffart <olivier.goffart@nokia.com>2010-07-23 14:54:35 (GMT)
commit9d2760f619782145e0861300901531a56c12991a (patch)
treef6f1bc0590571c3798a4b12412ba4979db47d427
parent558fafd76690e067b775a28a739c6aedfdffe783 (diff)
downloadQt-9d2760f619782145e0861300901531a56c12991a.zip
Qt-9d2760f619782145e0861300901531a56c12991a.tar.gz
Qt-9d2760f619782145e0861300901531a56c12991a.tar.bz2
QScriptEngineAgent: ensure that the top of the backtrace is correct in exceptionThrow
Reviewed-by: Jedrzej Nowacki
-rw-r--r--src/script/api/qscriptengineagent.cpp3
-rw-r--r--tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp83
2 files changed, 86 insertions, 0 deletions
diff --git a/src/script/api/qscriptengineagent.cpp b/src/script/api/qscriptengineagent.cpp
index 28905e8..0b5828a 100644
--- a/src/script/api/qscriptengineagent.cpp
+++ b/src/script/api/qscriptengineagent.cpp
@@ -134,9 +134,12 @@ void QScriptEngineAgentPrivate::returnEvent(const JSC::DebuggerCallFrame& frame,
void QScriptEngineAgentPrivate::exceptionThrow(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, bool hasHandler)
{
JSC::CallFrame *oldFrame = engine->currentFrame;
+ int oldAgentLineNumber = engine->agentLineNumber;
engine->currentFrame = frame.callFrame();
QScriptValue value(engine->scriptValueFromJSCValue(frame.exception()));
+ engine->agentLineNumber = value.property(QLatin1String("lineNumber")).toInt32();
q_ptr->exceptionThrow(sourceID, value, hasHandler);
+ engine->agentLineNumber = oldAgentLineNumber;
engine->currentFrame = oldFrame;
engine->setCurrentException(value);
};
diff --git a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp
index a0f10dd..ed00b96 100644
--- a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp
+++ b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp
@@ -116,6 +116,8 @@ private slots:
void evaluateProgram_SyntaxError();
void evaluateNullProgram();
void QTBUG6108();
+ void backtraces_data();
+ void backtraces();
private:
double m_testProperty;
@@ -2379,5 +2381,86 @@ void tst_QScriptEngineAgent::QTBUG6108()
QCOMPARE(spy->at(4).scriptId, spy->at(0).scriptId);
}
+class BacktraceSpy : public QScriptEngineAgent
+{
+public:
+ BacktraceSpy(QScriptEngine *engine, const QStringList &expectedbacktrace, int breakpoint)
+ : QScriptEngineAgent(engine), expectedbacktrace(expectedbacktrace), breakpoint(breakpoint), ok(false) {}
+
+ QStringList expectedbacktrace;
+ int breakpoint;
+ bool ok;
+
+protected:
+
+ void exceptionThrow(qint64 , const QScriptValue &, bool)
+ { check(); }
+
+ void positionChange(qint64 , int lineNumber, int )
+ {
+ if (lineNumber == breakpoint)
+ check();
+ }
+
+private:
+ void check()
+ {
+ QCOMPARE(engine()->currentContext()->backtrace(), expectedbacktrace);
+ ok = true;
+ }
+};
+
+
+void tst_QScriptEngineAgent::backtraces_data()
+{
+ QTest::addColumn<QString>("code");
+ QTest::addColumn<int>("breakpoint");
+ QTest::addColumn<QStringList>("expectedbacktrace");
+
+ {
+ QString source(
+ "function foo() {\n"
+ " var a = 5\n"
+ "}\n"
+ "foo('hello', { })\n"
+ "var r = 0;");
+
+ QStringList expected;
+ expected
+ << "foo('hello', [object Object]) at filename.js:2"
+ << "<global>() at filename.js:4";
+ QTest::newRow("simple breakpoint") << source << 2 << expected;
+ }
+
+ {
+ QString source(
+ "function foo() {\n"
+ " error = err\n" //this must throw
+ "}\n"
+ "foo('hello', { })\n"
+ "var r = 0;");
+
+ QStringList expected;
+ expected
+ << "foo('hello', [object Object]) at filename.js:2"
+ << "<global>() at filename.js:4";
+ QTest::newRow("throw because of error") << source << -100 << expected;
+ }
+}
+
+void tst_QScriptEngineAgent::backtraces()
+{
+ QFETCH(QString, code);
+ QFETCH(int, breakpoint);
+ QFETCH(QStringList, expectedbacktrace);
+
+ QScriptEngine eng;
+ BacktraceSpy *spy = new BacktraceSpy(&eng, expectedbacktrace, breakpoint);
+ eng.setAgent(spy);
+ QLatin1String filename("filename.js");
+ eng.evaluate(code, filename);
+ QVERIFY(spy->ok);
+}
+
QTEST_MAIN(tst_QScriptEngineAgent)
#include "tst_qscriptengineagent.moc"