aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-02-25 13:02:22 +0100
committerUlf Hermann <ulf.hermann@qt.io>2022-03-03 13:35:48 +0100
commit6efb9946cf43a369e71fa182da97d7510d86579f (patch)
treebf697e34013d7c41eb06724bd112dfd489f137b6
parent8272eef2d736351d2ba41590680da395647a874e (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.cpp6
-rw-r--r--src/qmlcompiler/qqmljsregistercontent_p.h3
-rw-r--r--src/qmlcompiler/qqmljstypepropagator.cpp6
-rw-r--r--src/qmlcompiler/qqmljstyperesolver.cpp8
-rw-r--r--src/qmlcompiler/qqmljstyperesolver_p.h2
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 &reg,
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 &reg,
const QQmlJSScope::ConstPtr &type) const;