Blob Blame History Raw
From 6371b208a9e55845090dcd34234e314c6587c105 Mon Sep 17 00:00:00 2001
From: Simon Hausmann <simon.hausmann@theqtcompany.com>
Date: Tue, 17 May 2016 15:18:12 +0200
Subject: [PATCH 07/40] Revert "Remove this piece of code"

This reverts commit bad007360a0f6fba304d8f4c99826a1250fd886c.

The lookup in the global object is necessary to detect whether we've seen any
unresolved properties. This is used for the optimization of skipping binding
refresh updates when a context property changes.

Task-number: QTBUG-53431
Change-Id: Idb39a32e4b58b915496bbb9d8a098dc17a6f688a
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
---
 src/qml/qml/qqmlcontextwrapper.cpp              | 13 +++++++++++--
 tests/auto/qml/qqmlcontext/data/qtbug_53431.qml |  7 +++++++
 tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp  | 14 ++++++++++++++
 3 files changed, 32 insertions(+), 2 deletions(-)
 create mode 100644 tests/auto/qml/qqmlcontext/data/qtbug_53431.qml

diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp
index 0d84c3b..e3770a7 100644
--- a/src/qml/qml/qqmlcontextwrapper.cpp
+++ b/src/qml/qml/qqmlcontextwrapper.cpp
@@ -99,14 +99,23 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr
     QV4::ExecutionEngine *v4 = resource->engine();
     QV4::Scope scope(v4);
 
+    // In V8 the JS global object would come _before_ the QML global object,
+    // so simulate that here.
+    bool hasProp;
+    QV4::ScopedValue result(scope, v4->globalObject->get(name, &hasProp));
+    if (hasProp) {
+        if (hasProperty)
+            *hasProperty = hasProp;
+        return result->asReturnedValue();
+    }
+
     if (resource->d()->isNullWrapper)
         return Object::get(m, name, hasProperty);
 
     if (v4->callingQmlContext() != resource->d()->context)
         return Object::get(m, name, hasProperty);
 
-    bool hasProp;
-    QV4::ScopedValue result(scope, Object::get(m, name, &hasProp));
+    result = Object::get(m, name, &hasProp);
     if (hasProp) {
         if (hasProperty)
             *hasProperty = hasProp;
diff --git a/tests/auto/qml/qqmlcontext/data/qtbug_53431.qml b/tests/auto/qml/qqmlcontext/data/qtbug_53431.qml
new file mode 100644
index 0000000..2ceee2b
--- /dev/null
+++ b/tests/auto/qml/qqmlcontext/data/qtbug_53431.qml
@@ -0,0 +1,7 @@
+import QtQml 2.0
+QtObject {
+    property int value: {
+        console.log("lookup in global object")
+        return 1
+    }
+}
diff --git a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
index 18ef7ac..d338e6f 100644
--- a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
+++ b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
@@ -61,6 +61,7 @@ private slots:
     void refreshExpressions();
     void refreshExpressionsCrash();
     void refreshExpressionsRootContext();
+    void skipExpressionRefresh_qtbug_53431();
 
     void qtbug_22535();
     void evalAfterInvalidate();
@@ -642,6 +643,19 @@ void tst_qqmlcontext::refreshExpressionsRootContext()
     delete o1;
 }
 
+void tst_qqmlcontext::skipExpressionRefresh_qtbug_53431()
+{
+    QQmlEngine engine;
+    QQmlComponent component(&engine, testFileUrl("qtbug_53431.qml"));
+    QScopedPointer<QObject> object(component.create(0));
+    QVERIFY(!object.isNull());
+    QCOMPARE(object->property("value").toInt(), 1);
+    object->setProperty("value", 10);
+    QCOMPARE(object->property("value").toInt(), 10);
+    engine.rootContext()->setContextProperty("randomContextProperty", 42);
+    QCOMPARE(object->property("value").toInt(), 10);
+}
+
 void tst_qqmlcontext::qtbug_22535()
 {
     QQmlEngine engine;
-- 
1.9.3