diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2019-02-13 09:17:10 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-02-13 10:52:32 +0000 |
commit | 01f9c623ed2dc1645ac022d69062f720e3b50132 (patch) | |
tree | 9f803a8294c509326909388288c970a3f11313aa | |
parent | 91a71bce9c633934540e9f06fb081e3b89259ff3 (diff) |
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.h | 1 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen_p.h | 4 | ||||
-rw-r--r-- | tests/auto/qml/qqmlconnections/data/override-proxy-type.qml | 13 | ||||
-rw-r--r-- | tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp | 25 |
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" |