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>
This commit is contained in:
parent
91a71bce9c
commit
01f9c623ed
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
}
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue