summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2019-02-13 09:17:10 +0100
committerUlf Hermann <ulf.hermann@qt.io>2019-02-13 10:52:32 +0000
commit01f9c623ed2dc1645ac022d69062f720e3b50132 (patch)
tree9f803a8294c509326909388288c970a3f11313aa
parent91a71bce9c633934540e9f06fb081e3b89259ff3 (diff)
downloadqtdeclarative-01f9c623ed2dc1645ac022d69062f720e3b50132.tar.gz
Don't optimize global lookups if fast QML lookups are disabled
If fast QML lookups are disabled, we generally want to look up by string. If the name then happens to be a member of the global JavaScript object, we still don't want to directly access that, as the name could have been overridden in a deeper context. Fixes: QTBUG-73750 Change-Id: Id16110969123d91501064ba46bfad4c2a39e4650 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h1
-rw-r--r--src/qml/compiler/qv4codegen.cpp2
-rw-r--r--src/qml/compiler/qv4codegen_p.h4
-rw-r--r--tests/auto/qml/qqmlconnections/data/override-proxy-type.qml13
-rw-r--r--tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp25
5 files changed, 43 insertions, 2 deletions
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index 3dde929cc4..1a3ca4163e 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -622,6 +622,7 @@ struct Q_QML_PRIVATE_EXPORT JSCodeGen : public QV4::Compiler::Codegen
protected:
void beginFunctionBodyHook() override;
+ bool canAccelerateGlobalLookups() const override { return !_disableAcceleratedLookups; }
Reference fallbackNameLookup(const QString &name) override;
private:
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index fb3c66b123..04da41430c 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -2404,7 +2404,7 @@ Codegen::Reference Codegen::referenceForName(const QString &name, bool isLhs, co
Reference r = Reference::fromName(this, name);
r.global = useFastLookups && (resolved.type == Context::ResolvedName::Global);
- if (!r.global && m_globalNames.contains(name))
+ if (!r.global && canAccelerateGlobalLookups() && m_globalNames.contains(name))
r.global = true;
return r;
}
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index 3f96afc7c2..4d7001fe64 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -561,8 +561,10 @@ protected:
Reference referenceForPropertyName(const Codegen::Reference &object, AST::PropertyName *name);
- // Hook provided to implement QML lookup semantics
+ // Hooks provided to implement QML lookup semantics
+ virtual bool canAccelerateGlobalLookups() const { return true; }
virtual Reference fallbackNameLookup(const QString &name);
+
virtual void beginFunctionBodyHook() {}
void emitReturn(const Reference &expr);
diff --git a/tests/auto/qml/qqmlconnections/data/override-proxy-type.qml b/tests/auto/qml/qqmlconnections/data/override-proxy-type.qml
new file mode 100644
index 0000000000..80e459966b
--- /dev/null
+++ b/tests/auto/qml/qqmlconnections/data/override-proxy-type.qml
@@ -0,0 +1,13 @@
+import QtQml 2.12
+import test.proxy 1.0
+
+Proxy {
+ property int testEnum: 0;
+ id: proxy
+ property Connections connections: Connections {
+ target: proxy
+ onSomeSignal: testEnum = Proxy.EnumValue;
+ }
+
+ Component.onCompleted: someSignal()
+}
diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
index 8ef00f8080..dc29363fcf 100644
--- a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
+++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
@@ -55,6 +55,7 @@ private slots:
void disabledAtStart();
void clearImplicitTarget();
void onWithoutASignal();
+ void noAcceleratedGlobalLookup();
private:
QQmlEngine engine;
@@ -407,6 +408,30 @@ void tst_qqmlconnections::onWithoutASignal()
QVERIFY(item == nullptr); // should parse error, and not give us an item (or crash).
}
+class Proxy : public QObject
+{
+ Q_OBJECT
+public:
+ enum MyEnum { EnumValue = 20, AnotherEnumValue };
+ Q_ENUM(MyEnum)
+
+signals:
+ void someSignal();
+};
+
+void tst_qqmlconnections::noAcceleratedGlobalLookup()
+{
+ qRegisterMetaType<Proxy::MyEnum>();
+ qmlRegisterType<Proxy>("test.proxy", 1, 0, "Proxy");
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("override-proxy-type.qml"));
+ QVERIFY(c.isReady());
+ QScopedPointer<QObject> object(c.create());
+ const QVariant val = object->property("testEnum");
+ QCOMPARE(val.type(), QMetaType::Int);
+ QCOMPARE(val.toInt(), int(Proxy::EnumValue));
+}
+
QTEST_MAIN(tst_qqmlconnections)
#include "tst_qqmlconnections.moc"