From 9d2760f619782145e0861300901531a56c12991a Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 23 Jul 2010 16:06:08 +0200 Subject: QScriptEngineAgent: ensure that the top of the backtrace is correct in exceptionThrow Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengineagent.cpp | 3 + .../qscriptengineagent/tst_qscriptengineagent.cpp | 83 ++++++++++++++++++++++ 2 files changed, 86 insertions(+) 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("code"); + QTest::addColumn("breakpoint"); + QTest::addColumn("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" + << "() 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" + << "() 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" -- cgit v0.12