aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-03-16 14:51:15 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2018-03-17 10:29:44 +0000
commit61447075954aab99b3abc9c78294e5966ae3b6ce (patch)
tree68192e06f529b2f2613d2541ea6063fa6fcba8ec
parent80b5f8c2f448be574e731e5d371c38b84578f5c3 (diff)
Pass "this" object when evaluating debug jobs
We have to explicitly specify the "this" object on QV4::Function::call, otherwise it will assume undefined or the QML global object. Task-number: QTBUG-66942 Change-Id: I1af7742b4fee1b49e9760a413834daf3edb15d74 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp10
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp10
-rw-r--r--src/qml/jsruntime/qv4script.cpp7
-rw-r--r--src/qml/jsruntime/qv4script_p.h2
-rw-r--r--tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp32
5 files changed, 53 insertions, 8 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
index 5b049ab521..7950d21612 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
@@ -112,8 +112,14 @@ void JavaScriptJob::run()
script.inheritContext = true;
script.parse();
QV4::ScopedValue result(scope);
- if (!scope.engine->hasException)
- result = script.run();
+ if (!scope.engine->hasException) {
+ if (frame) {
+ QV4::ScopedValue thisObject(scope, frame->thisObject());
+ result = script.run(thisObject);
+ } else {
+ result = script.run();
+ }
+ }
if (scope.engine->hasException) {
result = scope.engine->catchException();
resultIsException = true;
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
index 718975275a..e17fe92983 100644
--- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
@@ -260,8 +260,14 @@ QV4::ReturnedValue NativeDebugger::evaluateExpression(const QString &expression)
// That is a side-effect of inheritContext.
script.inheritContext = true;
script.parse();
- if (!m_engine->hasException)
- return script.run();
+ if (!m_engine->hasException) {
+ if (m_engine->currentStackFrame) {
+ QV4::ScopedValue thisObject(scope, m_engine->currentStackFrame->thisObject());
+ script.run(thisObject);
+ } else {
+ script.run();
+ }
+ }
m_runningJob = false;
return QV4::Encode::undefined();
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index bb6608bec0..267c93952d 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -136,7 +136,7 @@ void Script::parse()
}
}
-ReturnedValue Script::run()
+ReturnedValue Script::run(const QV4::Value *thisObject)
{
if (!parsed)
parse();
@@ -149,10 +149,11 @@ ReturnedValue Script::run()
if (qmlContext.isUndefined()) {
TemporaryAssignment<Function*> savedGlobalCode(engine->globalCode, vmFunction);
- return vmFunction->call(engine->globalObject, nullptr, 0, context);
+ return vmFunction->call(thisObject ? thisObject : engine->globalObject, nullptr, 0,
+ context);
} else {
Scoped<QmlContext> qml(valueScope, qmlContext.value());
- return vmFunction->call(nullptr, nullptr, 0, qml);
+ return vmFunction->call(thisObject, nullptr, 0, qml);
}
}
diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h
index 24291b9aa6..cb03c6b064 100644
--- a/src/qml/jsruntime/qv4script_p.h
+++ b/src/qml/jsruntime/qv4script_p.h
@@ -93,7 +93,7 @@ struct Q_QML_EXPORT Script {
bool parseAsBinding;
void parse();
- ReturnedValue run();
+ ReturnedValue run(const QV4::Value *thisObject = nullptr);
Function *function();
diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
index 5dd62da15a..4ce0f9fd89 100644
--- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
@@ -316,6 +316,8 @@ private slots:
void lastLineOfConditional_data();
void lastLineOfConditional();
+
+ void readThis();
private:
QV4Debugger *debugger() const
{
@@ -865,6 +867,36 @@ void tst_qv4debugger::lastLineOfConditional()
QCOMPARE(secondState.lineNumber, lastLine);
}
+void tst_qv4debugger::readThis()
+{
+ m_debuggerAgent->m_captureContextInfo = true;
+ QString script =
+ "var x = function() {\n"
+ " return this.a;\n"
+ "}.apply({a : 5}, []);\n";
+
+ TestAgent::ExpressionRequest request;
+ request.expression = "this";
+ request.frameNr = 0;
+ request.context = -1; // no extra context
+ m_debuggerAgent->m_expressionRequests << request;
+
+ debugger()->addBreakPoint("applyThis", 2);
+ evaluateJavaScript(script, "applyThis");
+ QVERIFY(m_debuggerAgent->m_wasPaused);
+
+ QCOMPARE(m_debuggerAgent->m_expressionResults.count(), 1);
+ QJsonObject result0 = m_debuggerAgent->m_expressionResults[0];
+ QCOMPARE(result0.value("type").toString(), QStringLiteral("object"));
+ QCOMPARE(result0.value("value").toInt(), 1);
+ QJsonArray properties = result0.value("properties").toArray();
+ QCOMPARE(properties.size(), 1);
+ QJsonObject a = properties.first().toObject();
+ QCOMPARE(a.value("name").toString(), QStringLiteral("a"));
+ QCOMPARE(a.value("type").toString(), QStringLiteral("number"));
+ QCOMPARE(a.value("value").toInt(), 5);
+}
+
void tst_qv4debugger::redundancy_data()
{
QTest::addColumn<bool>("redundantRefs");