diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2022-06-29 14:01:22 +0200 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-07-05 19:50:24 +0200 |
| commit | 7d36ec0bd9cd4747dbf33e92b8188fe25c295b88 (patch) | |
| tree | 10d69c518b60035c618c425f35b0b9f58bc6200a /src | |
| parent | 46396070368568d44597a36b7c7646f139d92b23 (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.cpp | 44 |
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); } |
