From 2f4b8f159545b545d4b49cb3c1429c09522519ee Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 29 May 2018 14:27:46 +0200 Subject: Formals come after locals in the CallContext The method updating the internal class for a CallContext messed up the order between locals and formals, leading to wrong name lookups for signal handlers taking implicit arguments Task-number: QTBUG-68522 Change-Id: I36d55b3b0cfe9af6397455782551498b7ddb940a Reviewed-by: Lars Knoll Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4function.cpp | 9 ++++---- tests/auto/qml/qqmlengine/tst_qqmlengine.cpp | 32 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index 83e861138b..6fca9ecd45 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -112,6 +112,11 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QListinternalClasses[EngineBase::Class_CallContext]; + // first locals + const quint32_le *localsIndices = compiledFunction->localsTable(); + for (quint32 i = 0; i < compiledFunction->nLocals; ++i) + internalClass = internalClass->addMember(engine->identifierTable->identifier(compilationUnit->runtimeStrings[localsIndices[i]]), Attr_NotConfigurable); + Scope scope(engine); ScopedString arg(scope); for (const QString ¶meterName : parameterNames) { @@ -119,10 +124,6 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QListaddMember(arg, Attr_NotConfigurable); } nFormals = parameters.size(); - - const quint32_le *localsIndices = compiledFunction->localsTable(); - for (quint32 i = 0; i < compiledFunction->nLocals; ++i) - internalClass = internalClass->addMember(engine->identifierTable->identifier(compilationUnit->runtimeStrings[localsIndices[i]]), Attr_NotConfigurable); } QT_END_NAMESPACE diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp index 6ae786469d..95098648fa 100644 --- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp +++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp @@ -78,6 +78,7 @@ private slots: void testGroupedPropertyRevisions(); void componentFromEval(); void qrcUrls(); + void cppSignalAndEval(); public slots: QObject *createAQObjectForOwnershipTest () @@ -924,6 +925,37 @@ void tst_qqmlengine::qrcUrls() } } +class ObjectCaller : public QObject +{ + Q_OBJECT +signals: + void doubleReply(const double a); +}; + +void tst_qqmlengine::cppSignalAndEval() +{ + ObjectCaller objectCaller; + QQmlEngine engine; + engine.rootContext()->setContextProperty(QLatin1Literal("CallerCpp"), &objectCaller); + QQmlComponent c(&engine); + c.setData("import QtQuick 2.9\n" + "Item {\n" + " property var r: 0\n" + " Connections {\n" + " target: CallerCpp;\n" + " onDoubleReply: {\n" + " eval('var z = 1');\n" + " r = a;\n" + " }\n" + " }\n" + "}", + QUrl(QStringLiteral("qrc:/main.qml"))); + QScopedPointer object(c.create()); + QVERIFY(!object.isNull()); + emit objectCaller.doubleReply(1.1234); + QCOMPARE(object->property("r"), 1.1234); +} + QTEST_MAIN(tst_qqmlengine) #include "tst_qqmlengine.moc" -- cgit v1.2.3