aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-06-29 14:01:22 +0200
committerUlf Hermann <ulf.hermann@qt.io>2022-07-05 19:50:24 +0200
commit7d36ec0bd9cd4747dbf33e92b8188fe25c295b88 (patch)
tree10d69c518b60035c618c425f35b0b9f58bc6200a /src
parent46396070368568d44597a36b7c7646f139d92b23 (diff)
QmlCompiler: Don't push type conversions back into the engine
In many cases we can generate better code for type conversions. Furthermore, the engine only does QMetaType::convert(). This misses a lot of conversions we do in other places. Pick-to: 6.4 Change-Id: I1526ec327d189420885f6a7385f6cc1c2c94b19e Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qmlcompiler/qqmljscodegenerator.cpp44
1 files changed, 33 insertions, 11 deletions
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp
index 0514b29904..f3c2bfeffc 100644
--- a/src/qmlcompiler/qqmljscodegenerator.cpp
+++ b/src/qmlcompiler/qqmljscodegenerator.cpp
@@ -139,7 +139,6 @@ QT_WARNING_POP
const int registerIndex = registerIt.key();
const bool registerIsArgument = isArgument(registerIndex);
- const bool isReadonlyArgument = registerIsArgument && registerTypes.size() == 1;
for (auto registerTypeIt = registerTypes.constBegin(), end = registerTypes.constEnd();
registerTypeIt != end; ++registerTypeIt) {
@@ -149,24 +148,45 @@ QT_WARNING_POP
if (generatedVariables.hasSeen(registerTypeIt.value()))
continue;
- // We would like to make the variable a const ref if it's a readonly argument,
- // but due to the various call interfaces accepting non-const values, we can't.
- // We rely on those calls to still not modify their arguments in place.
-
result.code += storedType->internalName();
- if (storedType->accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
+ const bool isPointer
+ = (storedType->accessSemantics() == QQmlJSScope::AccessSemantics::Reference);
+ if (isPointer)
result.code += u" *"_s;
else
- result.code += isReadonlyArgument ? u" &"_s : u" "_s;
+ result.code += u' ';
- result.code += registerTypeIt.value();
if (registerIsArgument && m_typeResolver->registerIsStoredIn(
argumentType(registerIndex), storedType)) {
const int argumentIndex = registerIndex - FirstArgument;
- result.code += u" = " + u"*static_cast<"_s
- + castTargetName(m_function->argumentTypes[argumentIndex].storedType())
+ const QQmlJSScope::ConstPtr argument
+ = m_function->argumentTypes[argumentIndex].storedType();
+ const QQmlJSScope::ConstPtr original
+ = m_typeResolver->originalType(argument);
+
+ const bool needsConversion = argument != original;
+ if (!isPointer && registerTypes.size() == 1 && !needsConversion) {
+ // Not a pointer, never written to, and doesn't need any initial conversion.
+ // This is a readonly argument.
+ //
+ // We would like to make the variable a const ref if it's a readonly argument,
+ // but due to the various call interfaces accepting non-const values, we can't.
+ // We rely on those calls to still not modify their arguments in place.
+ result.code += u'&';
+ }
+
+ result.code += registerTypeIt.value() + u" = "_s;
+
+ const QString originalValue = u"*static_cast<"_s + castTargetName(original)
+ u"*>(argumentsPtr["_s + QString::number(argumentIndex) + u"])"_s;
+
+ if (needsConversion)
+ result.code += conversion(original, argument, originalValue);
+ else
+ result.code += originalValue;
+ } else {
+ result.code += registerTypeIt.value();
}
result.code += u";\n"_s;
}
@@ -176,7 +196,9 @@ QT_WARNING_POP
for (const QQmlJSRegisterContent &argType : qAsConst(function->argumentTypes)) {
if (argType.isValid()) {
- result.argumentTypes.append(argType.storedType()->augmentedInternalName());
+ result.argumentTypes.append(
+ m_typeResolver->originalType(argType.storedType())
+ ->augmentedInternalName());
} else {
result.argumentTypes.append(u"void"_s);
}