summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-05-09 12:00:03 +0200
committerUlf Hermann <ulf.hermann@qt.io>2023-05-11 08:04:02 +0200
commit2316da3a800428d41432a052280ea0cd26465c2c (patch)
tree058448cf0b0360f83c7a672052ddc590c3c74ad0
parent60a34c33934e264e42d7aef00500f5ebf7f03bff (diff)
downloadqtdeclarative-2316da3a800428d41432a052280ea0cd26465c2c.tar.gz
QmlCompiler: Improve argument construction in generated code
We don't have to pass types that don't fit if we actually have the correct types in suitable wrappers. This still invokes the internal conversions of the call frame setup if we call with really generic types, for example if the same value is read multiple times with different target types. However, that is acceptable. Fixes: QTBUG-113465 Change-Id: I8ec4afeb39bbe6585e5268c0e9b0cfd2788d761a Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/qml/jsapi/qjsprimitivevalue.cpp11
-rw-r--r--src/qml/jsapi/qjsprimitivevalue.h27
-rw-r--r--src/qmlcompiler/qqmljscodegenerator.cpp45
3 files changed, 55 insertions, 28 deletions
diff --git a/src/qml/jsapi/qjsprimitivevalue.cpp b/src/qml/jsapi/qjsprimitivevalue.cpp
index 3ab2ade0dc..0bef52b5d8 100644
--- a/src/qml/jsapi/qjsprimitivevalue.cpp
+++ b/src/qml/jsapi/qjsprimitivevalue.cpp
@@ -146,6 +146,17 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn QJSPrimitiveValue::QJSPrimitiveValue(QMetaType type)
+ \since 6.6
+ \internal
+
+ Creates a QJSPrimitiveValue of type \a type, and initializes with a
+ default-constructed value if \a type can be stored in QJSPrimtiveValue.
+ If \a type cannot be stored this results in a QJSPrimitiveValue of type
+ Undefined.
+*/
+
+/*!
\fn QJSPrimitiveValue::QJSPrimitiveValue(const QVariant &value)
Creates a QJSPrimitiveValue from the contents of \a value if those contents
diff --git a/src/qml/jsapi/qjsprimitivevalue.h b/src/qml/jsapi/qjsprimitivevalue.h
index bb710eb31b..1f41743f65 100644
--- a/src/qml/jsapi/qjsprimitivevalue.h
+++ b/src/qml/jsapi/qjsprimitivevalue.h
@@ -163,6 +163,33 @@ public:
}
}
+ explicit QJSPrimitiveValue(const QMetaType type) noexcept
+ {
+ switch (type.id()) {
+ case QMetaType::UnknownType:
+ d = QJSPrimitiveUndefined();
+ break;
+ case QMetaType::Nullptr:
+ d = QJSPrimitiveNull();
+ break;
+ case QMetaType::Bool:
+ d = false;
+ break;
+ case QMetaType::Int:
+ d = 0;
+ break;
+ case QMetaType::Double:
+ d = 0.0;
+ break;
+ case QMetaType::QString:
+ d = QString();
+ break;
+ default:
+ // Unsupported. Remains undefined.
+ break;
+ }
+ }
+
explicit QJSPrimitiveValue(const QVariant &variant) noexcept
: QJSPrimitiveValue(variant.metaType(), variant.data())
{
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp
index c1df2d9cca..810ed90cc9 100644
--- a/src/qmlcompiler/qqmljscodegenerator.cpp
+++ b/src/qmlcompiler/qqmljscodegenerator.cpp
@@ -1316,7 +1316,6 @@ QString QQmlJSCodeGenerator::argumentsList(int argc, int argv, QString *outVar)
{
QString types;
QString args;
- QString conversions;
if (m_state.changedRegisterIndex() == InvalidRegister ||
m_typeResolver->registerContains(
@@ -1326,39 +1325,29 @@ QString QQmlJSCodeGenerator::argumentsList(int argc, int argv, QString *outVar)
} else {
*outVar = u"callResult"_s;
const QQmlJSScope::ConstPtr outType = m_state.accumulatorOut().storedType();
- m_body += outType->internalName();
- if (outType->accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
- m_body += u" *"_s;
- else
- m_body += u' ';
- m_body += *outVar + u";\n";
+ m_body += outType->augmentedInternalName() + u' ' + *outVar;
+ if (!m_typeResolver->registerContains(m_state.accumulatorOut(), outType)) {
+ if (m_typeResolver->equals(outType, m_typeResolver->varType())
+ || m_typeResolver->equals(outType, m_typeResolver->jsPrimitiveType())) {
+ m_body += u'('
+ + metaType(m_typeResolver->containedType(m_state.accumulatorOut()))
+ + u')';
+ }
+ }
+ m_body += u";\n";
- types = metaTypeFromType(m_state.accumulatorOut().storedType());
- args = u'&' + *outVar;
+ args = contentPointer(m_state.accumulatorOut(), *outVar);
+ types = contentType(m_state.accumulatorOut(), *outVar);
}
for (int i = 0; i < argc; ++i) {
const QQmlJSRegisterContent content = registerType(argv + i);
- if (m_typeResolver->registerIsStoredIn(content, m_typeResolver->jsPrimitiveType())) {
- QString argName = u"arg"_s + QString::number(i);
- conversions += u"QVariant "_s + argName + u" = "_s
- + convertStored(content.storedType(), m_typeResolver->varType(),
- consumedRegisterVariable(argv + i)) + u";\n"_s;
- args += u", "_s + argName + u".data()"_s;
- types += u", "_s + argName + u".metaType()"_s;
- } else if (m_typeResolver->registerIsStoredIn(content, m_typeResolver->varType())
- && !m_typeResolver->registerContains(content, m_typeResolver->varType())) {
- const QString var = registerVariable(argv + i);
- args += u", "_s + var + u".data()"_s;
- types += u", "_s + var + u".metaType()"_s;
- } else {
- const QString var = registerVariable(argv + i);
- args += u", &"_s + var;
- types += u", "_s + metaTypeFromType(content.storedType());
- }
+ const QString var = registerVariable(argv + i);
+ args += u", "_s + contentPointer(content, var);
+ types += u", "_s + contentType(content, var);
}
- return conversions
- + u"void *args[] = { "_s + args + u" };\n"_s
+
+ return u"void *args[] = { "_s + args + u" };\n"_s
+ u"const QMetaType types[] = { "_s + types + u" };\n"_s;
}