diff options
-rw-r--r-- | src/qml/jsruntime/qv4debugging.cpp | 32 | ||||
-rw-r--r-- | tests/auto/qml/qv4debugger/tst_qv4debugger.cpp | 44 |
2 files changed, 63 insertions, 13 deletions
diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp index bcf0d07719..88db9df91a 100644 --- a/src/qml/jsruntime/qv4debugging.cpp +++ b/src/qml/jsruntime/qv4debugging.cpp @@ -49,25 +49,34 @@ namespace { class JavaScriptJob: public Debugger::Job { QV4::ExecutionEngine *engine; + int frameNr; const QString &script; public: - JavaScriptJob(QV4::ExecutionEngine *engine, const QString &script) + JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, const QString &script) : engine(engine) + , frameNr(frameNr) , script(script) {} void run() { - QV4::Scope scope(engine); - QV4::ExecutionContext *ctx = engine->currentContext(); - ContextStateSaver ctxSaver(ctx); - QV4::ScopedValue result(scope); + Scope scope(engine); + + ExecutionContextSaver saver(engine->currentContext()); + + Value *savedContexts = scope.alloc(frameNr); + for (int i = 0; i < frameNr; ++i) { + savedContexts[i] = engine->currentContext(); + engine->popContext(); + } + ExecutionContext *ctx = engine->currentContext(); QV4::Script script(ctx, this->script); script.strictMode = ctx->d()->strictMode; script.inheritContext = false; script.parse(); + QV4::ScopedValue result(scope); if (!scope.engine->hasException) result = script.run(); if (scope.engine->hasException) @@ -85,7 +94,7 @@ class EvalJob: public JavaScriptJob public: EvalJob(QV4::ExecutionEngine *engine, const QString &script) - : JavaScriptJob(engine, script) + : JavaScriptJob(engine, /*frameNr*/-1, script) , result(false) {} @@ -105,8 +114,8 @@ class ExpressionEvalJob: public JavaScriptJob Debugger::Collector *collector; public: - ExpressionEvalJob(ExecutionEngine *engine, const QString &expression, Debugger::Collector *collector) - : JavaScriptJob(engine, expression) + ExpressionEvalJob(ExecutionEngine *engine, int frameNr, const QString &expression, Debugger::Collector *collector) + : JavaScriptJob(engine, frameNr, expression) , collector(collector) { } @@ -486,13 +495,10 @@ QVector<ExecutionContext::ContextType> Debugger::getScopeTypes(int frame) const void Debugger::evaluateExpression(int frameNr, const QString &expression, Debugger::Collector *resultsCollector) { Q_ASSERT(state() == Paused); - Q_UNUSED(frameNr); Q_ASSERT(m_runningJob == 0); - ExpressionEvalJob job(m_engine, expression, resultsCollector); - m_runningJob = &job; - m_runningJob->run(); - m_runningJob = 0; + ExpressionEvalJob job(m_engine, frameNr, expression, resultsCollector); + runInEngine(&job); } void Debugger::maybeBreakAtInstruction() diff --git a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp index 3fe14fa216..6457cb7898 100644 --- a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp +++ b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp @@ -182,6 +182,14 @@ public: m_stackTrace = debugger->stackTrace(); + while (!m_expressionRequests.isEmpty()) { + ExpressionRequest request = m_expressionRequests.takeFirst(); + QVariantMap result; + collector.setDestination(&result); + debugger->evaluateExpression(request.frameNr, request.expression, &collector); + m_expressionResults << result[QString::fromLatin1("body")]; + } + if (m_captureContextInfo) captureContextInfo(debugger); @@ -233,6 +241,13 @@ public: QList<QVariantMap> m_capturedLocals; QVariant m_thrownValue; + struct ExpressionRequest { + QString expression; + int frameNr; + }; + QVector<ExpressionRequest> m_expressionRequests; + QVector<QVariant> m_expressionResults; + // Utility methods: void dumpStackTrace() const { @@ -269,6 +284,8 @@ private slots: // exceptions: void pauseOnThrow(); + void evaluateExpression(); + private: void evaluateJavaScript(const QString &script, const QString &fileName, int lineNumber = 1) { @@ -556,6 +573,33 @@ void tst_qv4debugger::pauseOnThrow() QCOMPARE(m_debuggerAgent->m_thrownValue.toString(), QString("hard")); } +void tst_qv4debugger::evaluateExpression() +{ + QString script = + "function testFunction() {\n" + " var x = 10\n" + " return x\n" // breakpoint + "}\n" + "var x = 20\n" + "testFunction()\n"; + + TestAgent::ExpressionRequest request; + request.expression = "x"; + request.frameNr = 0; + m_debuggerAgent->m_expressionRequests << request; + request.expression = "x"; + request.frameNr = 1; + m_debuggerAgent->m_expressionRequests << request; + + m_debuggerAgent->addBreakPoint("evaluateExpression", 3); + + evaluateJavaScript(script, "evaluateExpression"); + + QCOMPARE(m_debuggerAgent->m_expressionResults.count(), 2); + QCOMPARE(m_debuggerAgent->m_expressionResults[0].toInt(), 10); + QCOMPARE(m_debuggerAgent->m_expressionResults[1].toInt(), 20); +} + QTEST_MAIN(tst_qv4debugger) #include "tst_qv4debugger.moc" |