aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljscodegenerator.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-02-04 22:35:23 +0100
committerUlf Hermann <ulf.hermann@qt.io>2022-02-16 14:44:39 +0100
commitbe90de3dc1efc447f17a5fc6ba5f0c6aa760f9a4 (patch)
tree2a9a0b18bee911769fde02c56700ed88f3393f42 /src/qmlcompiler/qqmljscodegenerator.cpp
parent160190968df4a2b5163700a2aebd88842d0c784e (diff)
QmlCompiler: track register contents by cloning types
Whenever we write a register, we create a new type. This way, whenever we determine that a different type would be a better fit at that place, we can just change the type in place, without affecting any unrelated code. Task-number: QTBUG-100157 Change-Id: I70be2eb83bda5483e083f58113fdfe57224b237e Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qmlcompiler/qqmljscodegenerator.cpp')
-rw-r--r--src/qmlcompiler/qqmljscodegenerator.cpp175
1 files changed, 93 insertions, 82 deletions
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp
index 8f07baf0c0..d338fbfb66 100644
--- a/src/qmlcompiler/qqmljscodegenerator.cpp
+++ b/src/qmlcompiler/qqmljscodegenerator.cpp
@@ -127,6 +127,7 @@ QQmlJSAotFunction QQmlJSCodeGenerator::run(
for (const auto loopLabel : m_context->labelInfo)
m_labels.insert(loopLabel, u"label_%1"_qs.arg(m_labels.count()));
+ m_state.State::operator=(initialState(function, m_typeResolver));
const QByteArray byteCode = function->code;
decode(byteCode.constData(), static_cast<uint>(byteCode.length()));
eliminateDeadStores();
@@ -139,9 +140,9 @@ QQmlJSAotFunction QQmlJSCodeGenerator::run(
registerTypeIt != end; ++registerTypeIt) {
const QQmlJSScope::ConstPtr storedType = registerTypeIt.key();
- if (storedType == m_typeResolver->nullType()
- || storedType == m_typeResolver->emptyListType()
- || storedType == m_typeResolver->voidType()) {
+ if (m_typeResolver->equals(storedType, m_typeResolver->nullType())
+ || m_typeResolver->equals(storedType, m_typeResolver->emptyListType())
+ || m_typeResolver->equals(storedType, m_typeResolver->voidType())) {
continue;
}
@@ -388,21 +389,23 @@ void QQmlJSCodeGenerator::generate_Ret()
const QString signalUndefined = u"aotContext->setReturnValueUndefined();\n"_qs;
if (!m_state.accumulatorVariableIn.isEmpty()) {
const QString in = use(m_state.accumulatorVariableIn);
- if (m_state.accumulatorIn().storedType() == m_typeResolver->varType()) {
+ if (m_typeResolver->registerIsStoredIn(
+ m_state.accumulatorIn(), m_typeResolver->varType())) {
m_body += u"if (!"_qs + in + u".isValid())\n"_qs;
m_body += u" "_qs + signalUndefined;
- } else if (m_state.accumulatorIn().storedType() == m_typeResolver->jsPrimitiveType()) {
+ } else if (m_typeResolver->registerIsStoredIn(
+ m_state.accumulatorIn(), m_typeResolver->jsPrimitiveType())) {
m_body += u"if ("_qs + in
+ u".type() == QJSPrimitiveValue::Undefined)\n"_qs;
m_body += u" "_qs + signalUndefined;
- } else if (m_state.accumulatorIn().storedType() == m_typeResolver->jsValueType()) {
+ } else if (m_typeResolver->registerIsStoredIn(
+ m_state.accumulatorIn(), m_typeResolver->jsValueType())) {
m_body += u"if ("_qs + in + u".isUndefined())\n"_qs;
m_body += u" "_qs + signalUndefined;
}
m_body += u"return "_qs
+ conversion(m_state.accumulatorIn().storedType(), m_function->returnType, in);
- } else if (m_function->returnType != m_typeResolver->voidType()
- && m_function->returnType->internalName() != u"void"_qs) {
+ } else if (m_function->returnType->internalName() != u"void"_qs) {
if (m_function->returnType->internalName().trimmed().endsWith(u'*')
|| m_function->returnType->internalName().trimmed().endsWith(u'&')) {
setError(u"Not all paths return a value"_qs);
@@ -513,18 +516,19 @@ void QQmlJSCodeGenerator::generate_MoveConst(int constIndex, int destTemp)
m_jsUnitGenerator->constant(constIndex));
if (v4Value.isNull()) {
- const auto type = m_state.changedRegister().storedType();
+ const auto changed = m_state.changedRegister();
m_body += var + u" = "_qs;
- if (type == m_typeResolver->jsPrimitiveType()) {
+ if (m_typeResolver->registerIsStoredIn(changed, m_typeResolver->jsPrimitiveType())) {
m_body += u"QJSPrimitiveNull()"_qs;
- } else if (type == m_typeResolver->jsValueType()) {
+ } else if (m_typeResolver->registerIsStoredIn(changed, m_typeResolver->jsValueType())) {
m_body += u"QJSValue(QJSValue::NullValue)"_qs;
- } else if (type == m_typeResolver->varType()) {
+ } else if (m_typeResolver->registerIsStoredIn(changed, m_typeResolver->varType())) {
m_body += u"QVariant::fromValue<std::nullptr_t>(nullptr)"_qs;
- } else if (type->accessSemantics() == QQmlJSScope::AccessSemantics::Reference) {
+ } else if (changed.storedType()->accessSemantics()
+ == QQmlJSScope::AccessSemantics::Reference) {
m_body += u"nullptr"_qs;
} else {
- setError(u"Cannot load null into %1"_qs.arg(m_state.changedRegister().descriptiveName()));
+ setError(u"Cannot load null into %1"_qs.arg(changed.descriptiveName()));
}
m_body += u";\n"_qs;
@@ -732,7 +736,7 @@ void QQmlJSCodeGenerator::generate_StoreNameSloppy(int nameIndex)
switch (type.variant()) {
case QQmlJSRegisterContent::ScopeProperty:
case QQmlJSRegisterContent::ExtensionScopeProperty: {
- if (type.property().type() != m_typeResolver->containedType(m_state.accumulatorIn())) {
+ if (!m_typeResolver->registerContains(m_state.accumulatorIn(), type.property().type())) {
m_body += u"{\n"_qs;
m_body += u"auto converted = "_qs
+ conversion(m_state.accumulatorIn(), type, use(m_state.accumulatorVariableIn))
@@ -778,7 +782,7 @@ void QQmlJSCodeGenerator::generate_LoadElement(int base)
return;
}
- if (baseType.storedType() != m_typeResolver->listPropertyType()) {
+ if (!m_typeResolver->registerIsStoredIn(baseType, m_typeResolver->listPropertyType())) {
reject(u"indirect LoadElement"_qs);
return;
}
@@ -817,7 +821,7 @@ void QQmlJSCodeGenerator::generate_StoreElement(int base, int index)
return;
}
- if (baseType.storedType() != m_typeResolver->listPropertyType()) {
+ if (!m_typeResolver->registerIsStoredIn(baseType, m_typeResolver->listPropertyType())) {
reject(u"indirect StoreElement"_qs);
return;
}
@@ -951,9 +955,9 @@ void QQmlJSCodeGenerator::generate_GetLookup(int index)
const QString namespaceString = m_state.accumulatorIn().isImportNamespace()
? QString::number(m_state.accumulatorIn().importNamespace())
: u"QQmlPrivate::AOTCompiledContext::InvalidStringId"_qs;
- const auto storedType = m_state.accumulatorIn().storedType();
- const bool isReferenceType
- = (storedType->accessSemantics() == QQmlJSScope::AccessSemantics::Reference);
+ const auto accumulatorIn = m_state.accumulatorIn();
+ const bool isReferenceType = (accumulatorIn.storedType()->accessSemantics()
+ == QQmlJSScope::AccessSemantics::Reference);
if (m_state.accumulatorOut().variant() == QQmlJSRegisterContent::ObjectAttached) {
if (!isReferenceType) {
// This can happen on incomplete type information. We contextually know that the
@@ -997,16 +1001,17 @@ void QQmlJSCodeGenerator::generate_GetLookup(int index)
m_state.accumulatorOut(), m_state.accumulatorVariableOut, index);
generateLookup(lookup, initialization, preparation);
m_body += u"}\n"_qs;
- } else if ((storedType == m_typeResolver->stringType()
- || storedType->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence)
+ } else if ((m_typeResolver->registerIsStoredIn(accumulatorIn, m_typeResolver->stringType())
+ || accumulatorIn.storedType()->accessSemantics()
+ == QQmlJSScope::AccessSemantics::Sequence)
&& m_jsUnitGenerator->lookupName(index) == u"length"_qs) {
// Special-cased the same way as in QQmlJSTypeResolver::memberType()
m_body += m_state.accumulatorVariableOut + u" = "_qs + use(m_state.accumulatorVariableIn)
+ u".count("_qs;
- if (storedType == m_typeResolver->listPropertyType())
+ if (m_typeResolver->registerIsStoredIn(accumulatorIn, m_typeResolver->listPropertyType()))
m_body += u'&' + use(m_state.accumulatorVariableIn);
m_body += u')' + u";\n"_qs;
- } else if (storedType == m_typeResolver->jsValueType()) {
+ } else if (m_typeResolver->registerIsStoredIn(accumulatorIn, m_typeResolver->jsValueType())) {
reject(u"lookup in QJSValue"_qs);
} else {
m_body += u"{\n"_qs;
@@ -1045,10 +1050,10 @@ void QQmlJSCodeGenerator::generate_StoreProperty(int nameIndex, int baseReg)
QString QQmlJSCodeGenerator::setLookupPreparation(
const QQmlJSRegisterContent &content, const QString &arg, int lookup)
{
- const QQmlJSScope::ConstPtr stored = content.storedType();
- if (m_typeResolver->containedType(content) == stored) {
+ if (m_typeResolver->registerContains(content, content.storedType()))
return QString();
- } else if (stored == m_typeResolver->varType()) {
+
+ if (m_typeResolver->registerIsStoredIn(content, m_typeResolver->varType())) {
return u"const QMetaType argType = aotContext->lookupResultMetaType("_qs
+ QString::number(lookup) + u");\n"_qs
+ u"if (argType.isValid())\n "_qs + arg + u".convert(argType)";
@@ -1068,7 +1073,6 @@ void QQmlJSCodeGenerator::generate_SetLookup(int index, int baseReg)
const QString indexString = QString::number(index);
const QQmlJSScope::ConstPtr valueType = m_state.accumulatorIn().storedType();
const QQmlJSRegisterContent callBase = registerType(baseReg);
- const QQmlJSScope::ConstPtr objectType = callBase.storedType();
const QQmlJSRegisterContent specific = m_typeResolver->memberType(
callBase, m_jsUnitGenerator->lookupName(index));
const QQmlJSRegisterContent property = specific.storedIn(
@@ -1080,7 +1084,8 @@ void QQmlJSCodeGenerator::generate_SetLookup(int index, int baseReg)
QString variableInType;
QString preparation;
QString argType;
- if (property != m_state.accumulatorIn()) {
+ if (!m_typeResolver->registerContains(
+ m_state.accumulatorIn(), m_typeResolver->containedType(property))) {
m_body += u"auto converted = "_qs
+ conversion(m_state.accumulatorIn(), property, use(m_state.accumulatorVariableIn))
+ u";\n"_qs;
@@ -1097,7 +1102,7 @@ void QQmlJSCodeGenerator::generate_SetLookup(int index, int baseReg)
argType = variableInType;
}
- switch (objectType->accessSemantics()) {
+ switch (callBase.storedType()->accessSemantics()) {
case QQmlJSScope::AccessSemantics::Reference: {
const QString lookup = u"aotContext->setObjectLookup("_qs + indexString
+ u", "_qs + object + u", "_qs + variableIn + u')';
@@ -1113,7 +1118,7 @@ void QQmlJSCodeGenerator::generate_SetLookup(int index, int baseReg)
break;
}
- if (objectType != m_typeResolver->listPropertyType()) {
+ if (!m_typeResolver->registerIsStoredIn(callBase, m_typeResolver->listPropertyType())) {
reject(u"SetLookup on sequence types (because of missing write-back)"_qs);
break;
}
@@ -1189,7 +1194,7 @@ QString QQmlJSCodeGenerator::argumentsList(int argc, int argv, QString *outVar)
QString args;
QString conversions;
- if (m_typeResolver->containedType(m_state.accumulatorOut()) == m_typeResolver->voidType()) {
+ if (m_typeResolver->registerContains(m_state.accumulatorOut(), m_typeResolver->voidType())) {
types = u"QMetaType()"_qs;
args = u"nullptr"_qs;
} else {
@@ -1207,20 +1212,20 @@ QString QQmlJSCodeGenerator::argumentsList(int argc, int argv, QString *outVar)
}
for (int i = 0; i < argc; ++i) {
- const QQmlJSScope::ConstPtr type = registerType(argv + i).storedType();
+ const QQmlJSRegisterContent content = registerType(argv + i);
const QString var = use(registerVariable(argv + i));
- if (type == m_typeResolver->jsPrimitiveType()) {
+ if (m_typeResolver->registerIsStoredIn(content, m_typeResolver->jsPrimitiveType())) {
QString argName = u"arg"_qs + QString::number(i);
conversions += u"QVariant "_qs + argName + u" = "_qs
- + conversion(type, m_typeResolver->varType(), var) + u";\n"_qs;
+ + conversion(content.storedType(), m_typeResolver->varType(), var) + u";\n"_qs;
args += u", "_qs + argName + u".data()"_qs;
types += u", "_qs + argName + u".metaType()"_qs;
- } else if (type == m_typeResolver->varType()) {
+ } else if (m_typeResolver->registerIsStoredIn(content, m_typeResolver->varType())) {
args += u", "_qs + var + u".data()"_qs;
types += u", "_qs + var + u".metaType()"_qs;
} else {
args += u", &"_qs + var;
- types += u", "_qs + metaTypeFromType(type);
+ types += u", "_qs + metaTypeFromType(content.storedType());
}
}
return conversions
@@ -1280,7 +1285,7 @@ bool QQmlJSCodeGenerator::inlineMathMethod(const QString &name, int argc, int ar
addInclude(u"qalgorithms.h"_qs);
addInclude(u"qrandom.h"_qs);
- if (m_state.accumulatorOut().storedType() != m_typeResolver->realType())
+ if (!m_typeResolver->registerIsStoredIn(m_state.accumulatorOut(), m_typeResolver->realType()))
return false;
m_body += u"{\n"_qs;
@@ -1403,7 +1408,7 @@ void QQmlJSCodeGenerator::generate_CallPropertyLookup(int index, int base, int a
if (baseType.storedType()->accessSemantics() != QQmlJSScope::AccessSemantics::Reference) {
const QString name = m_jsUnitGenerator->stringForIndex(
m_jsUnitGenerator->lookupNameIndex(index));
- if (m_typeResolver->containedType(baseType) == mathObject()) {
+ if (m_typeResolver->registerContains(baseType, mathObject())) {
if (inlineMathMethod(name, argc, argv))
return;
}
@@ -1830,10 +1835,10 @@ void QQmlJSCodeGenerator::generate_CmpNeNull()
QString QQmlJSCodeGenerator::eqIntExpression(int lhsConst)
{
- if (m_state.accumulatorIn().storedType() == m_typeResolver->intType())
+ if (m_typeResolver->registerIsStoredIn(m_state.accumulatorIn(), m_typeResolver->intType()))
return QString::number(lhsConst) + u" == "_qs + use(m_state.accumulatorVariableIn);
- if (m_state.accumulatorIn().storedType() == m_typeResolver->boolType()) {
+ if (m_typeResolver->registerIsStoredIn(m_state.accumulatorIn(), m_typeResolver->boolType())) {
return QString::number(lhsConst) + u" == "_qs
+ conversion(m_state.accumulatorIn().storedType(), m_typeResolver->intType(),
use(m_state.accumulatorVariableIn));
@@ -1859,10 +1864,10 @@ QString QQmlJSCodeGenerator::eqIntExpression(int lhsConst)
QString QQmlJSCodeGenerator::getLookupPreparation(
const QQmlJSRegisterContent &content, const QString &var, int lookup)
{
- const QQmlJSScope::ConstPtr stored = content.storedType();
- if (m_typeResolver->containedType(content) == stored) {
+ if (m_typeResolver->registerContains(content, content.storedType()))
return QString();
- } else if (stored == m_typeResolver->varType()) {
+
+ if (m_typeResolver->registerIsStoredIn(content, m_typeResolver->varType())) {
return var + u" = QVariant(aotContext->lookupResultMetaType("_qs
+ QString::number(lookup) + u"))"_qs;
}
@@ -1873,9 +1878,9 @@ QString QQmlJSCodeGenerator::getLookupPreparation(
QString QQmlJSCodeGenerator::contentPointer(const QQmlJSRegisterContent &content, const QString &var)
{
const QQmlJSScope::ConstPtr stored = content.storedType();
- if (m_typeResolver->containedType(content) == stored)
+ if (m_typeResolver->registerContains(content, stored))
return u'&' + var;
- else if (stored == m_typeResolver->varType())
+ else if (m_typeResolver->registerIsStoredIn(content, m_typeResolver->varType()))
return var + u".data()"_qs;
else if (stored->accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
return u'&' + var;
@@ -1889,9 +1894,9 @@ QString QQmlJSCodeGenerator::contentType(const QQmlJSRegisterContent &content, c
const QQmlJSScope::ConstPtr stored = content.storedType();
const QQmlJSScope::ConstPtr contained = QQmlJSScope::nonCompositeBaseType(
m_typeResolver->containedType(content));
- if (contained == stored)
+ if (m_typeResolver->equals(contained, stored))
return metaTypeFromType(stored);
- else if (stored == m_typeResolver->varType())
+ else if (m_typeResolver->equals(stored, m_typeResolver->varType()))
return var + u".metaType()"_qs; // We expect the QVariant to be initialized
else if (stored->accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
return metaTypeFromName(contained);
@@ -1984,7 +1989,8 @@ void QQmlJSCodeGenerator::generate_As(int lhs)
const QQmlJSScope::ConstPtr contained = m_typeResolver->containedType(m_state.accumulatorOut());
m_body += m_state.accumulatorVariableOut + u" = "_qs;
- if (m_state.accumulatorIn().storedType() == m_typeResolver->metaObjectType()
+ if (m_typeResolver->equals(
+ m_state.accumulatorIn().storedType(), m_typeResolver->metaObjectType())
&& contained->isComposite()) {
m_body += conversion(
m_typeResolver->genericType(contained), m_state.accumulatorOut().storedType(),
@@ -2324,7 +2330,7 @@ void QQmlJSCodeGenerator::generateEqualityOperation(int lhs, const QString &func
m_body += m_state.accumulatorVariableOut + u" = "_qs;
const auto primitive = m_typeResolver->jsPrimitiveType();
- if (lhsType == rhsType && lhsType != primitive) {
+ if (m_typeResolver->equals(lhsType, rhsType) && !m_typeResolver->equals(lhsType, primitive)) {
m_body += use(registerVariable(lhs));
m_body += (invert ? u" != "_qs : u" == "_qs);
m_body += use(m_state.accumulatorVariableIn);
@@ -2400,7 +2406,8 @@ void QQmlJSCodeGenerator::protectAccumulator()
// prepare the output QVariant, and afterwards use the input variant. Therefore we need to move
// the input out of the way first.
if (m_state.accumulatorVariableIn == m_state.accumulatorVariableOut
- && m_state.accumulatorOut().storedType() == m_typeResolver->varType()) {
+ && m_typeResolver->registerIsStoredIn(
+ m_state.accumulatorOut(), m_typeResolver->varType())) {
m_state.accumulatorVariableIn = use(m_state.accumulatorVariableIn) + u"_moved"_qs;
m_body += u"QVariant "_qs + m_state.accumulatorVariableIn
+ u" = std::move("_qs + m_state.accumulatorVariableOut + u");\n"_qs;
@@ -2439,6 +2446,7 @@ void QQmlJSCodeGenerator::generateJumpCodeWithTypeConversions(
currentVariable = registerVariable(registerIndex);
}
+ // Actually == here. We want the jump code also for equal types
if (!currentType.isValid() || currentType == targetType)
continue;
Q_ASSERT(m_registerVariables.contains(registerIndex));
@@ -2507,57 +2515,57 @@ QString QQmlJSCodeGenerator::conversion(const QQmlJSScope::ConstPtr &from,
const auto jsPrimitiveType = m_typeResolver->jsPrimitiveType();
const auto boolType = m_typeResolver->boolType();
- if (from == m_typeResolver->nullType()) {
+ if (m_typeResolver->equals(from, m_typeResolver->nullType())) {
if (to->accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
return u"static_cast<"_qs + to->internalName() + u" *>(nullptr)"_qs;
- if (to == jsValueType)
+ if (m_typeResolver->equals(to, jsValueType))
return u"QJSValue(QJSValue::NullValue)"_qs;
- if (to == jsPrimitiveType)
+ if (m_typeResolver->equals(to, jsPrimitiveType))
return u"QJSPrimitiveValue(QJSPrimitiveNull())"_qs;
- if (to == varType)
+ if (m_typeResolver->equals(to, varType))
return u"QVariant::fromValue<std::nullptr_t>(nullptr)"_qs;
- if (to == boolType)
+ if (m_typeResolver->equals(to, boolType))
return u"false"_qs;
if (m_typeResolver->isNumeric(m_typeResolver->globalType(to)))
return u"0"_qs;
- if (to == m_typeResolver->stringType())
+ if (m_typeResolver->equals(to, m_typeResolver->stringType()))
return u"null"_qs;
- if (to == from)
+ if (m_typeResolver->equals(from, to))
return QString();
reject(u"Conversion from null to %1"_qs.arg(to->internalName()));
}
- if (from == m_typeResolver->emptyListType()) {
+ if (m_typeResolver->equals(from, m_typeResolver->emptyListType())) {
if (to->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence)
return castTargetName(to) + u"()"_qs;
- if (to == m_typeResolver->varType())
+ if (m_typeResolver->equals(to, m_typeResolver->varType()))
return u"QVariant(QVariantList())"_qs;
- if (to == from)
+ if (m_typeResolver->equals(from, to))
return QString();
reject(u"Conversion from empty list to %1"_qs.arg(to->internalName()));
}
- if (from == to)
+ if (m_typeResolver->equals(from, to))
return variable;
if (from->accessSemantics() == QQmlJSScope::AccessSemantics::Reference) {
if (to->accessSemantics() == QQmlJSScope::AccessSemantics::Reference) {
for (QQmlJSScope::ConstPtr base = from; base; base = base->baseType()) {
// We still have to cast as other execution paths may result in different types.
- if (base == to)
+ if (m_typeResolver->equals(base, to))
return u"static_cast<"_qs + to->internalName() + u" *>("_qs + variable + u')';
}
for (QQmlJSScope::ConstPtr base = to; base; base = base->baseType()) {
- if (base == from)
+ if (m_typeResolver->equals(base, from))
return u"static_cast<"_qs + to->internalName() + u" *>("_qs + variable + u')';
}
- } else if (to == m_typeResolver->boolType()) {
+ } else if (m_typeResolver->equals(to, m_typeResolver->boolType())) {
return u'(' + variable + u" != nullptr)"_qs;
}
}
auto isJsValue = [&](const QQmlJSScope::ConstPtr &candidate) {
- return candidate == jsValueType || candidate->isScript();
+ return m_typeResolver->equals(candidate, jsValueType) || candidate->isScript();
};
if (isJsValue(from) && isJsValue(to))
@@ -2565,54 +2573,57 @@ QString QQmlJSCodeGenerator::conversion(const QQmlJSScope::ConstPtr &from,
const auto isBoolOrNumber = [&](const QQmlJSScope::ConstPtr &type) {
return m_typeResolver->isNumeric(m_typeResolver->globalType(type))
- || type == m_typeResolver->boolType()
+ || m_typeResolver->equals(type, m_typeResolver->boolType())
|| type->scopeType() == QQmlJSScope::EnumScope;
};
- if (from == m_typeResolver->realType() && to == m_typeResolver->intType())
+ if (m_typeResolver->equals(from, m_typeResolver->realType())
+ && m_typeResolver->equals(to, m_typeResolver->intType())) {
return u"QJSNumberCoercion::toInteger("_qs + variable + u')';
+ }
if (isBoolOrNumber(from) && isBoolOrNumber(to))
return to->internalName() + u'(' + variable + u')';
- if (from == jsPrimitiveType) {
- if (to == m_typeResolver->realType())
+
+ if (m_typeResolver->equals(from, jsPrimitiveType)) {
+ if (m_typeResolver->equals(to, m_typeResolver->realType()))
return variable + u".toDouble()"_qs;
- if (to == boolType)
+ if (m_typeResolver->equals(to, boolType))
return variable + u".toBoolean()"_qs;
- if (to == m_typeResolver->intType())
+ if (m_typeResolver->equals(to, m_typeResolver->intType()))
return variable + u".toInteger()"_qs;
- if (to == m_typeResolver->stringType())
+ if (m_typeResolver->equals(to, m_typeResolver->stringType()))
return variable + u".toString()"_qs;
- if (to == jsValueType)
+ if (m_typeResolver->equals(to, jsValueType))
return u"QJSValue(QJSPrimitiveValue("_qs + variable + u"))"_qs;
- if (to == varType)
+ if (m_typeResolver->equals(to, varType))
return variable + u".toVariant()"_qs;
if (to->accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
return u"static_cast<"_qs + to->internalName() + u" *>(nullptr)"_qs;
}
if (isJsValue(from)) {
- if (to == jsPrimitiveType)
+ if (m_typeResolver->equals(to, jsPrimitiveType))
return variable + u".toPrimitive()"_qs;
- if (to == varType)
+ if (m_typeResolver->equals(to, varType))
return variable + u".toVariant(QJSValue::RetainJSObjects)"_qs;
return u"qjsvalue_cast<"_qs + castTargetName(to) + u">("_qs + variable + u')';
}
- if (to == jsPrimitiveType)
+ if (m_typeResolver->equals(to, jsPrimitiveType))
return u"QJSPrimitiveValue("_qs + variable + u')';
- if (to == jsValueType)
+ if (m_typeResolver->equals(to, jsValueType))
return u"aotContext->engine->toScriptValue("_qs + variable + u')';
- if (from == varType) {
- if (to == m_typeResolver->listPropertyType())
+ if (m_typeResolver->equals(from, varType)) {
+ if (m_typeResolver->equals(to, m_typeResolver->listPropertyType()))
return u"QQmlListReference("_qs + variable + u", aotContext->qmlEngine())"_qs;
return u"qvariant_cast<"_qs + castTargetName(to) + u">("_qs + variable + u')';
}
- if (to == varType)
+ if (m_typeResolver->equals(to, varType))
return u"QVariant::fromValue("_qs + variable + u')';
// TODO: more efficient string conversions, possibly others