diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-07-23 14:06:08 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-07-23 14:54:35 (GMT) |
commit | 9d2760f619782145e0861300901531a56c12991a (patch) | |
tree | f6f1bc0590571c3798a4b12412ba4979db47d427 | |
parent | 558fafd76690e067b775a28a739c6aedfdffe783 (diff) | |
download | Qt-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.cpp | 3 | ||||
-rw-r--r-- | tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp | 83 |
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" |