From eae5a20b099450985442c70186fd7a7be442f133 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 30 Nov 2015 12:04:59 +0100 Subject: V4 Debugger: Allow expression evaluation without pausing We can schedule jobs into the GUI thread just fine, even if the debugger is running. They will run in global scope then. The only restriction is that we need exactly one engine to be running in order to do that, as otherwise we cannot decide which engine to use. To avoid interaction with the engine from the debugger thread we move the value lookup functionality into the data collector, and drop the RefHolder. Change-Id: Ifae124d70f42e488ed9a1b6794baef638992ddb1 Reviewed-by: Simon Hausmann --- .../qml/debugger/qv4debugger/tst_qv4debugger.cpp | 46 +++++++++------------- 1 file changed, 19 insertions(+), 27 deletions(-) (limited to 'tests/auto/qml/debugger') diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp index c5fa6be7a0..70883047c8 100644 --- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp +++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp @@ -104,11 +104,8 @@ public: typedef QV4DataCollector::Refs Refs; typedef QV4DataCollector::Ref Ref; struct NamedRefs { - NamedRefs(QV4DataCollector *collector = 0): collector(collector) {} - QStringList names; - Refs refs; - QV4DataCollector *collector; + QJsonArray refs; int size() const { Q_ASSERT(names.size() == refs.size()); @@ -126,7 +123,7 @@ public: QJsonObject rawValue(const QString &name) const { Q_ASSERT(contains(name)); - return collector->lookupRef(refs.at(names.indexOf(name))); + return refs.at(names.indexOf(name)).toObject(); } QJsonValue value(const QString &name) const { @@ -143,7 +140,7 @@ public: return; } - QJsonObject o = collector->lookupRef(refs.at(names.indexOf(name))); + QJsonObject o = refs.at(names.indexOf(name)).toObject(); QJsonDocument d; d.setObject(o); qDebug() << name << "=" << d.toJson(QJsonDocument::Indented); @@ -168,14 +165,10 @@ public slots: m_pauseReason = reason; m_statesWhenPaused << debugger->currentExecutionState(); - if (debugger->state() == QV4Debugger::Paused && - debugger->engine()->hasException) { - Refs refs; - RefHolder holder(&collector, &refs); + if (debugger->state() == QV4Debugger::Paused && debugger->engine()->hasException) { ExceptionCollectJob job(debugger->engine(), &collector); debugger->runInEngine(&job); - Q_ASSERT(refs.size() > 0); - m_thrownValue = refs.first(); + m_thrownValue = job.exceptionValue(); } foreach (const TestBreakPoint &bp, m_breakPointsToAddWhenPaused) @@ -187,11 +180,11 @@ public slots: while (!m_expressionRequests.isEmpty()) { Q_ASSERT(debugger->state() == QV4Debugger::Paused); ExpressionRequest request = m_expressionRequests.takeFirst(); - m_expressionResults << Refs(); - RefHolder holder(&collector, &m_expressionResults.last()); ExpressionEvalJob job(debugger->engine(), request.frameNr, request.expression, &collector); debugger->runInEngine(&job); + m_expressionResults << job.returnValue(); + m_expressionRefs << job.refs(); } if (m_captureContextInfo) @@ -213,17 +206,17 @@ public: void captureContextInfo(QV4Debugger *debugger) { for (int i = 0, ei = m_stackTrace.size(); i != ei; ++i) { - m_capturedArguments.append(NamedRefs(&collector)); - RefHolder argHolder(&collector, &m_capturedArguments.last().refs); + m_capturedArguments.append(NamedRefs()); ArgumentCollectJob argumentsJob(debugger->engine(), &collector, &m_capturedArguments.last().names, i, 0); debugger->runInEngine(&argumentsJob); + m_capturedArguments.last().refs = collector.flushCollectedRefs(); - m_capturedLocals.append(NamedRefs(&collector)); - RefHolder localHolder(&collector, &m_capturedLocals.last().refs); + m_capturedLocals.append(NamedRefs()); LocalCollectJob localsJob(debugger->engine(), &collector, &m_capturedLocals.last().names, i, 0); debugger->runInEngine(&localsJob); + m_capturedLocals.last().refs = collector.flushCollectedRefs(); } } @@ -250,7 +243,8 @@ public: int frameNr; }; QVector m_expressionRequests; - QVector m_expressionResults; + QList m_expressionResults; + QList m_expressionRefs; QV4Debugger *m_debugger; // Utility methods: @@ -578,7 +572,7 @@ void tst_qv4debugger::readObject() QCOMPARE(b_tail.value("name").toString(), QStringLiteral("tail")); QVERIFY(b_tail.contains("ref")); - QJsonObject b_tail_value = frame0.collector->lookupRef(b_tail.value("ref").toInt()); + QJsonObject b_tail_value = m_debuggerAgent->collector.lookupRef(b_tail.value("ref").toInt()); QCOMPARE(b_tail_value.value("type").toString(), QStringLiteral("object")); QVERIFY(b_tail_value.contains("properties")); QJsonArray b_tail_props = b_tail_value.value("properties").toArray(); @@ -711,15 +705,13 @@ void tst_qv4debugger::evaluateExpression() evaluateJavaScript(script, "evaluateExpression"); - QCOMPARE(m_debuggerAgent->m_expressionResults.count(), 2); - QCOMPARE(m_debuggerAgent->m_expressionResults[0].size(), 1); - QJsonObject result0 = - m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_expressionResults[0].first()); + QCOMPARE(m_debuggerAgent->m_expressionRefs.count(), 2); + QCOMPARE(m_debuggerAgent->m_expressionRefs[0].size(), 1); + QJsonObject result0 = m_debuggerAgent->m_expressionRefs[0].first().toObject(); QCOMPARE(result0.value("type").toString(), QStringLiteral("number")); QCOMPARE(result0.value("value").toInt(), 10); - QCOMPARE(m_debuggerAgent->m_expressionResults[1].size(), 1); - QJsonObject result1 = - m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_expressionResults[1].first()); + QCOMPARE(m_debuggerAgent->m_expressionRefs[1].size(), 1); + QJsonObject result1 = m_debuggerAgent->m_expressionRefs[1].first().toObject(); QCOMPARE(result1.value("type").toString(), QStringLiteral("number")); QCOMPARE(result1.value("value").toInt(), 20); } -- cgit v1.2.3