aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4debugging.cpp32
-rw-r--r--tests/auto/qml/qv4debugger/tst_qv4debugger.cpp44
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"