diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2022-02-25 13:02:22 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-03-03 13:35:48 +0100 |
commit | 6efb9946cf43a369e71fa182da97d7510d86579f (patch) | |
tree | bf697e34013d7c41eb06724bd112dfd489f137b6 | |
parent | 8272eef2d736351d2ba41590680da395647a874e (diff) |
QmlCompiler: Don't generate code for untyped JS calls
This is inefficient.
Task-number: QTBUG-101285
Change-Id: Iec7f02b4b95cb788c710a3634c2344843b125030
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
(cherry picked from commit 6e8f6f446ac8854fd23cb3cbf0fc1f3646299ca6)
-rw-r--r-- | src/qmlcompiler/qqmljscodegenerator.cpp | 6 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsregistercontent_p.h | 3 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljstypepropagator.cpp | 6 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljstyperesolver.cpp | 8 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljstyperesolver_p.h | 2 |
5 files changed, 23 insertions, 2 deletions
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp index 1c988ffc01..7e2748f2bc 100644 --- a/src/qmlcompiler/qqmljscodegenerator.cpp +++ b/src/qmlcompiler/qqmljscodegenerator.cpp @@ -1412,6 +1412,9 @@ void QQmlJSCodeGenerator::generate_CallPropertyLookup(int index, int base, int a { INJECT_TRACE_INFO(generate_CallPropertyLookup); + if (m_state.accumulatorOut.variant() == QQmlJSRegisterContent::JavaScriptReturnValue) + reject(u"call to untyped JavaScript function"_qs); + const QQmlJSRegisterContent baseType = registerType(base); if (baseType.storedType()->accessSemantics() != QQmlJSScope::AccessSemantics::Reference) { const QString name = m_jsUnitGenerator->stringForIndex( @@ -1479,6 +1482,9 @@ void QQmlJSCodeGenerator::generate_CallQmlContextPropertyLookup(int index, int a { INJECT_TRACE_INFO(generate_CallQmlContextPropertyLookup); + if (m_state.accumulatorOut.variant() == QQmlJSRegisterContent::JavaScriptReturnValue) + reject(u"call to untyped JavaScript function"_qs); + m_body.setHasSideEffects(true); const QString indexString = QString::number(index); diff --git a/src/qmlcompiler/qqmljsregistercontent_p.h b/src/qmlcompiler/qqmljsregistercontent_p.h index 174eeeb3bc..00e47ebe73 100644 --- a/src/qmlcompiler/qqmljsregistercontent_p.h +++ b/src/qmlcompiler/qqmljsregistercontent_p.h @@ -77,6 +77,9 @@ public: ExtensionObjectMethod, ExtensionObjectEnum, + MethodReturnValue, + JavaScriptReturnValue, + ListValue, Builtin, Unknown, diff --git a/src/qmlcompiler/qqmljstypepropagator.cpp b/src/qmlcompiler/qqmljstypepropagator.cpp index 5945aa4584..a0e49d9c59 100644 --- a/src/qmlcompiler/qqmljstypepropagator.cpp +++ b/src/qmlcompiler/qqmljstypepropagator.cpp @@ -909,8 +909,10 @@ void QQmlJSTypePropagator::propagateCall(const QList<QQmlJSMetaMethod> &methods, const auto returnType = match.isJavaScriptFunction() ? m_typeResolver->jsValueType() : QQmlJSScope::ConstPtr(match.returnType()); - m_state.accumulatorOut = m_typeResolver->globalType( - returnType ? QQmlJSScope::ConstPtr(returnType) : m_typeResolver->voidType()); + m_state.accumulatorOut = m_typeResolver->returnType( + returnType ? QQmlJSScope::ConstPtr(returnType) : m_typeResolver->voidType(), + match.isJavaScriptFunction() ? QQmlJSRegisterContent::JavaScriptReturnValue + : QQmlJSRegisterContent::MethodReturnValue); if (!m_state.accumulatorOut.isValid()) setError(u"Cannot store return type of method %1()."_qs.arg(match.methodName())); } diff --git a/src/qmlcompiler/qqmljstyperesolver.cpp b/src/qmlcompiler/qqmljstyperesolver.cpp index f872526d6b..f532e063a2 100644 --- a/src/qmlcompiler/qqmljstyperesolver.cpp +++ b/src/qmlcompiler/qqmljstyperesolver.cpp @@ -945,6 +945,14 @@ QQmlJSRegisterContent QQmlJSTypeResolver::valueType(const QQmlJSRegisterContent return QQmlJSRegisterContent::create(stored, property, QQmlJSRegisterContent::ListValue, scope); } +QQmlJSRegisterContent QQmlJSTypeResolver::returnType( + const QQmlJSScope::ConstPtr &type, QQmlJSRegisterContent::ContentVariant variant) const +{ + Q_ASSERT(variant == QQmlJSRegisterContent::MethodReturnValue + || variant == QQmlJSRegisterContent::JavaScriptReturnValue); + return QQmlJSRegisterContent::create(storedType(type), type, variant); +} + bool QQmlJSTypeResolver::registerContains(const QQmlJSRegisterContent ®, const QQmlJSScope::ConstPtr &type) const { diff --git a/src/qmlcompiler/qqmljstyperesolver_p.h b/src/qmlcompiler/qqmljstyperesolver_p.h index 96f19a8b33..c2c682b8ff 100644 --- a/src/qmlcompiler/qqmljstyperesolver_p.h +++ b/src/qmlcompiler/qqmljstyperesolver_p.h @@ -122,6 +122,8 @@ public: QQmlJSRegisterContent scopedType(const QQmlJSScope::ConstPtr &scope, const QString &name) const; QQmlJSRegisterContent memberType(const QQmlJSRegisterContent &type, const QString &name) const; QQmlJSRegisterContent valueType(const QQmlJSRegisterContent &listType) const; + QQmlJSRegisterContent returnType(const QQmlJSScope::ConstPtr &type, + QQmlJSRegisterContent::ContentVariant variant) const; bool registerContains(const QQmlJSRegisterContent ®, const QQmlJSScope::ConstPtr &type) const; |