aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-02-24 16:36:14 +0100
committerUlf Hermann <ulf.hermann@qt.io>2022-03-02 22:50:35 +0100
commite14866222a4c07bd4b71344d4a83034e17c51984 (patch)
tree2a37d290e17b812e701860702c83aa2cfb4fe8bd
parent1ddf33ac4da4f34451393dfac6caae580e965fc7 (diff)
QmlCompiler: Optimize some more type conversions
Some of those make the compiled code slower than the interpreted code. That is bad enough of a bug to pick it back to 6.2. Fixes: QTBUG-100847 Change-Id: I823ff688d3aead364e21ae1e90e16a4bfaedb1f5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit dddd6a66ddd77d3887c52cb145e7e14b8fb542b9)
-rw-r--r--src/qmlcompiler/qqmljscodegenerator.cpp77
1 files changed, 67 insertions, 10 deletions
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp
index 644a1ec6fd..1c988ffc01 100644
--- a/src/qmlcompiler/qqmljscodegenerator.cpp
+++ b/src/qmlcompiler/qqmljscodegenerator.cpp
@@ -83,8 +83,13 @@ QString QQmlJSCodeGenerator::metaTypeFromName(const QQmlJSScope::ConstPtr &type)
QString QQmlJSCodeGenerator::metaObject(const QQmlJSScope::ConstPtr &objectType)
{
- if (!objectType->isComposite())
+ if (!objectType->isComposite()) {
+ if (objectType->internalName() == u"QtObject"_qs
+ || objectType->internalName() == u"QQmlComponent"_qs) {
+ return metaTypeFromType(objectType) + u".metaObject()"_qs;
+ }
return metaTypeFromName(objectType) + u".metaObject()"_qs;
+ }
reject(u"retrieving the metaObject of a composite type without using an instance."_qs);
return QString();
@@ -366,10 +371,8 @@ void QQmlJSCodeGenerator::eliminateDeadStores()
QString QQmlJSCodeGenerator::errorReturnValue() const
{
- if (m_function->returnType) {
- return conversion(m_typeResolver->jsPrimitiveType(), m_function->returnType,
- u"QJSPrimitiveValue(QJSPrimitiveUndefined())"_qs);
- }
+ if (m_function->returnType)
+ return conversion(m_typeResolver->voidType(), m_function->returnType, QString());
return QString();
}
@@ -2483,6 +2486,37 @@ QString QQmlJSCodeGenerator::conversion(const QQmlJSScope::ConstPtr &from,
// add a move(from, to, variable) function that implements the moves.
Q_ASSERT(!to->isComposite()); // We cannot directly convert to composites.
+ const auto jsValueType = m_typeResolver->jsValueType();
+ const auto varType = m_typeResolver->varType();
+ const auto jsPrimitiveType = m_typeResolver->jsPrimitiveType();
+ const auto boolType = m_typeResolver->boolType();
+
+ auto zeroBoolOrNumeric = [&](const QQmlJSScope::ConstPtr &to) {
+ if (to == boolType)
+ return u"false"_qs;
+ if (to == m_typeResolver->intType())
+ return u"0"_qs;
+ if (to == m_typeResolver->floatType())
+ return u"0.0f"_qs;
+ if (to == m_typeResolver->realType())
+ return u"0.0"_qs;
+ return QString();
+ };
+
+ if (from == m_typeResolver->voidType()) {
+ if (to->accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
+ return u"static_cast<"_qs + to->internalName() + u" *>(nullptr)"_qs;
+ const QString zero = zeroBoolOrNumeric(to);
+ if (!zero.isEmpty())
+ return zero;
+ if (to == m_typeResolver->stringType())
+ return QQmlJSUtils::toLiteral(u"undefined"_qs);
+ if (from == to)
+ return variable;
+ // Anything else is just the default constructed type.
+ return to->augmentedInternalName() + u"()"_qs;
+ }
+
if (from == to)
return variable;
@@ -2502,8 +2536,6 @@ QString QQmlJSCodeGenerator::conversion(const QQmlJSScope::ConstPtr &from,
}
}
- const auto jsValueType = m_typeResolver->jsValueType();
-
auto isJsValue = [&](const QQmlJSScope::ConstPtr &candidate) {
return candidate == jsValueType || candidate->isScript();
};
@@ -2511,7 +2543,6 @@ QString QQmlJSCodeGenerator::conversion(const QQmlJSScope::ConstPtr &from,
if (isJsValue(from) && isJsValue(to))
return variable;
- const auto boolType = m_typeResolver->boolType();
const auto isBoolOrNumber = [&](const QQmlJSScope::ConstPtr &type) {
return m_typeResolver->isNumeric(m_typeResolver->globalType(type))
|| type == m_typeResolver->boolType()
@@ -2524,8 +2555,6 @@ QString QQmlJSCodeGenerator::conversion(const QQmlJSScope::ConstPtr &from,
if (isBoolOrNumber(from) && isBoolOrNumber(to))
return to->internalName() + u'(' + variable + u')';
- const auto varType = m_typeResolver->varType();
- const auto jsPrimitiveType = m_typeResolver->jsPrimitiveType();
if (from == jsPrimitiveType) {
if (to == m_typeResolver->realType())
return variable + u".toDouble()"_qs;
@@ -2567,6 +2596,34 @@ QString QQmlJSCodeGenerator::conversion(const QQmlJSScope::ConstPtr &from,
if (to == varType)
return u"QVariant::fromValue("_qs + variable + u')';
+ if (from == m_typeResolver->urlType() && to == m_typeResolver->stringType())
+ return variable + u".toString()"_qs;
+
+ if (from == m_typeResolver->stringType() && to == m_typeResolver->urlType())
+ return u"QUrl("_qs + variable + u')';
+
+ const auto retrieveFromPrimitive = [&](const QQmlJSScope::ConstPtr &type) {
+ if (type == m_typeResolver->boolType())
+ return u".toBool()"_qs;
+ if (type == m_typeResolver->intType())
+ return u".toInteger()"_qs;
+ if (type == m_typeResolver->realType())
+ return u".toDouble()"_qs;
+ if (type == m_typeResolver->stringType())
+ return u".toString()"_qs;
+ return QString();
+ };
+
+ const auto fitsIntoPrimitive = [&](const QQmlJSScope::ConstPtr &type) {
+ return !retrieveFromPrimitive(type).isEmpty() || type == m_typeResolver->floatType();
+ };
+
+ if (fitsIntoPrimitive(from)) {
+ const QString retrieve = retrieveFromPrimitive(to);
+ if (!retrieve.isEmpty())
+ return u"QJSPrimitiveValue("_qs + variable + u')' + retrieve;
+ }
+
// TODO: more efficient string conversions, possibly others
return u"aotContext->engine->fromScriptValue<"_qs + castTargetName(to)