10#include <private/qqmljstypepropagator_p.h>
12#include <private/qqmlirbuilder_p.h>
13#include <private/qqmljsscope_p.h>
14#include <private/qqmljsutils_p.h>
15#include <private/qv4compilerscanfunctions_p.h>
16#include <private/qduplicatetracker_p.h>
18#include <QtCore/qdir.h>
19#include <QtCore/qfileinfo.h>
34#define BYTECODE_UNIMPLEMENTED() Q_ASSERT_X(false, Q_FUNC_INFO, "not implemented");
36#define INJECT_TRACE_INFO(function) \
37 static const bool injectTraceInfo = true; \
38 if (injectTraceInfo) { \
39 m_body += u"// "_s + QStringLiteral(#function) + u'\n'; \
52 return type->augmentedInternalName();
60 , m_context(compilerContext)
65 return u
"QMetaType::fromType<"_s +
type->augmentedInternalName() + u
">()"_s;
70 return u
"[]() { static const auto t = QMetaType::fromName(\""_s
72 + u
"\"); return t; }()"_s;
80 return u
'&' + objectType->
internalName() + u
"::staticMetaObject"_s;
85 reject(u
"retrieving the metaObject of a composite type without using an instance."_s);
100 m_annotations = annotations;
111 auto &typesForRegisters = m_registerVariables[registerIndex];
112 if (!typesForRegisters.contains(seenType)) {
113 auto ¤tRegisterNames = registerNames[registerIndex];
116 name = u
"r%1_%2"_s.
arg(registerIndex).
arg(currentRegisterNames.size());
117 typesForRegisters[seenType] =
name;
123 for (
const auto &annotation : *m_annotations) {
124 addVariable(annotation.second.changedRegisterIndex,
125 annotation.second.changedRegister.storedType());
126 for (
auto it = annotation.second.typeConversions.
begin(),
127 end = annotation.second.typeConversions.end();
129 addVariable(
it.key(),
it.value().content.storedType());
135 for (
const auto loopLabel : m_context->
labelInfo)
136 m_labels.
insert(loopLabel, u
"label_%1"_s.arg(m_labels.
size()));
147 result.includes.swap(m_includes);
149 result.code += u
"// %1 at line %2, column %3\n"_s
150 .arg(m_context->
name).arg(m_context->
line).arg(m_context->
column);
153 for (
auto registerIt = m_registerVariables.cbegin(), registerEnd = m_registerVariables.cend();
154 registerIt != registerEnd; ++registerIt) {
155 const auto ®isterTypes = *registerIt;
156 const int registerIndex = registerIt.key();
158 const bool registerIsArgument =
isArgument(registerIndex);
160 for (
auto registerTypeIt = registerTypes.constBegin(),
end = registerTypes.constEnd();
161 registerTypeIt !=
end; ++registerTypeIt) {
165 if (generatedVariables.
hasSeen(registerTypeIt.value()))
171 = (storedType->
accessSemantics() == QQmlJSScope::AccessSemantics::Reference);
177 if (!registerIsArgument
179 && registerIndex !=
This
183 result.code += registerTypeIt.value() + u
" = "_s;
193 const bool needsConversion =
argument != original;
194 if (!isPointer && registerTypes.size() == 1 && !needsConversion) {
204 result.code += registerTypeIt.value() + u
" = "_s;
214 result.code += registerTypeIt.value();
223 if (argType.isValid()) {
234 if (
function->returnType->accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
235 result.returnType += u
'*';
237 result.returnType = u
"void"_s;
246 return ret->accessSemantics() == QQmlJSScope::AccessSemantics::Reference
248 :
ret->internalName() + u
"()"_s;
258 const QString signalUndefined = u
"aotContext->setReturnValueUndefined();\n"_s;
263 m_body += u
"if (!"_s +
in + u
".isValid())\n"_s;
264 m_body += u
" "_s + signalUndefined;
268 + u
".type() == QJSPrimitiveValue::Undefined)\n"_s;
269 m_body += u
" "_s + signalUndefined;
272 m_body += u
"if ("_s +
in + u
".isUndefined())\n"_s;
273 m_body += u
" "_s + signalUndefined;
280 m_body += signalUndefined;
290 m_skipUntilNextLabel =
true;
301 if (
value >= std::numeric_limits<int>::min() &&
value <= std::numeric_limits<int>::max()) {
309 const QString inf = u
"std::numeric_limits<double>::infinity()"_s;
310 return std::signbit(
value) ? (u
'-' + inf) : inf;
313 return u
"std::numeric_limits<double>::quiet_NaN()"_s;
315 return std::signbit(
value) ? u
"-0.0"_s : u
"0"_s;
347 value.booleanValue() ? u
"true"_s : u
"false"_s);
357 reject(u
"unsupported constant type"_s);
442 if (v4Value.isNull()) {
444 }
else if (v4Value.isUndefined()) {
446 }
else if (v4Value.isBoolean()) {
448 input = v4Value.booleanValue() ? u
"true"_s : u
"false"_s;
449 }
else if (v4Value.isInteger()) {
452 }
else if (v4Value.isDouble()) {
456 reject(u
"unknown const type"_s);
574 const QString initialization = u
"aotContext->initLoadGlobalLookup("_s
591 u
"aotContext->javaScriptGlobalProperty("_s +
QString::number(nameIndex) + u
")")
598 const QString lookup = u
"aotContext->loadContextIdLookup("_s
599 + indexString + u
", "_s
601 const QString initialization = u
"aotContext->initLoadContextIdLookup("_s
602 + indexString + u
')';
613 const QString lookup = u
"aotContext->loadScopeObjectPropertyLookup("_s
614 + indexString + u
", "_s
617 = u
"aotContext->initLoadScopeObjectPropertyLookup("_s
618 + indexString + u
", "_s
625 generateTypeLookup(
index);
639 switch (
type.variant()) {
654 reject(u
"assignment to scope method"_s);
676 reject(u
"LoadElement with non-list base type or non-numeric arguments"_s);
690 m_body += u
"if (!QJSNumberCoercion::isInteger("_s + indexName + u
"))\n"_s
697 m_body += u
"if ("_s + indexName + u
" < 0)\n"_s
708 m_body += u
"if ("_s + indexName + u
" < "_s + baseName
709 + u
".count(&"_s + baseName + u
"))\n"_s;
712 baseName + u
".at(&"_s + baseName + u
", "_s
713 + indexName + u
')') + u
";\n"_s;
727 reject(u
"LoadElement on a sequence potentially affected by side effects"_s);
729 reject(u
"LoadElement on a sequence wrapped in a non-sequence type"_s);
731 m_body += u
"if ("_s + indexName + u
" < "_s + baseName + u
".size())\n"_s;
746 reject(u
"StoreElement with non-list base type or non-numeric arguments"_s);
751 reject(u
"indirect StoreElement"_s);
764 m_body += u
"QJSNumberCoercion::isInteger("_s + indexName + u
") && "_s;
766 m_body += indexName + u
" >= 0 && "_s;
767 m_body += indexName + u
" < "_s + baseName + u
".count(&"_s + baseName
769 m_body += u
" "_s + baseName + u
".replace(&"_s + baseName
770 + u
", "_s + indexName + u
", "_s;
778 reject(u
"LoadProperty"_s);
813 reject(u
"qmltypes misses name entry for flag; did you pass the enum type to Q_FLAG instead of the QFlag type?"
814 "\nType is %1, enum name is %2"_s.arg(scopeType->
internalName(), metaEnum.
name()));
815 reject(u
"qmltypes misses name entry for enum"_s);
819 const QString initialization = u
"aotContext->initGetEnumLookup("_s
821 + u
", \""_s + enumName + u
"\", \""_s + enumMember
826void QQmlJSCodeGenerator::generateTypeLookup(
int index)
833 : u
"QQmlPrivate::AOTCompiledContext::InvalidStringId"_s;
837 rejectIfNonQObjectOut(u
"non-QObject singleton type"_s);
838 const QString lookup = u
"aotContext->loadSingletonLookup("_s + indexString
840 const QString initialization = u
"aotContext->initLoadSingletonLookup("_s + indexString
841 + u
", "_s + namespaceString + u
')';
848 rejectIfNonQObjectOut(u
"non-QObject attached type"_s);
849 const QString lookup = u
"aotContext->loadAttachedLookup("_s + indexString
851 const QString initialization = u
"aotContext->initLoadAttachedLookup("_s + indexString
852 + u
", "_s + namespaceString + u
", aotContext->qmlScopeObject)"_s;
857 reject(u
"script lookup"_s);
864 reject(u
"meta-object stored in different type"_s);
866 const QString lookup = u
"aotContext->loadTypeLookup("_s + indexString
868 const QString initialization = u
"aotContext->initLoadTypeLookup("_s + indexString
869 + u
", "_s + namespaceString + u
")"_s;
878void QQmlJSCodeGenerator::generateVariantEqualityComparison(
888 m_body += u
"if ("_s + registerName
889 + u
".metaType() == QMetaType::fromType<QJSPrimitiveValue>()) {\n"_s
892 u
"static_cast<const QJSPrimitiveValue *>("_s + registerName
893 + u
".constData())"_s + u
"->type() "_s
894 + (
invert ? u
"!="_s : u
"=="_s)
896 ? u
"QJSPrimitiveValue::Null"_s
897 : u
"QJSPrimitiveValue::Undefined"_s))
898 + u
";\n} else if ("_s + registerName
899 + u
".metaType() == QMetaType::fromType<QJSValue>()) {\n"_s
900 +
m_state.accumulatorVariableOut + u
" = "_s
902 (
invert ? u
"!"_s :
QString()) + u
"static_cast<const QJSValue *>("_s
903 + registerName + u
".constData())"_s + u
"->"_s
906 : u
"isUndefined()"_s))
912 m_body += u
"else if ("_s + registerName
913 + u
".metaType().flags().testFlag(QMetaType::PointerToQObject)) {\n"_s
916 u
"*static_cast<QObject *const *>("_s + registerName
917 + u
".constData())"_s + (
invert ? u
"!="_s : u
"=="_s)
919 + u
";\n} else if ("_s + registerName
920 + u
".metaType() == QMetaType::fromType<std::nullptr_t>()) {\n"_s
921 +
m_state.accumulatorVariableOut + u
" = "_s
923 (
invert ? u
"false"_s : u
"true"_s))
930 (
invert ? (registerName + u
".isValid() ? true : false"_s)
931 : (registerName + u
".isValid() ? false : true"_s)))
935void QQmlJSCodeGenerator::rejectIfNonQObjectOut(
const QString &
error)
938 != QQmlJSScope::AccessSemantics::Reference) {
950bool QQmlJSCodeGenerator::generateContentPointerCheck(
964 reject(u
"lookup of members of %1 in %2"_s.arg(
968 bool needsVarContentConversion =
false;
981 needsVarContentConversion =
true;
988 m_body += u
" aotContext->engine->throwError(QJSValue::TypeError, "_s;
989 m_body += u
"QLatin1String(\"%1\"));\n"_s.
arg(processedErrorMessage);
992 return needsVarContentConversion;
995QString QQmlJSCodeGenerator::resolveValueTypeContentPointer(
1004QString QQmlJSCodeGenerator::resolveQObjectPointer(
1009 return u
"*static_cast<QObject *const *>("_s +
variable + u
".constData())"_s;
1018 reject(u
"lookup of function property."_s);
1044 : u
"QQmlPrivate::AOTCompiledContext::InvalidStringId"_s;
1051 if (!isReferenceType) {
1056 reject(u
"attached object for non-QObject type"_s);
1062 reject(u
"attached object of potentially non-QObject base"_s);
1065 rejectIfNonQObjectOut(u
"non-QObject attached type"_s);
1067 const QString lookup = u
"aotContext->loadAttachedLookup("_s + indexString
1070 const QString initialization = u
"aotContext->initLoadAttachedLookup("_s
1071 + indexString + u
", "_s + namespaceString + u
", "_s
1079 generateTypeLookup(
index);
1089 reject(u
"lookup in QJSValue"_s);
1090 }
else if (isReferenceType) {
1091 const QString inputPointer = resolveQObjectPointer(
1093 u
"Cannot read property '%1' of %2"_s.
arg(
1095 const QString lookup = u
"aotContext->getObjectLookup("_s + indexString
1096 + u
", "_s + inputPointer + u
", "_s
1098 const QString initialization = u
"aotContext->initGetObjectLookup("_s
1099 + indexString + u
", "_s + inputPointer
1105 }
else if ((accumulatorIn.
isList()
1117 }
else if (stored->
accessSemantics() == QQmlJSScope::AccessSemantics::Sequence
1125 reject(u
"access to 'length' property of sequence wrapped in non-sequence"_s);
1137 reject(u
"reading from a value that's potentially affected by side effects"_s);
1139 const QString inputContentPointer = resolveValueTypeContentPointer(
1141 u
"Cannot read property '%1' of %2"_s.
arg(
1144 const QString lookup = u
"aotContext->getValueLookup("_s + indexString
1145 + u
", "_s + inputContentPointer
1148 const QString initialization = u
"aotContext->initGetValueLookup("_s
1149 + indexString + u
", "_s
1169 reject(u
"StoreProperty"_s);
1179 return u
"const QMetaType argType = aotContext->lookupResultMetaType("_s
1181 + u
"if (argType.isValid())\n "_s +
arg + u
".convert(argType)";
1199 reject(u
"SetLookup. Could not find property "
1220 m_body += u
"auto converted = "_s
1229 argType = u
"argType"_s;
1233 argType = variableInType;
1236 switch (
property.scopeType()->accessSemantics()) {
1237 case QQmlJSScope::AccessSemantics::Reference: {
1238 const QString basePointer = resolveQObjectPointer(
1240 u
"TypeError: Value is %1 and could not be converted to an object"_s);
1242 const QString lookup = u
"aotContext->setObjectLookup("_s + indexString
1243 + u
", "_s + basePointer + u
", "_s + variableIn + u
')';
1244 const QString initialization = u
"aotContext->initSetObjectLookup("_s
1245 + indexString + u
", "_s + basePointer + u
", "_s + argType + u
')';
1249 case QQmlJSScope::AccessSemantics::Sequence: {
1251 if (propertyName != u
"length"_s) {
1252 reject(u
"setting non-length property on a sequence type"_s);
1257 reject(u
"resizing sequence types (because of missing write-back)"_s);
1262 m_body += u
"const int begin = "_s +
object + u
".count(&" +
object + u
");\n"_s;
1263 m_body += u
"const int end = "_s
1264 + (variableIn.
startsWith(u
'&') ? variableIn.
mid(1) : (u
'*' + variableIn))
1266 m_body += u
"for (int i = begin; i < end; ++i)\n"_s;
1267 m_body += u
" "_s +
object + u
".append(&"_s +
object + u
", nullptr);\n"_s;
1268 m_body += u
"for (int i = begin; i > end; --i)\n"_s;
1269 m_body += u
" "_s +
object + u
".removeLast(&"_s +
object + u
')'
1273 case QQmlJSScope::AccessSemantics::Value: {
1279 const QString baseContentPointer = resolveValueTypeContentPointer(
1281 u
"TypeError: Value is %1 and could not be converted to an object"_s);
1283 const QString lookup = u
"aotContext->setValueLookup("_s + indexString
1284 + u
", "_s + baseContentPointer
1285 + u
", "_s + variableIn + u
')';
1286 const QString initialization = u
"aotContext->initSetValueLookup("_s
1288 + u
", "_s + argType + u
')';
1291 reject(u
"SetLookup on value types (because of missing write-back)"_s);
1294 case QQmlJSScope::AccessSemantics::None:
1329QString QQmlJSCodeGenerator::argumentsList(
int argc,
int argv,
QString *outVar)
1337 types = u
"QMetaType()"_s;
1338 args = u
"nullptr"_s;
1340 *outVar = u
"callResult"_s;
1357 for (
int i = 0;
i < argc; ++
i) {
1364 return u
"void *args[] = { "_s +
args + u
" };\n"_s
1365 + u
"const QMetaType types[] = { "_s +
types + u
" };\n"_s;
1368void QQmlJSCodeGenerator::generateMoveOutVar(
const QString &outVar)
1374 m_body += u
"std::move(" + outVar + u
");\n";
1400 reject(u
"CallProperty"_s);
1403bool QQmlJSCodeGenerator::inlineStringMethod(
const QString &
name,
int base,
int argc,
int argv)
1405 if (
name != u
"arg"_s || argc != 1)
1433bool QQmlJSCodeGenerator::inlineTranslateMethod(
const QString &
name,
int argc,
int argv)
1443 const auto stringArg = [&](
int i) {
1449 const auto intArg = [&](
int i) {
1453 const auto stringRet = [&](
const QString &expression) {
1458 const auto capture = [&]() {
1459 m_body += u
"aotContext->captureTranslation();\n"_s;
1462 if (
name == u
"QT_TRID_NOOP"_s ||
name == u
"QT_TR_NOOP"_s) {
1469 if (
name == u
"QT_TRANSLATE_NOOP"_s) {
1476 if (
name == u
"qsTrId"_s) {
1482 + stringRet(u
"QCoreApplication::translate(nullptr, "_s + stringArg(0) +
1483 u
", nullptr, "_s + intArg(1) + u
")"_s) + u
";\n"_s;
1487 if (
name == u
"qsTr"_s) {
1490 + stringRet(u
"QCoreApplication::translate("_s
1491 + u
"aotContext->translationContext().toUtf8().constData(), "_s
1492 + stringArg(0) + u
", "_s + stringArg(1) + u
", "_s
1493 + intArg(2) + u
")"_s) + u
";\n"_s;
1497 if (
name == u
"qsTranslate"_s) {
1500 + stringRet(u
"QCoreApplication::translate("_s
1501 + stringArg(0) + u
", "_s + stringArg(1) + u
", "_s
1502 + stringArg(2) + u
", "_s + intArg(3) + u
")"_s) + u
";\n"_s;
1514 u
"[&]() { \nauto tmpMax = (qIsNull(arg2) && qIsNull(arg1) && std::copysign(1.0, arg2) == 1) ? arg2 : ((arg2 > arg1 || std::isnan(arg2)) ? arg2 : arg1);\n"_s;
1515 for (
int i = 2;
i < argc;
i++) {
1517 "\ttmpMax = (qIsNull(%1) && qIsNull(tmpMax) && std::copysign(1.0, %1) == 1) ? arg2 : ((%1 > tmpMax || std::isnan(%1)) ? %1 : tmpMax);\n"_L1
1520 expression +=
"return tmpMax;\n}()"_L1;
1530 u
"[&]() { \nauto tmpMin = (qIsNull(arg2) && qIsNull(arg1) && std::copysign(1.0, arg2) == -1) ? arg2 : ((arg2 < arg1 || std::isnan(arg2)) ? arg2 : arg1);\n"_s;
1531 for (
int i = 2;
i < argc;
i++) {
1533 "tmpMin = (qIsNull(%1) && qIsNull(tmpMin) && std::copysign(1.0, %1) == -1) ? arg2 : ((%1 < tmpMin || std::isnan(%1)) ? %1 : tmpMin);\n"_L1
1536 expression +=
"return tmpMin;\n}()"_L1;
1541bool QQmlJSCodeGenerator::inlineMathMethod(
const QString &
name,
int argc,
int argv)
1555 for (
int i = 0;
i < argc; ++
i) {
1562 const QString qNaN = u
"std::numeric_limits<double>::quiet_NaN()"_s;
1563 const QString inf = u
"std::numeric_limits<double>::infinity()"_s;
1568 if (
name == u
"abs" && argc == 1) {
1569 expression = u
"(qIsNull(arg1) ? 0 : (arg1 < 0.0 ? -arg1 : arg1))"_s;
1570 }
else if (
name == u
"acos"_s && argc == 1) {
1571 expression = u
"arg1 > 1.0 ? %1 : std::acos(arg1)"_s.
arg(qNaN);
1572 }
else if (
name == u
"acosh"_s && argc == 1) {
1573 expression = u
"arg1 < 1.0 ? %1 : std::acosh(arg1)"_s.
arg(qNaN);
1574 }
else if (
name == u
"asin"_s && argc == 1) {
1575 expression = u
"arg1 > 1.0 ? %1 : std::asin(arg1)"_s.
arg(qNaN);
1576 }
else if (
name == u
"asinh"_s && argc == 1) {
1577 expression = u
"qIsNull(arg1) ? arg1 : std::asinh(arg1)"_s;
1578 }
else if (
name == u
"atan"_s && argc == 1) {
1579 expression = u
"qIsNull(arg1) ? arg1 : std::atan(arg1)"_s;
1580 }
else if (
name == u
"atanh"_s && argc == 1) {
1581 expression = u
"qIsNull(arg1) ? arg1 : std::atanh(arg1)"_s;
1582 }
else if (
name == u
"atan2"_s) {
1585 }
else if (
name == u
"cbrt"_s && argc == 1) {
1586 expression = u
"std::cbrt(arg1)"_s;
1587 }
else if (
name == u
"ceil"_s && argc == 1) {
1588 expression = u
"(arg1 < 0.0 && arg1 > -1.0) ? std::copysign(0.0, -1.0) : std::ceil(arg1)"_s;
1589 }
else if (
name == u
"clz32"_s && argc == 1) {
1590 expression = u
"qint32(qCountLeadingZeroBits(quint32(QJSNumberCoercion::toInteger(arg1))))"_s;
1591 }
else if (
name == u
"cos"_s && argc == 1) {
1592 expression = u
"std::cos(arg1)"_s;
1593 }
else if (
name == u
"cosh"_s && argc == 1) {
1594 expression = u
"std::cosh(arg1)"_s;
1595 }
else if (
name == u
"exp"_s && argc == 1) {
1596 expression = u
"std::isinf(arg1) "
1597 "? (std::copysign(1.0, arg1) == -1 ? 0.0 : %1) "
1598 ": std::exp(arg1)"_s.
arg(inf);
1599 }
else if (
name == u
"expm1"_s) {
1602 }
else if (
name == u
"floor"_s && argc == 1) {
1603 expression = u
"std::floor(arg1)"_s;
1604 }
else if (
name == u
"fround"_s && argc == 1) {
1605 expression = u
"(std::isnan(arg1) || std::isinf(arg1) || qIsNull(arg1)) "
1607 ": double(float(arg1))"_s;
1608 }
else if (
name == u
"hypot"_s) {
1611 }
else if (
name == u
"imul"_s && argc == 2) {
1612 expression = u
"qint32(quint32(QJSNumberCoercion::toInteger(arg1)) "
1613 "* quint32(QJSNumberCoercion::toInteger(arg2)))"_s;
1614 }
else if (
name == u
"log"_s && argc == 1) {
1615 expression = u
"arg1 < 0.0 ? %1 : std::log(arg1)"_s.
arg(qNaN);
1616 }
else if (
name == u
"log10"_s && argc == 1) {
1617 expression = u
"arg1 < 0.0 ? %1 : std::log10(arg1)"_s.
arg(qNaN);
1618 }
else if (
name == u
"log1p"_s && argc == 1) {
1619 expression = u
"arg1 < -1.0 ? %1 : std::log1p(arg1)"_s.
arg(qNaN);
1620 }
else if (
name == u
"log2"_s && argc == 1) {
1621 expression = u
"arg1 < -0.0 ? %1 : std::log2(arg1)"_s.
arg(qNaN);
1622 }
else if (
name == u
"max"_s && argc >= 2) {
1624 }
else if (
name == u
"min"_s && argc >= 2) {
1626 }
else if (
name == u
"pow"_s) {
1627 expression = u
"QQmlPrivate::jsExponentiate(arg1, arg2)"_s;
1628 }
else if (
name == u
"random"_s && argc == 0) {
1629 expression = u
"QRandomGenerator::global()->generateDouble()"_s;
1630 }
else if (
name == u
"round"_s && argc == 1) {
1631 expression = u
"std::isfinite(arg1) "
1632 "? ((arg1 < 0.5 && arg1 >= -0.5) "
1633 "? std::copysign(0.0, arg1) "
1634 ": std::floor(arg1 + 0.5)) "
1636 }
else if (
name == u
"sign"_s && argc == 1) {
1637 expression = u
"std::isnan(arg1) "
1641 ": (std::signbit(arg1) ? -1.0 : 1.0))"_s.
arg(qNaN);
1642 }
else if (
name == u
"sin"_s && argc == 1) {
1643 expression = u
"qIsNull(arg1) ? arg1 : std::sin(arg1)"_s;
1644 }
else if (
name == u
"sinh"_s && argc == 1) {
1645 expression = u
"qIsNull(arg1) ? arg1 : std::sinh(arg1)"_s;
1646 }
else if (
name == u
"sqrt"_s && argc == 1) {
1647 expression = u
"std::sqrt(arg1)"_s;
1648 }
else if (
name == u
"tan"_s && argc == 1) {
1649 expression = u
"qIsNull(arg1) ? arg1 : std::tan(arg1)"_s;
1650 }
else if (
name == u
"tanh"_s && argc == 1) {
1651 expression = u
"qIsNull(arg1) ? arg1 : std::tanh(arg1)"_s;
1652 }
else if (
name == u
"trunc"_s && argc == 1) {
1653 expression = u
"std::trunc(arg1)"_s;
1668 return u
"QtDebugMsg"_s;
1670 return u
"QtInfoMsg"_s;
1672 return u
"QtWarningMsg"_s;
1674 return u
"QtCriticalMsg"_s;
1678bool QQmlJSCodeGenerator::inlineConsoleMethod(
const QString &
name,
int argc,
int argv)
1687 m_body += u
" bool firstArgIsCategory = false;\n";
1695 const bool firstArgIsReference = argc > 0
1698 if (firstArgIsReference) {
1699 m_body += u
" QObject *firstArg = ";
1707 m_body += u
" const QLoggingCategory *category = aotContext->resolveLoggingCategory(";
1708 m_body += firstArgIsReference ? u
"firstArg" : u
"nullptr";
1709 m_body += u
", &firstArgIsCategory);\n";
1710 m_body += u
" if (category && category->isEnabled(" +
type + u
")) {\n";
1712 m_body += u
" const QString message = ";
1717 if (firstArgIsReference) {
1718 m_body += u
"(firstArgIsCategory ? QString() : (" + firstArgStringConversion;
1720 m_body += u
".append(QLatin1Char(' ')))).append(";
1724 m_body += firstArgStringConversion;
1726 m_body += u
".append(QLatin1Char(' ')).append(";
1729 for (
int i = 1;
i < argc; ++
i) {
1731 m_body += u
".append(QLatin1Char(' ')).append("_s;
1741 m_body += u
" aotContext->writeToConsole(" +
type + u
", message, category);\n";
1747bool QQmlJSCodeGenerator::inlineArrayMethod(
const QString &
name,
int base,
int argc,
int argv)
1756 const QString qjsListMethod = u
"QJSList(&"_s + baseVar + u
", aotContext->engine)."
1761 if (
name == u
"includes" && argc > 0 && argc < 3) {
1776 if (
name == u
"toString" || (
name == u
"join" && argc < 2)) {
1789 if (
name == u
"slice" && argc < 3) {
1791 for (
int i = 0;
i < argc; ++
i) {
1808 if ((
name == u
"indexOf" ||
name == u
"lastIndexOf") && argc > 0 && argc < 3) {
1831 reject(u
"call to untyped JavaScript function"_s);
1840 if (inlineMathMethod(
name, argc, argv))
1845 if (inlineConsoleMethod(
name, argc, argv))
1851 if (inlineStringMethod(
name,
base, argc, argv))
1856 if (inlineArrayMethod(
name,
base, argc, argv))
1869 m_body += argumentsList(argc, argv, &outVar);
1870 const QString lookup = u
"aotContext->callObjectPropertyLookup("_s + indexString
1873 const QString initialization = u
"aotContext->initCallObjectPropertyLookup("_s
1874 + indexString + u
')';
1876 generateMoveOutVar(outVar);
1901 reject(u
"CallGlobalLookup"_s);
1909 reject(u
"call to untyped JavaScript function"_s);
1915 if (inlineTranslateMethod(
name, argc, argv))
1925 m_body += argumentsList(argc, argv, &outVar);
1926 const QString lookup = u
"aotContext->callQmlContextPropertyLookup("_s + indexString
1928 const QString initialization = u
"aotContext->initCallQmlContextPropertyLookup("_s
1929 + indexString + u
')';
1931 generateMoveOutVar(outVar);
1973 reject(u
"SetUnwindHandlerh"_s);
1978 reject(u
"UnwindDispatch"_s);
2000 m_body += u
"aotContext->engine->throwError("_s
2005 m_skipUntilNextLabel =
true;
2030 reject(u
"PushCatchContext"_s);
2120 reject(u
"TypeofValue"_s);
2135 if (stored->
accessSemantics() != QQmlJSScope::AccessSemantics::Sequence) {
2138 reject(u
"storing an array in a non-sequence type"_s);
2146 for (
int i = 0;
i < argc; ++
i) {
2153 reject(u
"creating a QQmlListProperty not backed by a property"_s);
2164 m_body += initializer.join(u
", "_s);
2174 if (stored->
accessSemantics() != QQmlJSScope::AccessSemantics::Value) {
2175 reject(u
"storing an object literal in a non-value type"_s);
2187 }
else if (isVariantOrPrimitive) {
2190 reject(u
"storing an object literal in an unsupported container %1"_s
2195 bool isExtension =
false;
2197 reject(u
"storing an object literal in a non-structured value type"_s);
2210 m_body += u
" const QMetaObject *meta = ";
2211 if (!isExtension && isVariantOrPrimitive)
2217 for (
int i = 0;
i < classSize; ++
i) {
2220 const int currentArg =
args +
i;
2234 int index =
property.index();
2238 m_body += u
" void *argv[] = { %1, nullptr };\n"_s
2240 m_body += u
" meta->d.static_metacall(reinterpret_cast<QObject *>(";
2242 m_body += u
"), QMetaObject::WriteProperty, ";
2252 if (argc > classSize)
2253 reject(u
"non-literal keys of object literals"_s);
2289 u
"aotContext->thisObject()"_s)
2307 generateJumpCodeWithTypeConversions(
offset);
2309 m_skipUntilNextLabel =
true;
2321 generateJumpCodeWithTypeConversions(
offset);
2333 generateJumpCodeWithTypeConversions(
offset);
2341 m_body += u
"if (!context->engine->hasException()) "_s;
2342 generateJumpCodeWithTypeConversions(
offset);
2356 generateExceptionCheck();
2366 u
"QJSPrimitiveValue(QJSPrimitiveNull()).equals("_s
2380 u
"!QJSPrimitiveValue(QJSPrimitiveNull()).equals("_s
2387QString QQmlJSCodeGenerator::eqIntExpression(
int lhsConst)
2422 return var + u
" = QVariant(aotContext->lookupResultMetaType("_s
2437 return var + u
".data()"_s;
2440 if (stored->
accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
2465 return var + u
".metaType()"_s;
2468 if (stored->
accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
2487 eqIntExpression(lhsConst)) + u
";\n"_s;
2496 u
"!("_s + eqIntExpression(lhsConst) + u
')') + u
";\n"_s;
2502 generateEqualityOperation(lhs, u
"equals"_s,
false);
2508 generateEqualityOperation(lhs, u
"equals"_s,
true);
2514 generateCompareOperation(lhs, u
">"_s);
2520 generateCompareOperation(lhs, u
">="_s);
2526 generateCompareOperation(lhs, u
"<"_s);
2532 generateCompareOperation(lhs, u
"<="_s);
2538 generateEqualityOperation(lhs, u
"strictlyEquals"_s,
false);
2544 generateEqualityOperation(lhs, u
"strictlyEquals"_s,
true);
2584 genericContained, outputContent,
2588 genericContained, outputContent,
2589 u
'(' +
metaObject(contained) + u
")->cast("_s + inputConversion + u
')');
2614 reject(u
"unsupported type assertion"_s);
2621 generateUnaryOperation(u
"!"_s);
2627 generateUnaryOperation(u
"+"_s);
2633 generateUnaryOperation(u
"-"_s);
2639 generateUnaryOperation(u
"~"_s);
2645 generateInPlaceOperation(u
"++"_s);
2651 generateInPlaceOperation(u
"--"_s);
2657 generateArithmeticOperation(lhs, u
"+"_s);
2663 generateArithmeticOperation(lhs, u
"&"_s);
2669 generateArithmeticOperation(lhs, u
"|"_s);
2675 generateArithmeticOperation(lhs, u
"^"_s);
2681 generateShiftOperation(lhs, u
">>"_s);
2687 generateShiftOperation(lhs, u
">>"_s);
2693 generateShiftOperation(lhs, u
"<<"_s);
2699 generateArithmeticConstOperation(rhs, u
"&"_s);
2705 generateArithmeticConstOperation(rhs, u
"|"_s);
2711 generateArithmeticConstOperation(rhs, u
"^"_s);
2717 generateArithmeticConstOperation(rhs & 0x1f, u
">>"_s);
2723 generateArithmeticConstOperation(rhs & 0x1f, u
">>"_s);
2729 generateArithmeticConstOperation(rhs & 0x1f, u
"<<"_s);
2749 u
"QQmlPrivate::jsExponentiate("_s + lhsString + u
", "_s + rhsString + u
')');
2756 generateArithmeticOperation(lhs, u
"*"_s);
2762 generateArithmeticOperation(lhs, u
"/"_s);
2781 u
'(' + lhsVar + u
" % "_s + rhsVar + u
')');
2788 generateArithmeticOperation(lhs, u
"-"_s);
2817 .value(accumulatorIn.value().content.
storedType());
2824 if (labelIt != m_labels.
constEnd()) {
2825 m_body += *labelIt + u
":;\n"_s;
2826 m_skipUntilNextLabel =
false;
2854 if (!m_skipUntilNextLabel)
2855 generateJumpCodeWithTypeConversions(0);
2860 m_body += u
"aotContext->setInstructionPointer("_s
2864void QQmlJSCodeGenerator::generateExceptionCheck()
2866 m_body += u
"if (aotContext->engine->hasError())\n"_s;
2870void QQmlJSCodeGenerator::generateEqualityOperation(
int lhs,
const QString &function,
bool invert)
2873 const bool strictlyComparableWithVar =
function ==
"strictlyEquals"_L1
2875 auto isComparable = [&]() {
2884 if (strictlyComparableWithVar)
2893 if (!isComparable()) {
2912 }
else if (strictlyComparableWithVar) {
2915 !registerVariableName.
isEmpty()) {
2928 :
m_state.accumulatorVariableIn)
2929 + (
invert ? u
" != "_s : u
" == "_s) + u
"nullptr)"_s;
2938 m_state.accumulatorIn().storedType(), primitive,
2945void QQmlJSCodeGenerator::generateCompareOperation(
int lhs,
const QString &cppOperator)
2959 + u
' ' + cppOperator + u
' '
2965void QQmlJSCodeGenerator::generateArithmeticOperation(
int lhs,
const QString &cppOperator)
2967 generateArithmeticOperation(
2975void QQmlJSCodeGenerator::generateShiftOperation(
int lhs,
const QString &cppOperator)
2977 generateArithmeticOperation(
2985void QQmlJSCodeGenerator::generateArithmeticOperation(
2996 u
'(' + lhs + u
' ' + cppOperator + u
' ' + rhs + u
')');
3000void QQmlJSCodeGenerator::generateArithmeticConstOperation(
int rhsConst,
const QString &cppOperator)
3002 generateArithmeticOperation(
3010void QQmlJSCodeGenerator::generateUnaryOperation(
const QString &cppOperator)
3032void QQmlJSCodeGenerator::generateInPlaceOperation(
const QString &cppOperator)
3055 m_body += u
"auto converted = "_s +
var + u
";\n"_s;
3058 + cppOperator + u
"converted)"_s) + u
";\n"_s;
3063 const QString &resultPreparation)
3065 if (!resultPreparation.
isEmpty())
3066 m_body += resultPreparation + u
";\n"_s;
3067 m_body += u
"while (!"_s + lookup + u
") {\n"_s;
3069 m_body += initialization + u
";\n"_s;
3070 generateExceptionCheck();
3071 if (!resultPreparation.
isEmpty())
3072 m_body += resultPreparation + u
";\n"_s;
3076void QQmlJSCodeGenerator::generateJumpCodeWithTypeConversions(
int relativeOffset)
3081 if (annotation != m_annotations->
constEnd()) {
3082 const auto &conversions = annotation->second.typeConversions;
3084 for (
auto regIt = conversions.constBegin(), regEnd = conversions.constEnd();
3085 regIt != regEnd; ++regIt) {
3086 int registerIndex = regIt.key();
3100 currentType =
it.value().content;
3105 if (currentType == targetType
3110 Q_ASSERT(m_registerVariables.contains(registerIndex));
3111 const auto ¤tRegisterVariables = m_registerVariables[registerIndex];
3113 if (
variable == currentRegisterVariables.end() || *
variable == currentVariable)
3117 conversionCode += u
" = "_s;
3118 conversionCode +=
conversion(currentType, targetType, currentVariable);
3119 conversionCode += u
";\n"_s;
3123 if (relativeOffset) {
3125 if (labelIt == m_labels.
end())
3127 conversionCode += u
" goto "_s + *labelIt + u
";\n"_s;
3130 if (!conversionCode.
isEmpty())
3131 m_body += u
"{\n"_s + conversionCode + u
"}\n"_s;
3136 auto it = m_registerVariables.find(
index);
3137 if (
it != m_registerVariables.end()) {
3151 return u
"std::move(" +
var + u
")";
3171 return it.value().content;
3245 return u
"static_cast<"_s + to->
internalName() + u
" *>(nullptr)"_s;
3247 if (!
zero.isEmpty())
3250 return u
"std::numeric_limits<float>::quiet_NaN()"_s;
3252 return u
"std::numeric_limits<double>::quiet_NaN()"_s;
3263 return u
"static_cast<"_s + to->
internalName() + u
" *>(nullptr)"_s;
3265 return u
"QJSValue(QJSValue::NullValue)"_s;
3267 return u
"QJSPrimitiveValue(QJSPrimitiveNull())"_s;
3269 return u
"QVariant::fromValue<std::nullptr_t>(nullptr)"_s;
3271 if (!
zero.isEmpty())
3287 if (from->
accessSemantics() == QQmlJSScope::AccessSemantics::Reference) {
3288 if (to->
accessSemantics() == QQmlJSScope::AccessSemantics::Reference) {
3303 return u
'(' +
variable + u
" != nullptr)"_s;
3311 if (isJsValue(from) && isJsValue(to))
3323 return u
"QJSNumberCoercion::toInteger("_s +
variable + u
')';
3325 return u
"uint(QJSNumberCoercion::toInteger("_s +
variable + u
"))"_s;
3330 if (isBoolOrNumber(from) && isBoolOrNumber(to))
3336 return variable + u
".toDouble()"_s;
3338 return variable + u
".toBoolean()"_s;
3340 return variable + u
".toInteger()"_s;
3342 return u
"uint("_s +
variable + u
".toInteger())"_s;
3344 return variable + u
".toString()"_s;
3346 return u
"QJSValue(QJSPrimitiveValue("_s +
variable + u
"))"_s;
3348 return variable + u
".toVariant()"_s;
3350 return u
"static_cast<"_s + to->
internalName() + u
" *>(nullptr)"_s;
3353 if (isJsValue(from)) {
3355 return variable + u
".toPrimitive()"_s;
3357 return variable + u
".toVariant(QJSValue::RetainJSObjects)"_s;
3358 return u
"qjsvalue_cast<"_s + castTargetName(to) + u
">("_s +
variable + u
')';
3370 return u
"QJSPrimitiveValue("_s +
variable + u
')';
3374 return u
"QJSPrimitiveValue(int("_s +
variable + u
"))"_s;
3376 return u
"QJSPrimitiveValue(double("_s +
variable + u
"))"_s;
3381 return u
"aotContext->engine->toScriptValue("_s +
variable + u
')';
3385 return u
"QQmlListReference("_s +
variable + u
", aotContext->qmlEngine())"_s;
3386 return u
"aotContext->engine->fromVariant<"_s + castTargetName(to) + u
">("_s
3391 return u
"QVariant::fromValue("_s +
variable + u
')';
3395 return variable + u
".toString()"_s;
3400 return u
"QUrl("_s +
variable + u
')';
3405 return u
"QString::fromUtf8("_s +
variable + u
')';
3413 for (
const auto &originType : {
3418 for (
const auto &targetType : {
3424 return u
"aotContext->engine->coerceValue<%1, %2>(%3)"_s.
arg(
3425 originType->internalName(), targetType->internalName(),
variable);
3432 const auto retrieveFromPrimitive = [&](
3436 return expression + u
".toBoolean()"_s;
3438 return expression + u
".toInteger()"_s;
3440 return u
"uint("_s + expression + u
".toInteger())"_s;
3442 return expression + u
".toDouble()"_s;
3444 return u
"float("_s + expression + u
".toDouble())"_s;
3446 return expression + u
".toString()"_s;
3450 if (!retrieveFromPrimitive(from, u
"x"_s).isEmpty()) {
3451 const QString retrieve = retrieveFromPrimitive(
3458 return u
"aotContext->engine->coerceValue<"_s + castTargetName(from) + u
", "
3459 + castTargetName(to) + u
">("_s +
variable + u
')';
3467 Q_ASSERT(retrieveFromPrimitive(from, u
"x"_s).isEmpty());
3483 bool isExtension =
false;
3488 const auto argumentTypes = ctor.parameters();
3512 reject(u
"internal conversion into unsupported wrapper type."_s);
3515 bool isExtension =
false;
3520 containedTo, containedFrom, &isExtension); ctor.isValid()) {
3521 const auto argumentTypes = ctor.parameters();
3541 return u
"[&](){ auto arg = " +
input
3542 + u
"; return aotContext->constructValueType("_s +
metaType(containedTo)
3546 + u
", "_s + argPointer + u
"); }()"_s;
3549 reject(u
"internal conversion with incompatible or ambiguous types"_s);
3555 setError(u
"Cannot generate efficient code for %1"_s.arg(thing));
3559 : accumulatorOut(
generator->m_state.accumulatorOut())
3560 , accumulatorVariableIn(
generator->m_state.accumulatorVariableIn)
3561 , accumulatorVariableOut(
generator->m_state.accumulatorVariableOut)
3564 if (accumulatorVariableOut.
isEmpty())
3574 if (!resolver->
equals(origStored, stored)
3579 generator->m_state.accumulatorVariableOut = storable ? u
"retrieved"_s :
QString();
3584 +
generator->m_state.accumulatorVariableOut + u
";\n";
3586 }
else if (
generator->m_state.accumulatorVariableIn ==
generator->m_state.accumulatorVariableOut
3593 generator->m_state.accumulatorVariableIn
3594 =
generator->m_state.accumulatorVariableIn + u
"_moved"_s;
3597 + u
" = std::move("_s +
generator->m_state.accumulatorVariableOut + u
");\n"_s;
3603 if (accumulatorVariableOut !=
generator->m_state.accumulatorVariableOut) {
3605 generator->m_state.accumulatorOut(), accumulatorOut,
3606 generator->m_state.accumulatorVariableOut) + u
";\n"_s;
3609 generator->m_state.accumulatorVariableOut = accumulatorVariableOut;
3610 }
else if (accumulatorVariableIn !=
generator->m_state.accumulatorVariableIn) {
3612 generator->m_state.accumulatorVariableIn = accumulatorVariableIn;
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
iterator find(const Key &key)
const_iterator constEnd() const
T value(const Key &key, const T &defaultValue) const
qsizetype size() const noexcept
Returns the number of items in the hash.
const_iterator constFind(const Key &key) const noexcept
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
void generate_UPlus() override
void generate_Resume(int) override
void generate_DefineObjectLiteral(int internalClassId, int argc, int args) override
QString consumedAccumulatorVariableIn() const
void generate_CmpNeInt(int lhs) override
void generate_LoadReg(int reg) override
bool shouldMoveRegister(int index) const
void generate_LoadZero() override
void generate_ShrConst(int value) override
QString convertStored(const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to, const QString &variable)
void generateLookup(const QString &lookup, const QString &initialization, const QString &resultPreparation=QString())
void generate_LoadProperty(int nameIndex) override
QString contentType(const QQmlJSRegisterContent &content, const QString &var)
void generate_StoreReg(int reg) override
void generate_StoreLocal(int index) override
void generate_GetLookup(int index) override
void generate_StoreNameSloppy(int nameIndex) override
void generate_Shl(int lhs) override
QQmlJSCodeGenerator(const QV4::Compiler::Context *compilerContext, const QV4::Compiler::JSUnitGenerator *unitGenerator, const QQmlJSTypeResolver *typeResolver, QQmlJSLogger *logger)
void generate_LoadName(int nameIndex) override
void generate_IteratorNext(int value, int done) override
void generate_Exp(int lhs) override
void generate_MoveRegExp(int regExpId, int destReg) override
QString consumedRegisterVariable(int index) const
void generate_CmpInstanceOf(int lhs) override
void generate_JumpNoException(int offset) override
void generate_IteratorNextForYieldStar(int iterator, int object) override
void generate_StoreScopedLocal(int scope, int index) override
void generate_CallName(int name, int argc, int argv) override
void generate_CmpStrictNotEqual(int lhs) override
void generate_ThrowOnNullOrUndefined() override
void generate_CallQmlContextPropertyLookup(int index, int argc, int argv) override
void generate_PopScriptContext() override
void generate_PopContext() override
QString convertContained(const QQmlJSRegisterContent &from, const QQmlJSRegisterContent &to, const QString &variable)
void generate_LoadQmlContextPropertyLookup(int index) override
QString conversion(const QQmlJSRegisterContent &from, const QQmlJSRegisterContent &to, const QString &variable)
void generate_LoadInt(int value) override
void generate_ThrowException() override
QString registerVariable(int index) const
QQmlJSRegisterContent registerType(int index) const
void generate_Jump(int offset) override
void generate_BitOr(int lhs) override
void generate_PushCatchContext(int index, int name) override
void generate_DestructureRestElement() override
void generate_Decrement() override
void generate_Increment() override
void generate_CmpEqNull() override
void generate_DeleteProperty(int base, int index) override
QString errorReturnValue()
void generate_CmpGe(int lhs) override
void generate_CmpEq(int lhs) override
void generate_StoreProperty(int name, int baseReg) override
void generate_UnwindDispatch() override
void generate_LoadElement(int base) override
void generate_Sub(int lhs) override
void generate_GetIterator(int iterator) override
void generate_CmpLe(int lhs) override
void generate_Div(int lhs) override
void generate_LoadLocal(int index) override
void generate_CreateRestParameter(int argIndex) override
void generate_SetLookup(int index, int base) override
void generate_As(int lhs) override
void generate_ToObject() override
void generate_LoadTrue() override
void generate_CallWithSpread(int func, int thisObject, int argc, int argv) override
void addInclude(const QString &include)
void generate_Mod(int lhs) override
QString metaTypeFromName(const QQmlJSScope::ConstPtr &type) const
QQmlJSAotFunction run(const Function *function, const InstructionAnnotations *annotations, QQmlJS::DiagnosticMessage *error)
void generate_StoreNameStrict(int name) override
void generate_CreateClass(int classIndex, int heritage, int computedNames) override
void generate_CallValue(int name, int argc, int argv) override
void generateEnumLookup(int index)
virtual QString metaType(const QQmlJSScope::ConstPtr &type)
void reject(const QString &thing)
QString setLookupPreparation(const QQmlJSRegisterContent &content, const QString &arg, int lookup)
void generate_BitAndConst(int rhs) override
void generate_LoadSuperConstructor() override
void generate_LoadUndefined() override
Verdict startInstruction(QV4::Moth::Instr::Type) override
void generate_CallPossiblyDirectEval(int argc, int argv) override
void generate_TypeofValue() override
void generate_LoadGlobalLookup(int index) override
void generate_TailCall(int func, int thisObject, int argc, int argv) override
void generate_MoveReg(int srcReg, int destReg) override
void generate_PushBlockContext(int index) override
void generate_ConvertThisToObject() override
void generate_CmpStrictEqual(int lhs) override
void generate_Debug() override
void generate_YieldStar() override
void generate_DeleteName(int name) override
void generate_BitAnd(int lhs) override
void generate_CmpNeNull() override
void generate_Construct(int func, int argc, int argv) override
void generate_CallWithReceiver(int name, int thisObject, int argc, int argv) override
void generate_UnwindToLabel(int level, int offset) override
void generate_CreateMappedArgumentsObject() override
void generate_LoadOptionalProperty(int name, int offset) override
void generate_JumpNotUndefined(int offset) override
void generate_GetException() override
void generateSetInstructionPointer()
void generate_ShlConst(int rhs) override
void generate_JumpFalse(int offset) override
QString getLookupPreparation(const QQmlJSRegisterContent &content, const QString &var, int lookup)
void generate_CmpLt(int lhs) override
void generate_GetTemplateObject(int index) override
void generate_StoreElement(int base, int index) override
void generate_CmpGt(int lhs) override
void generate_Ret() override
void generate_CreateUnmappedArgumentsObject() override
void generate_SetUnwindHandler(int offset) override
void generate_StoreSuperProperty(int property) override
void generate_DefineArray(int argc, int args) override
void generate_JumpTrue(int offset) override
void generate_CheckException() override
void generate_PushWithContext() override
void generate_CreateCallContext() override
void generate_UNot() override
QString changedRegisterVariable() const
QString contentPointer(const QQmlJSRegisterContent &content, const QString &var)
void generate_UShrConst(int rhs) override
void generate_UShr(int lhs) override
void generate_ConstructWithSpread(int func, int argc, int argv) override
void generate_BitXorConst(int rhs) override
void generate_IteratorClose(int done) override
void generate_TypeofName(int name) override
void generate_LoadImport(int index) override
void generate_BitOrConst(int rhs) override
void generate_BitXor(int lhs) override
void generate_LoadConst(int index) override
void generate_CmpNe(int lhs) override
virtual QString metaObject(const QQmlJSScope::ConstPtr &objectType)
void generate_CallProperty(int name, int base, int argc, int argv) override
void generate_InitializeBlockDeadTemporalZone(int firstReg, int count) override
void generate_CloneBlockContext() override
void generate_Mul(int lhs) override
void generate_LoadSuperProperty(int property) override
void generate_LoadFalse() override
void generate_CallPropertyLookup(int lookupIndex, int base, int argc, int argv) override
void generate_SetException() override
void generate_LoadNull() override
void generate_DeadTemporalZoneCheck(int name) override
void generate_PushScriptContext(int index) override
void generate_CmpEqInt(int lhs) override
void generate_UCompl() override
void generate_DeclareVar(int varName, int isDeletable) override
void generate_GetOptionalLookup(int index, int offset) override
void generate_Yield() override
void generate_Add(int lhs) override
void generate_CmpIn(int lhs) override
void generate_LoadRuntimeString(int stringId) override
void generate_UMinus() override
void generate_Shr(int lhs) override
void endInstruction(QV4::Moth::Instr::Type) override
void generate_LoadScopedLocal(int scope, int index) override
void generate_CallGlobalLookup(int index, int argc, int argv) override
QString metaTypeFromType(const QQmlJSScope::ConstPtr &type) const
void generate_LoadClosure(int value) override
void generate_MoveConst(int constIndex, int destTemp) override
int firstRegisterIndex() const
const QV4::Compiler::JSUnitGenerator * m_jsUnitGenerator
bool isArgument(int registerIndex) const
static bool instructionManipulatesContext(QV4::Moth::Instr::Type type)
const Function * m_function
const QQmlJSTypeResolver * m_typeResolver
QQmlJS::DiagnosticMessage * m_error
State initialState(const Function *function)
State nextStateFromAnnotations(const State &oldState, const InstructionAnnotations &annotations)
void setError(const QString &message, int instructionOffset)
QQmlJSRegisterContent argumentType(int registerIndex) const
QQmlJSRegisterContent storedIn(const QQmlJSScope::ConstPtr &newStoredType) const
QString descriptiveName() const
QQmlJSScope::ConstPtr scopeType() const
uint importNamespace() const
bool isConversion() const
QList< QQmlJSScope::ConstPtr > conversionOrigins() const
bool isImportNamespace() const
ContentVariant variant() const
QQmlJSScope::ConstPtr type() const
QQmlJSScope::ConstPtr storedType() const
QQmlJSMetaEnum enumeration() const
QString enumMember() const
bool isEnumeration() const
AnnotatedScope extensionType() const
ScopeType scopeType() const
QString internalName() const
bool isReferenceType() const
static QQmlJSScope::ConstPtr nonCompositeBaseType(const QQmlJSScope::ConstPtr &type)
AccessSemantics accessSemantics() const
bool isListProperty() const
QString augmentedInternalName() const
QQmlJSMetaProperty property(const QString &name) const
QQmlJSScope::ConstPtr baseType() const
QQmlJSScope::ConstPtr valueType() const
bool equals(const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const
QQmlJSRegisterContent original(const QQmlJSRegisterContent &type) const
QQmlJSRegisterContent merge(const QQmlJSRegisterContent &a, const QQmlJSRegisterContent &b) const
QQmlJSScope::ConstPtr dateTimeType() const
QQmlJSRegisterContent memberType(const QQmlJSRegisterContent &type, const QString &name) const
QQmlJSMetaMethod selectConstructor(const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument, bool *isExtension) const
QQmlJSScope::ConstPtr stringType() const
QQmlJSScope::ConstPtr listPropertyType() const
QQmlJSScope::ConstPtr nullType() const
QQmlJSScope::ConstPtr timeType() const
QQmlJSScope::ConstPtr genericType(const QQmlJSScope::ConstPtr &type, ComponentIsGeneric allowComponent=ComponentIsGeneric::No) const
bool areEquivalentLists(const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const
bool registerIsStoredIn(const QQmlJSRegisterContent ®, const QQmlJSScope::ConstPtr &type) const
bool canPopulate(const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument, bool *isExtension) const
QQmlJSScope::ConstPtr containedType(const QQmlJSRegisterContent &container) const
QQmlJSScope::ConstPtr jsPrimitiveType() const
bool isNumeric(const QQmlJSRegisterContent &type) const
QQmlJSScope::ConstPtr uint8Type() const
QQmlJSScope::ConstPtr byteArrayType() const
QQmlJSScope::ConstPtr boolType() const
QQmlJSScope::ConstPtr qObjectListType() const
QQmlJSScope::ConstPtr jsGlobalObject() const
bool registerContains(const QQmlJSRegisterContent ®, const QQmlJSScope::ConstPtr &type) const
bool isIntegral(const QQmlJSRegisterContent &type) const
bool canHold(const QQmlJSScope::ConstPtr &container, const QQmlJSScope::ConstPtr &contained) const
bool isPrimitive(const QQmlJSRegisterContent &type) const
QQmlJSScope::ConstPtr jsValueType() const
QQmlJSRegisterContent globalType(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr originalType(const QQmlJSScope::ConstPtr &type) const
QQmlJSRegisterContent valueType(const QQmlJSRegisterContent &list) const
QQmlJSScope::ConstPtr originalContainedType(const QQmlJSRegisterContent &container) const
QQmlJSScope::ConstPtr uint16Type() const
QQmlJSScope::ConstPtr comparableType(const QQmlJSScope::ConstPtr &type) const
bool isTriviallyCopyable(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr int32Type() const
QQmlJSScope::ConstPtr voidType() const
QQmlJSScope::ConstPtr metaObjectType() const
QQmlJSScope::ConstPtr realType() const
QQmlJSScope::ConstPtr urlType() const
bool isUnsignedInteger(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr dateType() const
QQmlJSScope::ConstPtr typeForConst(QV4::ReturnedValue rv) const
bool isSignedInteger(const QQmlJSScope::ConstPtr &type) const
QQmlJSRegisterContent scopedType(const QQmlJSScope::ConstPtr &scope, const QString &name) const
QQmlJSScope::ConstPtr qObjectType() const
QQmlJSScope::ConstPtr varType() const
QQmlJSScope::ConstPtr variantMapType() const
QQmlJSScope::ConstPtr floatType() const
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
void clear()
Clears the contents of the string and makes it null.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString & append(QChar c)
int currentInstructionOffset() const
int absoluteOffset(int relativeOffset) const
int nextInstructionOffset() const
QSet< QString >::iterator it
Combined button and popup list for selecting options.
#define QT_WARNING_DISABLE_CLANG(text)
static const QCssKnownValue origins[NumKnownOrigins - 1]
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError * error
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
int qFpClassify(qfloat16 f) noexcept
GLenum GLuint GLint level
GLsizei GLenum GLenum * types
GLenum GLenum GLsizei count
GLenum GLuint GLintptr offset
GLenum GLenum GLenum input
static QString toNumericString(double value)
static QString messageTypeForMethod(const QString &method)
#define BYTECODE_UNIMPLEMENTED()
#define INJECT_TRACE_INFO(function)
static QString minExpression(int argc)
static QString maxExpression(int argc)
static bool isTypeStorable(const QQmlJSTypeResolver *resolver, const QQmlJSScope::ConstPtr &type)
bool canCompareWithQObject(const QQmlJSTypeResolver *typeResolver, const QQmlJSRegisterContent &lhsContent, const QQmlJSRegisterContent &rhsContent)
bool canCompareWithQUrl(const QQmlJSTypeResolver *typeResolver, const QQmlJSRegisterContent &lhsContent, const QQmlJSRegisterContent &rhsContent)
bool canStrictlyCompareWithVar(const QQmlJSTypeResolver *typeResolver, const QQmlJSRegisterContent &lhsContent, const QQmlJSRegisterContent &rhsContent)
#define Q_ASSERT_X(cond, x, msg)
static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &errorSource, qsizetype errorPosition)
QRandomGenerator generator(sseq)
obj metaObject() -> className()
AccumulatorConverter(QQmlJSCodeGenerator *generator)
QString accumulatorVariableOut
QString accumulatorVariableIn
QList< QQmlJSRegisterContent > argumentTypes
QQmlJSScope::ConstPtr qmlScope
QQmlJSScope::ConstPtr returnType
const QQmlJSRegisterContent & accumulatorIn() const
VirtualRegisters registers
int changedRegisterIndex() const
bool canMoveReadRegister(int registerIndex) const
bool isRegisterAffectedBySideEffects(int registerIndex) const
QQmlJSRegisterContent readRegister(int registerIndex) const
const QQmlJSRegisterContent & changedRegister() const
bool hasSideEffects() const
QQmlJSRegisterContent readAccumulator() const
const QQmlJSRegisterContent & accumulatorOut() const
QQmlJSRegisterContent content
QQmlJSScope::ConstPtr scope
static QString toLiteral(const QString &s, QStringView ctor=u"QStringLiteral")
static bool searchBaseAndExtensionTypes(QQmlJSScopePtr type, const Action &check)
std::vector< unsigned > labelInfo
QString jsClassMember(int jsClassId, int member) const
QString lookupName(int index) const
ReturnedValue constant(int idx) const
int lookupNameIndex(int index) const
QString stringForIndex(int index) const
int jsClassSize(int jsClassId) const
static constexpr StaticValue fromReturnedValue(ReturnedValue val)