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 :
QQmlJSCompilePass(unitGenerator, typeResolver, logger, basicBlocks, annotations)
61 , m_context(compilerContext)
66 return u
"QMetaType::fromType<"_s +
type->augmentedInternalName() + u
">()"_s;
71 return u
"[]() { static const auto t = QMetaType::fromName(\""_s
73 + u
"\"); return t; }()"_s;
78 return u
"[](auto *aotContext) { static const auto t = QQmlPrivate::compositeListMetaType("
79 "aotContext->compilationUnit, QStringLiteral(\""_s
81 + u
"\")); return t; }(aotContext)"_s;
86 return u
"[](auto *aotContext) { static const auto t = QQmlPrivate::compositeMetaType("
87 "aotContext->compilationUnit, QStringLiteral(\""_s
89 + u
"\")); return t; }(aotContext)"_s;
97 reject(u
"retrieving the metaObject of a composite type without an element name."_s);
105 return u
'&' + objectType->
internalName() + u
"::staticMetaObject"_s;
112 if (
type->isComposite()) {
118 if (
type->isListProperty() &&
type->valueType()->isComposite()) {
131 bool basicBlocksValidationFailed)
136 QHash<int, int> numRegisterVariablesPerIndex;
138 const auto addVariable
144 const RegisterVariablesKey
key = { seenType->internalName(), registerIndex, lookupIndex };
147 const auto oldSize = m_registerVariables.
size();
148 auto &e = m_registerVariables[
key];
149 if (m_registerVariables.
size() != oldSize) {
150 e.variableName = u
"r%1_%2"_s
152 .arg(numRegisterVariablesPerIndex[registerIndex]++);
161 addVariable(annotation.second.changedRegisterIndex,
162 annotation.second.changedRegister.resultLookupIndex(),
163 annotation.second.changedRegister.storedType());
164 for (
auto it = annotation.second.typeConversions.
begin(),
165 end = annotation.second.typeConversions.end();
168 it.key(),
it.value().content.resultLookupIndex(),
169 it.value().content.storedType());
175 for (
const auto loopLabel : m_context->
labelInfo)
176 m_labels.
insert(loopLabel, u
"label_%1"_s.arg(m_labels.
size()));
187 result.includes.swap(m_includes);
189 if (basicBlocksValidationFailed) {
190 result.code +=
"// QV4_BASIC_BLOCK_VALIDATION_FAILED: This file failed compilation "_L1
191 "with basic blocks validation but compiled without it.\n"_L1;
194 result.code += u
"// %1 at line %2, column %3\n"_s
195 .arg(m_context->
name).arg(m_context->
line).arg(m_context->
column);
197 for (
auto registerIt = m_registerVariables.
cbegin(), registerEnd = m_registerVariables.
cend();
198 registerIt != registerEnd; ++registerIt) {
200 const int registerIndex = registerIt.key().registerIndex;
201 const bool registerIsArgument =
isArgument(registerIndex);
203 result.code += registerIt.key().internalName;
207 = (storedType->
accessSemantics() == QQmlJSScope::AccessSemantics::Reference);
213 if (!registerIsArgument
215 && registerIndex !=
This
219 result.code += registerIt->variableName + u
" = "_s;
229 const bool needsConversion =
argument != original;
230 if (!isPointer && registerIt->numTracked == 1 && !needsConversion) {
240 result.code += registerIt->variableName + u
" = "_s;
243 = u
"(*static_cast<"_s + castTargetName(original.
storedType())
251 result.code += registerIt->variableName;
260 = u
" struct { QV4::ExecutableCompilationUnit *compilationUnit; } c { unit };\n"
261 " const auto *aotContext = &c;\n"
262 " Q_UNUSED(aotContext);\n"_s;
264 if (function->returnType.isValid()) {
265 signature += u
" argTypes[0] = %1;\n"_s.arg(
268 signature += u
" argTypes[0] = QMetaType();\n"_s;
270 result.numArguments = function->argumentTypes.length();
272 signature += u
" argTypes[%1] = %2;\n"_s.arg(
277 result.signature = signature;
285 m_body += u
"aotContext->setReturnValueUndefined();\n"_s;
290 m_body += u
"if (argv[0]) {\n"_s;
293 const auto stored =
ret.storedType();
294 if (contained->isReferenceType() && stored->isReferenceType()) {
295 m_body += u
" *static_cast<"_s
296 + stored->augmentedInternalName()
297 + u
" *>(argv[0]) = nullptr;\n"_s;
299 m_body += u
" *static_cast<"_s + stored->internalName() + u
" *>(argv[0]) = "_s
300 + stored->internalName() + u
"();\n"_s;
302 m_body += u
" const QMetaType returnType = "_s
304 m_body += u
" returnType.destruct(argv[0]);\n"_s;
305 m_body += u
" returnType.construct(argv[0]);\n "_s;
317 m_skipUntilNextLabel =
true;
324 m_body += u
"if (argv[0]) {\n"_s;
326 const QString signalUndefined = u
"aotContext->setReturnValueUndefined();\n"_s;
332 m_body += signalUndefined;
337 m_body += u
" if (!"_s +
in + u
".isValid())\n"_s;
338 m_body += u
" "_s + signalUndefined;
341 m_body += u
" if ("_s +
in + u
".type() == QJSPrimitiveValue::Undefined)\n"_s;
342 m_body += u
" "_s + signalUndefined;
345 m_body += u
" if ("_s +
in + u
".isUndefined())\n"_s;
346 m_body += u
" "_s + signalUndefined;
358 || (contained->isReferenceType() && stored->isReferenceType())) {
359 m_body += u
" *static_cast<"_s
360 + stored->augmentedInternalName()
361 + u
" *>(argv[0]) = "_s
368 m_body += u
" returnType.destruct(argv[0]);\n"_s;
369 m_body += u
" returnType.construct(argv[0], "_s
372 m_body += u
" const auto converted = "_s
375 m_body += u
" const QMetaType returnType = "_s
378 m_body += u
" returnType.destruct(argv[0]);\n"_s;
379 m_body += u
" returnType.construct(argv[0], "_s
393 if (
value >= std::numeric_limits<int>::min() &&
value <= std::numeric_limits<int>::max()) {
401 const QString inf = u
"std::numeric_limits<double>::infinity()"_s;
402 return std::signbit(
value) ? (u
'-' + inf) : inf;
405 return u
"std::numeric_limits<double>::quiet_NaN()"_s;
407 return std::signbit(
value) ? u
"-0.0"_s : u
"0"_s;
439 value.booleanValue() ? u
"true"_s : u
"false"_s);
449 reject(u
"unsupported constant type"_s);
534 if (v4Value.isNull()) {
536 }
else if (v4Value.isUndefined()) {
538 }
else if (v4Value.isBoolean()) {
540 input = v4Value.booleanValue() ? u
"true"_s : u
"false"_s;
541 }
else if (v4Value.isInteger()) {
544 }
else if (v4Value.isDouble()) {
548 reject(u
"unknown const type"_s);
587 if (destRegName.isEmpty())
667 const QString initialization = u
"aotContext->initLoadGlobalLookup("_s
684 u
"aotContext->javaScriptGlobalProperty("_s +
QString::number(nameIndex) + u
")")
691 const QString lookup = u
"aotContext->loadContextIdLookup("_s
692 + indexString + u
", "_s
694 const QString initialization = u
"aotContext->initLoadContextIdLookup("_s
695 + indexString + u
')';
706 const QString lookup = u
"aotContext->loadScopeObjectPropertyLookup("_s
707 + indexString + u
", "_s
710 = u
"aotContext->initLoadScopeObjectPropertyLookup("_s
711 + indexString + u
", "_s
718 generateTypeLookup(
index);
732 switch (
type.variant()) {
747 reject(u
"assignment to scope method"_s);
784 m_body += u
"if (!" + indexName + u
".metaType().isValid())\n"
790 reject(u
"LoadElement with non-numeric argument"_s);
799 m_body += u
"if (!QJSNumberCoercion::isArrayIndex("_s + indexName + u
"))\n"_s
803 m_body += u
"if ("_s + indexName + u
" < 0)\n"_s
812 m_body += u
"if ("_s + indexName + u
" < "_s + baseName
813 + u
".count(&"_s + baseName + u
"))\n"_s;
816 baseName + u
".at(&"_s + baseName + u
", "_s
817 + indexName + u
')') + u
";\n"_s;
831 reject(u
"LoadElement on a sequence potentially affected by side effects"_s);
833 reject(u
"LoadElement on a sequence wrapped in a non-sequence type"_s);
835 m_body += u
"if ("_s + indexName + u
" < "_s + baseName + u
".size())\n"_s;
850 reject(u
"StoreElement with non-list base type or non-numeric arguments"_s);
855 reject(u
"indirect StoreElement"_s);
868 m_body += u
"if (QJSNumberCoercion::isArrayIndex("_s + indexName + u
")) {\n"_s;
870 m_body += u
"if ("_s + indexName + u
" >= 0) {\n"_s;
875 m_body += u
" if ("_s + indexName + u
" < "_s + baseName + u
".count(&"_s + baseName
877 m_body += u
" "_s + baseName + u
".replace(&"_s + baseName
878 + u
", "_s + indexName + u
", "_s;
886 reject(u
"LoadElement on a sequence potentially affected by side effects"_s);
888 m_body += u
" if ("_s + indexName + u
" >= " + baseName + u
".size())\n"_s;
889 m_body += u
" QJSList(&"_s + baseName + u
", aotContext->engine).resize("_s
890 + indexName + u
" + 1);\n"_s;
891 m_body += u
" "_s + baseName + u
'[' + indexName + u
"] = "_s;
896 generateWriteBack(
base);
902 reject(u
"LoadProperty"_s);
922 reject(u
"Lookup of enum metatype"_s);
928 if (metaEnum.hasValues()) {
940 const QString enumName = metaEnum.isFlag() ? metaEnum.alias() : metaEnum.name();
942 if (metaEnum.isFlag() && !metaEnum.name().isEmpty())
943 reject(u
"qmltypes misses name entry for flag; did you pass the enum type to Q_FLAG instead of the QFlag type?"
944 "\nType is %1, enum name is %2"_s.arg(scopeType->
internalName(), metaEnum.name()));
945 reject(u
"qmltypes misses name entry for enum"_s);
949 const QString initialization = u
"aotContext->initGetEnumLookup("_s
951 + u
", \""_s + enumName + u
"\", \""_s + enumMember
956void QQmlJSCodeGenerator::generateTypeLookup(
int index)
963 : u
"QQmlPrivate::AOTCompiledContext::InvalidStringId"_s;
967 rejectIfNonQObjectOut(u
"non-QObject singleton type"_s);
968 const QString lookup = u
"aotContext->loadSingletonLookup("_s + indexString
970 const QString initialization = u
"aotContext->initLoadSingletonLookup("_s + indexString
971 + u
", "_s + namespaceString + u
')';
978 rejectIfNonQObjectOut(u
"non-QObject attached type"_s);
979 const QString lookup = u
"aotContext->loadAttachedLookup("_s + indexString
981 const QString initialization = u
"aotContext->initLoadAttachedLookup("_s + indexString
982 + u
", "_s + namespaceString + u
", aotContext->qmlScopeObject)"_s;
987 reject(u
"script lookup"_s);
994 reject(u
"meta-object stored in different type"_s);
996 const QString lookup = u
"aotContext->loadTypeLookup("_s + indexString
998 const QString initialization = u
"aotContext->initLoadTypeLookup("_s + indexString
999 + u
", "_s + namespaceString + u
")"_s;
1008void QQmlJSCodeGenerator::generateVariantEqualityComparison(
1018 m_body += u
"if ("_s + registerName
1019 + u
".metaType() == QMetaType::fromType<QJSPrimitiveValue>()) {\n"_s
1022 u
"static_cast<const QJSPrimitiveValue *>("_s + registerName
1023 + u
".constData())"_s + u
"->type() "_s
1024 + (
invert ? u
"!="_s : u
"=="_s)
1026 ? u
"QJSPrimitiveValue::Null"_s
1027 : u
"QJSPrimitiveValue::Undefined"_s))
1028 + u
";\n} else if ("_s + registerName
1029 + u
".metaType() == QMetaType::fromType<QJSValue>()) {\n"_s
1030 +
m_state.accumulatorVariableOut + u
" = "_s
1032 (
invert ? u
"!"_s :
QString()) + u
"static_cast<const QJSValue *>("_s
1033 + registerName + u
".constData())"_s + u
"->"_s
1036 : u
"isUndefined()"_s))
1042 m_body += u
"else if ("_s + registerName
1043 + u
".metaType().flags().testFlag(QMetaType::PointerToQObject)) {\n"_s
1046 u
"*static_cast<QObject *const *>("_s + registerName
1047 + u
".constData())"_s + (
invert ? u
"!="_s : u
"=="_s)
1049 + u
";\n} else if ("_s + registerName
1050 + u
".metaType() == QMetaType::fromType<std::nullptr_t>()) {\n"_s
1051 +
m_state.accumulatorVariableOut + u
" = "_s
1053 (
invert ? u
"false"_s : u
"true"_s))
1060 (
invert ? (registerName + u
".isValid() ? true : false"_s)
1061 : (registerName + u
".isValid() ? false : true"_s)))
1065void QQmlJSCodeGenerator::generateVariantEqualityComparison(
1071 const auto contained = storableContent.isEnumeration()
1072 ? storableContent.storedType()
1075 if (contained->isReferenceType()) {
1079 + varRegisterName + u
".metaType().flags() & QMetaType::PointerToQObject) "_s
1080 + u
" && "_s +
conversion(storableContent, comparable, typedRegisterName) + u
" == "_s
1089 +
conversion(storableContent, comparable, typedRegisterName)
1090 + u
".strictlyEquals("_s
1095 reject(u
"comparison of non-primitive, non-object type to var"_s);
1098void QQmlJSCodeGenerator::generateArrayInitializer(
int argc,
int argv)
1105 for (
int i = 0;
i < argc; ++
i) {
1112 m_body += initializer.join(u
", "_s);
1116void QQmlJSCodeGenerator::generateWriteBack(
int registerIndex)
1122 !writeBack.
storedType()->isReferenceType();) {
1123 if (writeBackAffectedBySideEffects)
1124 reject(u
"write-back of value affected by side effects"_s);
1126 if (writeBack.isConversion())
1127 reject(u
"write-back of converted value"_s);
1129 const int lookupIndex = writeBack.resultLookupIndex();
1130 if (lookupIndex == -1) {
1140 reject(u
"write-back of non-lookup"_s);
1149 const QString lookup = u
"aotContext->writeBackScopeObjectPropertyLookup("_s
1150 + writeBackIndexString
1153 = u
"aotContext->initLoadScopeObjectPropertyLookup("_s
1154 + writeBackIndexString
1155 + u
", "_s +
contentType(writeBack, writeBackRegister) + u
')';
1163 bool outerAffectedBySideEffects =
false;
1166 if (
it.value().content.resultLookupIndex() == writeBack.baseLookupIndex()) {
1167 outerContent =
it.value().content;
1168 outerRegister =
lookupVariable(outerContent.resultLookupIndex());
1169 outerAffectedBySideEffects =
it.value().affectedBySideEffects;
1174 if (!outerContent.isValid()) {
1176 reject(u
"write-back of lookup across jumps or merges."_s);
1180 Q_ASSERT(!outerRegister.isEmpty());
1182 switch (writeBack.variant()) {
1188 if (writeBack.scopeType()->isReferenceType()) {
1189 const QString lookup = u
"aotContext->writeBackObjectLookup("_s
1190 + writeBackIndexString
1191 + u
", "_s + outerRegister
1193 const QString initialization = u
"aotContext->initGetObjectLookup("_s
1194 + writeBackIndexString
1195 + u
", "_s + outerRegister
1196 + u
", "_s +
contentType(writeBack, writeBackRegister) + u
')';
1200 const QString lookup = u
"aotContext->writeBackValueLookup("_s
1201 + writeBackIndexString
1202 + u
", "_s + valuePointer
1204 const QString initialization = u
"aotContext->initGetValueLookup("_s
1205 + writeBackIndexString
1206 + u
", "_s +
metaObject(writeBack.scopeType())
1207 + u
", "_s +
contentType(writeBack, writeBackRegister) + u
')';
1212 reject(u
"SetLookup on value types (because of missing write-back)"_s);
1215 writeBackRegister = outerRegister;
1216 writeBack = outerContent;
1217 writeBackAffectedBySideEffects = outerAffectedBySideEffects;
1221void QQmlJSCodeGenerator::rejectIfNonQObjectOut(
const QString &
error)
1224 != QQmlJSScope::AccessSemantics::Reference) {
1229void QQmlJSCodeGenerator::rejectIfBadArray()
1232 if (stored->
accessSemantics() != QQmlJSScope::AccessSemantics::Sequence) {
1236 reject(u
"storing an array in a non-sequence type"_s);
1246 reject(u
"creating a QQmlListProperty not backed by a property"_s);
1258bool QQmlJSCodeGenerator::generateContentPointerCheck(
1272 reject(u
"lookup of members of %1 in %2"_s.arg(
1276 bool needsVarContentConversion =
false;
1277 QString processedErrorMessage;
1278 if (actual.storedType()->isReferenceType()) {
1289 needsVarContentConversion =
true;
1290 processedErrorMessage =
errorMessage.arg(u
"undefined");
1292 reject(u
"retrieving metatype from %1"_s.arg(actual.descriptiveName()));
1296 m_body += u
" aotContext->engine->throwError(QJSValue::TypeError, "_s;
1297 m_body += u
"QLatin1String(\"%1\"));\n"_s.arg(processedErrorMessage);
1300 return needsVarContentConversion;
1303QString QQmlJSCodeGenerator::resolveValueTypeContentPointer(
1312QString QQmlJSCodeGenerator::resolveQObjectPointer(
1317 return u
"*static_cast<QObject *const *>("_s +
variable + u
".constData())"_s;
1324 generate_GetLookupHelper(
index);
1327void QQmlJSCodeGenerator::generate_GetLookupHelper(
int index)
1330 reject(u
"lookup of function property."_s);
1339 value = std::exp(1.0);
1340 }
else if (
name == u
"LN10") {
1342 }
else if (
name == u
"LN2") {
1344 }
else if (
name == u
"LOG10E") {
1345 value = log10(std::exp(1.0));
1346 }
else if (
name == u
"LOG2E") {
1348 }
else if (
name == u
"PI") {
1349 value = 3.14159265358979323846;
1350 }
else if (
name == u
"SQRT1_2") {
1351 value = std::sqrt(0.5);
1352 }
else if (
name == u
"SQRT2") {
1353 value = std::sqrt(2.0);
1376 AccumulatorConverter registers(
this);
1386 : u
"QQmlPrivate::AOTCompiledContext::InvalidStringId"_s;
1393 if (!isReferenceType) {
1398 reject(u
"attached object for non-QObject type"_s);
1404 reject(u
"attached object of potentially non-QObject base"_s);
1407 rejectIfNonQObjectOut(u
"non-QObject attached type"_s);
1409 const QString lookup = u
"aotContext->loadAttachedLookup("_s + indexString
1412 const QString initialization = u
"aotContext->initLoadAttachedLookup("_s
1413 + indexString + u
", "_s + namespaceString + u
", "_s
1422 generateTypeLookup(
index);
1432 reject(u
"lookup in QJSValue"_s);
1433 }
else if (isReferenceType) {
1434 const QString inputPointer = resolveQObjectPointer(
1436 u
"Cannot read property '%1' of %2"_s.arg(
1438 const QString lookup = u
"aotContext->getObjectLookup("_s + indexString
1439 + u
", "_s + inputPointer + u
", "_s
1441 const QString initialization = u
"aotContext->initGetObjectLookup("_s
1442 + indexString + u
", "_s + inputPointer
1448 }
else if ((scope->
accessSemantics() == QQmlJSScope::AccessSemantics::Sequence
1460 }
else if (stored->
accessSemantics() == QQmlJSScope::AccessSemantics::Sequence
1468 reject(u
"access to 'length' property of sequence wrapped in non-sequence"_s);
1480 reject(u
"reading from a value that's potentially affected by side effects"_s);
1482 const QString inputContentPointer = resolveValueTypeContentPointer(
1484 u
"Cannot read property '%1' of %2"_s.
arg(
1487 const QString lookup = u
"aotContext->getValueLookup("_s + indexString
1488 + u
", "_s + inputContentPointer
1491 const QString initialization = u
"aotContext->initGetValueLookup("_s
1492 + indexString + u
", "_s
1510 m_body += u
"if (!%1)\n"_s.
arg(accumulatorVarIn);
1511 generateJumpCodeWithTypeConversions(
offset);
1513 m_body += u
"if (!%1.isValid() || ((%1.metaType().flags() & QMetaType::PointerToQObject) "
1514 "&& %1.value<QObject *>() == nullptr))\n"_s.
arg(accumulatorVarIn);
1515 generateJumpCodeWithTypeConversions(
offset);
1517 m_body += u
"if (%1.equals(QJSPrimitiveUndefined()) "
1518 "|| %1.equals(QJSPrimitiveNull()))\n"_s.
arg(accumulatorVarIn);
1519 generateJumpCodeWithTypeConversions(
offset);
1520 }
else if (annotation.changedRegisterIndex ==
Accumulator
1524 m_body += u
"if (%1.isNull() || %1.isUndefined())\n"_s.
arg(accumulatorVarIn);
1525 generateJumpCodeWithTypeConversions(
offset);
1530 generate_GetLookupHelper(
index);
1537 reject(u
"StoreProperty"_s);
1547 return u
"const QMetaType argType = aotContext->lookupResultMetaType("_s
1549 + u
"if (argType.isValid())\n "_s +
arg + u
".convert(argType)";
1567 if (specific.storedType().isNull()) {
1568 reject(u
"SetLookup. Could not find property "
1571 + originalScope->internalName());
1598 m_body += u
"auto converted = "_s
1604 if (preparation.isEmpty())
1607 argType = u
"argType"_s;
1611 argType = variableInType;
1614 switch (originalScope->accessSemantics()) {
1615 case QQmlJSScope::AccessSemantics::Reference: {
1616 const QString basePointer = resolveQObjectPointer(
1618 u
"TypeError: Value is %1 and could not be converted to an object"_s);
1620 const QString lookup = u
"aotContext->setObjectLookup("_s + indexString
1621 + u
", "_s + basePointer + u
", "_s + variableIn + u
')';
1622 const QString initialization = u
"aotContext->initSetObjectLookup("_s
1623 + indexString + u
", "_s + basePointer + u
", "_s + argType + u
')';
1627 case QQmlJSScope::AccessSemantics::Sequence: {
1629 if (propertyName != u
"length"_s) {
1630 reject(u
"setting non-length property on a sequence type"_s);
1634 if (!originalScope->isListProperty()) {
1635 reject(u
"resizing sequence types (because of missing write-back)"_s);
1640 m_body += u
"const int begin = "_s +
object + u
".count(&" +
object + u
");\n"_s;
1641 m_body += u
"const int end = "_s
1642 + (variableIn.startsWith(u
'&') ? variableIn.mid(1) : (u
'*' + variableIn))
1644 m_body += u
"for (int i = begin; i < end; ++i)\n"_s;
1645 m_body += u
" "_s +
object + u
".append(&"_s +
object + u
", nullptr);\n"_s;
1646 m_body += u
"for (int i = begin; i > end; --i)\n"_s;
1647 m_body += u
" "_s +
object + u
".removeLast(&"_s +
object + u
')'
1651 case QQmlJSScope::AccessSemantics::Value: {
1653 const QString baseContentPointer = resolveValueTypeContentPointer(
1654 originalScope,
base,
object,
1655 u
"TypeError: Value is %1 and could not be converted to an object"_s);
1657 const QString lookup = u
"aotContext->setValueLookup("_s + indexString
1658 + u
", "_s + baseContentPointer
1659 + u
", "_s + variableIn + u
')';
1660 const QString initialization = u
"aotContext->initSetValueLookup("_s
1661 + indexString + u
", "_s +
metaObject(originalScope)
1662 + u
", "_s + argType + u
')';
1665 generateWriteBack(baseReg);
1669 case QQmlJSScope::AccessSemantics::None:
1704QString QQmlJSCodeGenerator::argumentsList(
int argc,
int argv,
QString *outVar)
1712 types = u
"QMetaType()"_s;
1713 args = u
"nullptr"_s;
1715 *outVar = u
"callResult"_s;
1717 m_body += outType->augmentedInternalName() + u
' ' + *outVar;
1732 for (
int i = 0;
i < argc; ++
i) {
1739 return u
"void *args[] = { "_s +
args + u
" };\n"_s
1740 + u
"const QMetaType types[] = { "_s +
types + u
" };\n"_s;
1743void QQmlJSCodeGenerator::generateMoveOutVar(
const QString &outVar)
1749 m_body += u
"std::move(" + outVar + u
");\n";
1775 reject(u
"CallProperty"_s);
1778bool QQmlJSCodeGenerator::inlineStringMethod(
const QString &
name,
int base,
int argc,
int argv)
1780 if (
name != u
"arg"_s || argc != 1)
1808bool QQmlJSCodeGenerator::inlineTranslateMethod(
const QString &
name,
int argc,
int argv)
1818 const auto stringArg = [&](
int i) {
1824 const auto intArg = [&](
int i) {
1828 const auto stringRet = [&](
const QString &expression) {
1833 const auto capture = [&]() {
1834 m_body += u
"aotContext->captureTranslation();\n"_s;
1837 if (
name == u
"QT_TRID_NOOP"_s ||
name == u
"QT_TR_NOOP"_s) {
1844 if (
name == u
"QT_TRANSLATE_NOOP"_s) {
1851 if (
name == u
"qsTrId"_s) {
1857 + stringRet(u
"QCoreApplication::translate(nullptr, "_s + stringArg(0) +
1858 u
", nullptr, "_s + intArg(1) + u
")"_s) + u
";\n"_s;
1862 if (
name == u
"qsTr"_s) {
1865 + stringRet(u
"QCoreApplication::translate("_s
1866 + u
"aotContext->translationContext().toUtf8().constData(), "_s
1867 + stringArg(0) + u
", "_s + stringArg(1) + u
", "_s
1868 + intArg(2) + u
")"_s) + u
";\n"_s;
1872 if (
name == u
"qsTranslate"_s) {
1875 + stringRet(u
"QCoreApplication::translate("_s
1876 + stringArg(0) + u
", "_s + stringArg(1) + u
", "_s
1877 + stringArg(2) + u
", "_s + intArg(3) + u
")"_s) + u
";\n"_s;
1889 u
"[&]() { \nauto tmpMax = (qIsNull(arg2) && qIsNull(arg1) && std::copysign(1.0, arg2) == 1) ? arg2 : ((arg2 > arg1 || std::isnan(arg2)) ? arg2 : arg1);\n"_s;
1890 for (
int i = 2;
i < argc;
i++) {
1892 "\ttmpMax = (qIsNull(%1) && qIsNull(tmpMax) && std::copysign(1.0, %1) == 1) ? arg2 : ((%1 > tmpMax || std::isnan(%1)) ? %1 : tmpMax);\n"_L1
1895 expression +=
"return tmpMax;\n}()"_L1;
1905 u
"[&]() { \nauto tmpMin = (qIsNull(arg2) && qIsNull(arg1) && std::copysign(1.0, arg2) == -1) ? arg2 : ((arg2 < arg1 || std::isnan(arg2)) ? arg2 : arg1);\n"_s;
1906 for (
int i = 2;
i < argc;
i++) {
1908 "tmpMin = (qIsNull(%1) && qIsNull(tmpMin) && std::copysign(1.0, %1) == -1) ? arg2 : ((%1 < tmpMin || std::isnan(%1)) ? %1 : tmpMin);\n"_L1
1911 expression +=
"return tmpMin;\n}()"_L1;
1916bool QQmlJSCodeGenerator::inlineMathMethod(
const QString &
name,
int argc,
int argv)
1930 for (
int i = 0;
i < argc; ++
i) {
1937 const QString qNaN = u
"std::numeric_limits<double>::quiet_NaN()"_s;
1938 const QString inf = u
"std::numeric_limits<double>::infinity()"_s;
1943 if (
name == u
"abs" && argc == 1) {
1944 expression = u
"(qIsNull(arg1) ? 0 : (arg1 < 0.0 ? -arg1 : arg1))"_s;
1945 }
else if (
name == u
"acos"_s && argc == 1) {
1946 expression = u
"arg1 > 1.0 ? %1 : std::acos(arg1)"_s.
arg(qNaN);
1947 }
else if (
name == u
"acosh"_s && argc == 1) {
1948 expression = u
"arg1 < 1.0 ? %1 : std::acosh(arg1)"_s.
arg(qNaN);
1949 }
else if (
name == u
"asin"_s && argc == 1) {
1950 expression = u
"arg1 > 1.0 ? %1 : std::asin(arg1)"_s.
arg(qNaN);
1951 }
else if (
name == u
"asinh"_s && argc == 1) {
1952 expression = u
"qIsNull(arg1) ? arg1 : std::asinh(arg1)"_s;
1953 }
else if (
name == u
"atan"_s && argc == 1) {
1954 expression = u
"qIsNull(arg1) ? arg1 : std::atan(arg1)"_s;
1955 }
else if (
name == u
"atanh"_s && argc == 1) {
1956 expression = u
"qIsNull(arg1) ? arg1 : std::atanh(arg1)"_s;
1957 }
else if (
name == u
"atan2"_s) {
1960 }
else if (
name == u
"cbrt"_s && argc == 1) {
1961 expression = u
"std::cbrt(arg1)"_s;
1962 }
else if (
name == u
"ceil"_s && argc == 1) {
1963 expression = u
"(arg1 < 0.0 && arg1 > -1.0) ? std::copysign(0.0, -1.0) : std::ceil(arg1)"_s;
1964 }
else if (
name == u
"clz32"_s && argc == 1) {
1965 expression = u
"qint32(qCountLeadingZeroBits(quint32(QJSNumberCoercion::toInteger(arg1))))"_s;
1966 }
else if (
name == u
"cos"_s && argc == 1) {
1967 expression = u
"std::cos(arg1)"_s;
1968 }
else if (
name == u
"cosh"_s && argc == 1) {
1969 expression = u
"std::cosh(arg1)"_s;
1970 }
else if (
name == u
"exp"_s && argc == 1) {
1971 expression = u
"std::isinf(arg1) "
1972 "? (std::copysign(1.0, arg1) == -1 ? 0.0 : %1) "
1973 ": std::exp(arg1)"_s.
arg(inf);
1974 }
else if (
name == u
"expm1"_s) {
1977 }
else if (
name == u
"floor"_s && argc == 1) {
1978 expression = u
"std::floor(arg1)"_s;
1979 }
else if (
name == u
"fround"_s && argc == 1) {
1980 expression = u
"(std::isnan(arg1) || std::isinf(arg1) || qIsNull(arg1)) "
1982 ": double(float(arg1))"_s;
1983 }
else if (
name == u
"hypot"_s) {
1986 }
else if (
name == u
"imul"_s && argc == 2) {
1987 expression = u
"qint32(quint32(QJSNumberCoercion::toInteger(arg1)) "
1988 "* quint32(QJSNumberCoercion::toInteger(arg2)))"_s;
1989 }
else if (
name == u
"log"_s && argc == 1) {
1990 expression = u
"arg1 < 0.0 ? %1 : std::log(arg1)"_s.
arg(qNaN);
1991 }
else if (
name == u
"log10"_s && argc == 1) {
1992 expression = u
"arg1 < 0.0 ? %1 : std::log10(arg1)"_s.
arg(qNaN);
1993 }
else if (
name == u
"log1p"_s && argc == 1) {
1994 expression = u
"arg1 < -1.0 ? %1 : std::log1p(arg1)"_s.
arg(qNaN);
1995 }
else if (
name == u
"log2"_s && argc == 1) {
1996 expression = u
"arg1 < -0.0 ? %1 : std::log2(arg1)"_s.
arg(qNaN);
1997 }
else if (
name == u
"max"_s && argc >= 2) {
1999 }
else if (
name == u
"min"_s && argc >= 2) {
2001 }
else if (
name == u
"pow"_s) {
2002 expression = u
"QQmlPrivate::jsExponentiate(arg1, arg2)"_s;
2003 }
else if (
name == u
"random"_s && argc == 0) {
2004 expression = u
"QRandomGenerator::global()->generateDouble()"_s;
2005 }
else if (
name == u
"round"_s && argc == 1) {
2006 expression = u
"std::isfinite(arg1) "
2007 "? ((arg1 < 0.5 && arg1 >= -0.5) "
2008 "? std::copysign(0.0, arg1) "
2009 ": std::floor(arg1 + 0.5)) "
2011 }
else if (
name == u
"sign"_s && argc == 1) {
2012 expression = u
"std::isnan(arg1) "
2016 ": (std::signbit(arg1) ? -1.0 : 1.0))"_s.
arg(qNaN);
2017 }
else if (
name == u
"sin"_s && argc == 1) {
2018 expression = u
"qIsNull(arg1) ? arg1 : std::sin(arg1)"_s;
2019 }
else if (
name == u
"sinh"_s && argc == 1) {
2020 expression = u
"qIsNull(arg1) ? arg1 : std::sinh(arg1)"_s;
2021 }
else if (
name == u
"sqrt"_s && argc == 1) {
2022 expression = u
"std::sqrt(arg1)"_s;
2023 }
else if (
name == u
"tan"_s && argc == 1) {
2024 expression = u
"qIsNull(arg1) ? arg1 : std::tan(arg1)"_s;
2025 }
else if (
name == u
"tanh"_s && argc == 1) {
2026 expression = u
"qIsNull(arg1) ? arg1 : std::tanh(arg1)"_s;
2027 }
else if (
name == u
"trunc"_s && argc == 1) {
2028 expression = u
"std::trunc(arg1)"_s;
2043 return u
"QtDebugMsg"_s;
2045 return u
"QtInfoMsg"_s;
2047 return u
"QtWarningMsg"_s;
2049 return u
"QtCriticalMsg"_s;
2053bool QQmlJSCodeGenerator::inlineConsoleMethod(
const QString &
name,
int argc,
int argv)
2062 m_body += u
" bool firstArgIsCategory = false;\n";
2070 const bool firstArgIsReference = argc > 0
2073 if (firstArgIsReference) {
2074 m_body += u
" QObject *firstArg = ";
2076 firstArg.storedType(),
2082 m_body += u
" const QLoggingCategory *category = aotContext->resolveLoggingCategory(";
2083 m_body += firstArgIsReference ? u
"firstArg" : u
"nullptr";
2084 m_body += u
", &firstArgIsCategory);\n";
2085 m_body += u
" if (category && category->isEnabled(" +
type + u
")) {\n";
2087 m_body += u
" const QString message = ";
2089 const auto stringConversion = [&](
int i) ->
QString {
2095 }
else if (stored->
accessSemantics() == QQmlJSScope::AccessSemantics::Sequence) {
2098 + u
", aotContext->engine).toString() + u']'"_s;
2100 reject(u
"converting arguments for console method to string"_s);
2106 if (firstArgIsReference) {
2110 m_body += u
"(firstArgIsCategory ? QString() : (" + firstArgStringConversion;
2112 m_body += u
".append(QLatin1Char(' ')))).append(";
2116 m_body += stringConversion(0);
2118 m_body += u
".append(QLatin1Char(' ')).append(";
2121 for (
int i = 1;
i < argc; ++
i) {
2123 m_body += u
".append(QLatin1Char(' ')).append("_s;
2124 m_body += stringConversion(
i) + u
')';
2131 m_body += u
" aotContext->writeToConsole(" +
type + u
", message, category);\n";
2137bool QQmlJSCodeGenerator::inlineArrayMethod(
const QString &
name,
int base,
int argc,
int argv)
2146 const QString qjsListMethod = u
"QJSList(&"_s + baseVar + u
", aotContext->engine)."
2151 if (
name == u
"includes" && argc > 0 && argc < 3) {
2166 if (
name == u
"toString" || (
name == u
"join" && argc < 2)) {
2179 if (
name == u
"slice" && argc < 3) {
2181 for (
int i = 0;
i < argc; ++
i) {
2189 const auto outType = baseType.storedType()->isListProperty()
2198 if ((
name == u
"indexOf" ||
name == u
"lastIndexOf") && argc > 0 && argc < 3) {
2221 reject(u
"call to untyped JavaScript function"_s);
2231 if (inlineMathMethod(
name, argc, argv))
2234 if (inlineConsoleMethod(
name, argc, argv))
2237 if (inlineStringMethod(
name,
base, argc, argv))
2240 if (inlineArrayMethod(
name,
base, argc, argv))
2249 const QString inputPointer = resolveQObjectPointer(
2251 u
"Cannot call method '%1' of %2"_s.arg(
name));
2258 m_body += argumentsList(argc, argv, &outVar);
2259 const QString lookup = u
"aotContext->callObjectPropertyLookup("_s + indexString
2260 + u
", "_s + inputPointer
2262 const QString initialization = u
"aotContext->initCallObjectPropertyLookup("_s
2263 + indexString + u
')';
2265 generateMoveOutVar(outVar);
2290 reject(u
"CallGlobalLookup"_s);
2298 reject(u
"call to untyped JavaScript function"_s);
2304 if (inlineTranslateMethod(
name, argc, argv))
2314 m_body += argumentsList(argc, argv, &outVar);
2315 const QString lookup = u
"aotContext->callQmlContextPropertyLookup("_s + indexString
2317 const QString initialization = u
"aotContext->initCallQmlContextPropertyLookup("_s
2318 + indexString + u
')';
2320 generateMoveOutVar(outVar);
2355 u
"QDateTime::currentDateTime()"_s) + u
";\n";
2369 constexpr int maxArgc = 7;
2370 for (
int i = 0;
i < std::min(argc, maxArgc); ++
i) {
2379 u
"aotContext->constructDateTime("_s + ctorArgs + u
')') + u
";\n";
2391 const QString error = u
" aotContext->engine->throwError(QJSValue::RangeError, "_s
2392 + u
"QLatin1String(\"Invalid array length\"));\n"_s;
2397 m_body += u
"if (!QJSNumberCoercion::isArrayIndex("_s + indexName + u
")) {\n"_s
2402 m_body += u
"if ("_s + indexName + u
" < 0) {\n"_s
2411 + u
", aotContext->engine).resize("_s
2417 generateArrayInitializer(argc, argv);
2436 reject(u
"SetUnwindHandlerh"_s);
2441 reject(u
"UnwindDispatch"_s);
2464 m_body += u
"aotContext->engine->throwError("_s
2469 m_skipUntilNextLabel =
true;
2494 reject(u
"PushCatchContext"_s);
2539 reject(u
"iterator on non-list type"_s);
2542 if (!iteratorType.isProperty()) {
2543 reject(u
"using non-iterator as iterator"_s);
2551 m_body += u
"QJSListFor"_s
2553 + u
"Iterator "_s + iteratorName + u
";\n";
2559 reject(u
"using non-iterator as iterator"_s);
2566 reject(u
"using non-iterator as iterator"_s);
2567 m_body += u
"const auto &"
2578 if (!iteratorContent.isProperty()) {
2579 reject(u
"using non-iterator as iterator"_s);
2584 const QString iteratorTypeName = iteratorType->internalName();
2589 qjsList = u
"QJSList(&" + listName + u
", aotContext->engine)";
2591 reject(u
"using non-iterator as iterator"_s);
2600 m_body += u
"} else {\n ";
2604 generateJumpCodeWithTypeConversions(
offset);
2647 reject(u
"TypeofValue"_s);
2663 generateArrayInitializer(argc,
args);
2671 if (stored->
accessSemantics() != QQmlJSScope::AccessSemantics::Value) {
2672 reject(u
"storing an object literal in a non-value type"_s);
2686 for (
int i = 0;
i < classSize; ++
i) {
2690 const int currentArg =
args +
i;
2696 for (
int i = classSize;
i < argc;
i += 3) {
2697 const int nameArg =
args +
i + 1;
2705 const int valueArg =
args +
i + 2;
2723 }
else if (isVariantOrPrimitive) {
2726 reject(u
"storing an object literal in an unsupported container %1"_s
2734 bool isExtension =
false;
2736 reject(u
"storing an object literal in a non-structured value type"_s);
2744 m_body += u
" const QMetaObject *meta = ";
2745 if (!isExtension && isVariantOrPrimitive)
2751 for (
int i = 0;
i < classSize; ++
i) {
2754 const int currentArg =
args +
i;
2768 int index =
property.index();
2772 m_body += u
" void *argv[] = { %1, nullptr };\n"_s
2774 m_body += u
" meta->d.static_metacall(reinterpret_cast<QObject *>(";
2776 m_body += u
"), QMetaObject::WriteProperty, ";
2786 if (argc > classSize)
2787 reject(u
"non-literal keys of object literals"_s);
2823 u
"aotContext->thisObject()"_s)
2841 generateJumpCodeWithTypeConversions(
offset);
2842 m_skipUntilNextLabel =
true;
2854 generateJumpCodeWithTypeConversions(
offset);
2865 generateJumpCodeWithTypeConversions(
offset);
2872 m_body += u
"if (!context->engine->hasException()) "_s;
2873 generateJumpCodeWithTypeConversions(
offset);
2886 generateExceptionCheck();
2892 generateEqualityOperation(
2899 generateEqualityOperation(
2910 return var + u
" = QVariant(aotContext->lookupResultMetaType("_s
2925 return var + u
".data()"_s;
2928 if (stored->
accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
2952 return var + u
".metaType()"_s;
2955 if (stored->
accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
2973 generateEqualityOperation(
2975 u
"equals"_s,
false);
2982 generateEqualityOperation(
3002 generateCompareOperation(lhs, u
">"_s);
3008 generateCompareOperation(lhs, u
">="_s);
3014 generateCompareOperation(lhs, u
"<"_s);
3020 generateCompareOperation(lhs, u
"<="_s);
3063 reject(u
"type assertion to unknown type"_s);
3072 if (!isTrivial &&
target->isReferenceType()) {
3074 const QString inputConversion = inputContent.storedType()->isReferenceType()
3081 genericContained, outputContent,
3085 genericContained, outputContent,
3115 reject(u
"non-trivial value type assertion"_s);
3121 generateUnaryOperation(u
"!"_s);
3127 generateUnaryOperation(u
"+"_s);
3133 generateUnaryOperation(u
"-"_s);
3139 generateUnaryOperation(u
"~"_s);
3145 generateInPlaceOperation(u
"++"_s);
3151 generateInPlaceOperation(u
"--"_s);
3157 generateArithmeticOperation(lhs, u
"+"_s);
3163 generateArithmeticOperation(lhs, u
"&"_s);
3169 generateArithmeticOperation(lhs, u
"|"_s);
3175 generateArithmeticOperation(lhs, u
"^"_s);
3181 generateShiftOperation(lhs, u
">>"_s);
3187 generateShiftOperation(lhs, u
">>"_s);
3193 generateShiftOperation(lhs, u
"<<"_s);
3199 generateArithmeticConstOperation(rhs, u
"&"_s);
3205 generateArithmeticConstOperation(rhs, u
"|"_s);
3211 generateArithmeticConstOperation(rhs, u
"^"_s);
3217 generateArithmeticConstOperation(rhs & 0x1f, u
">>"_s);
3223 generateArithmeticConstOperation(rhs & 0x1f, u
">>"_s);
3229 generateArithmeticConstOperation(rhs & 0x1f, u
"<<"_s);
3249 u
"QQmlPrivate::jsExponentiate("_s + lhsString + u
", "_s + rhsString + u
')');
3256 generateArithmeticOperation(lhs, u
"*"_s);
3262 generateArithmeticOperation(lhs, u
"/"_s);
3281 u
'(' + lhsVar + u
" % "_s + rhsVar + u
')');
3288 generateArithmeticOperation(lhs, u
"-"_s);
3328 if (labelIt != m_labels.
constEnd()) {
3329 m_body += *labelIt + u
":;\n"_s;
3330 m_skipUntilNextLabel =
false;
3351 generateJumpCodeWithTypeConversions(0);
3360 if (!m_skipUntilNextLabel)
3361 generateJumpCodeWithTypeConversions(0);
3366 m_body += u
"aotContext->setInstructionPointer("_s
3370void QQmlJSCodeGenerator::generateExceptionCheck()
3372 m_body += u
"if (aotContext->engine->hasError()) {\n"_s;
3377void QQmlJSCodeGenerator::generateEqualityOperation(
3384 const auto rhsContained = rhsIsOptional
3388 const auto lhsContained = lhsIsOptional
3392 const bool isStrict = function ==
"strictlyEquals"_L1;
3393 const bool strictlyComparableWithVar
3395 auto isComparable = [&]() {
3402 if (strictlyComparableWithVar)
3421 if (original.isConversion()) {
3423 return original.storedIn(content.storedType());
3426 return original.storedIn(content.storedType());
3432 if (!isComparable()) {
3435 if (lhsOriginal != lhsContent || rhsOriginal != rhsContent) {
3438 generateEqualityOperation(lhsOriginal, rhsOriginal,
3439 conversion(lhsContent.storedType(), lhsOriginal, lhsName),
3440 conversion(rhsContent.storedType(), rhsOriginal, rhsName),
3445 reject(u
"incomparable types %1 and %2"_s.arg(
3446 rhsContent.descriptiveName(), lhsContent.descriptiveName()));
3452 if (strictlyComparableWithVar) {
3454 if (!lhsName.isEmpty() && rhsName.isEmpty()) {
3456 generateVariantEqualityComparison(rhsContent, lhsName,
invert);
3460 if (!rhsName.isEmpty() && lhsName.isEmpty()) {
3462 generateVariantEqualityComparison(lhsContent, rhsName,
invert);
3467 generateVariantEqualityComparison(rhsContent, rhsName, lhsName,
invert);
3472 generateVariantEqualityComparison(lhsContent, lhsName, rhsName,
invert);
3478 reject(u
"comparison of optional null"_s);
3481 const auto comparison = [&]() ->
QString {
3493 return lhsName +
sign + rhsName;
3496 return invert ? u
"false"_s : u
"true"_s;
3513 if (lhsIsOptional) {
3514 if (rhsIsOptional) {
3517 + lhsName + u
".isValid() && !"_s
3518 + rhsName + u
".isValid()) || "_s;
3521 result += u
'(' + lhsName + u
".isValid() && "_s;
3526 if (rhsIsOptional) {
3527 result += rhsName + u
".isValid() && "_s;
3539 const QString content = u
"*static_cast<QObject **>("_s +
name + u
".data())"_s;
3542 : u
'(' +
name + u
".isValid() ? "_s + content + u
" : nullptr)"_s;
3545 const QString lhsResolved = lhsIsOptional ? resolvedName(lhsName) : lhsName;
3546 const QString rhsResolved = rhsIsOptional ? resolvedName(rhsName) : rhsName;
3560 return lhsName +
sign + rhsName;
3585 + u
'.' + function + u
'(' +
convertStored(rhsType, primitive, rhsName) + u
')';
3593void QQmlJSCodeGenerator::generateCompareOperation(
int lhs,
const QString &cppOperator)
3607 + u
' ' + cppOperator + u
' '
3613void QQmlJSCodeGenerator::generateArithmeticOperation(
int lhs,
const QString &cppOperator)
3615 generateArithmeticOperation(
3623void QQmlJSCodeGenerator::generateShiftOperation(
int lhs,
const QString &cppOperator)
3625 generateArithmeticOperation(
3633void QQmlJSCodeGenerator::generateArithmeticOperation(
3644 u
'(' + lhs + u
' ' + cppOperator + u
' ' + rhs + u
')');
3648void QQmlJSCodeGenerator::generateArithmeticConstOperation(
int rhsConst,
const QString &cppOperator)
3650 generateArithmeticOperation(
3658void QQmlJSCodeGenerator::generateUnaryOperation(
const QString &cppOperator)
3681void QQmlJSCodeGenerator::generateInPlaceOperation(
const QString &cppOperator)
3704 m_body += u
"auto converted = "_s +
var + u
";\n"_s;
3707 + cppOperator + u
"converted)"_s) + u
";\n"_s;
3712 const QString &resultPreparation)
3714 m_body += u
"#ifndef QT_NO_DEBUG\n"_s;
3718 if (!resultPreparation.isEmpty())
3719 m_body += resultPreparation + u
";\n"_s;
3720 m_body += u
"while (!"_s + lookup + u
") {\n"_s;
3722 m_body += u
"#ifdef QT_NO_DEBUG\n"_s;
3726 m_body += initialization + u
";\n"_s;
3727 generateExceptionCheck();
3728 if (!resultPreparation.isEmpty())
3729 m_body += resultPreparation + u
";\n"_s;
3733void QQmlJSCodeGenerator::generateJumpCodeWithTypeConversions(
int relativeOffset)
3739 const auto &conversions = annotation->second.typeConversions;
3741 for (
auto regIt = conversions.constBegin(), regEnd = conversions.constEnd();
3742 regIt != regEnd; ++regIt) {
3747 const int registerIndex = regIt.key();
3761 if (
variable->variableName == currentVariable)
3765 currentVariable = u
"std::move("_s + currentVariable + u
')';
3773 currentType =
it.value().content;
3778 if (currentType == targetType)
3781 conversionCode +=
variable->variableName;
3782 conversionCode += u
" = "_s;
3783 conversionCode +=
conversion(currentType, targetType, currentVariable);
3784 conversionCode += u
";\n"_s;
3788 if (relativeOffset) {
3790 if (labelIt == m_labels.
end())
3792 conversionCode += u
" goto "_s + *labelIt + u
";\n"_s;
3795 m_body += u
"{\n"_s + conversionCode + u
"}\n"_s;
3801 const auto it = m_registerVariables.
constFind(RegisterVariablesKey {
3807 return it->variableName;
3815 if (
it.key().lookupIndex == lookupIndex)
3816 return it->variableName;
3826 return u
"std::move(" +
var + u
")";
3844 return m_registerVariables.
value(RegisterVariablesKey {
3855 return it.value().content;
3864 return it.value().content;
3947 return u
"static_cast<"_s + to->
internalName() + u
" *>(nullptr)"_s;
3949 if (!
zero.isEmpty())
3952 return u
"std::numeric_limits<float>::quiet_NaN()"_s;
3954 return u
"std::numeric_limits<double>::quiet_NaN()"_s;
3958 return u
"QVariant()"_s;
3960 return u
"QJSValue();"_s;
3962 return u
"QJSPrimitiveValue()"_s;
3969 return u
"static_cast<"_s + to->
internalName() + u
" *>(nullptr)"_s;
3971 return u
"QJSValue(QJSValue::NullValue)"_s;
3973 return u
"QJSPrimitiveValue(QJSPrimitiveNull())"_s;
3975 return u
"QVariant::fromValue<std::nullptr_t>(nullptr)"_s;
3977 if (!
zero.isEmpty())
3993 if (from->
accessSemantics() == QQmlJSScope::AccessSemantics::Reference) {
3994 if (to->
accessSemantics() == QQmlJSScope::AccessSemantics::Reference) {
4009 return u
'(' +
variable + u
" != nullptr)"_s;
4017 if (isJsValue(from) && isJsValue(to))
4029 return u
"QJSNumberCoercion::toInteger("_s +
variable + u
')';
4031 return u
"uint(QJSNumberCoercion::toInteger("_s +
variable + u
"))"_s;
4033 return u
"[](double moved){ return moved && !std::isnan(moved); }("_s +
variable + u
')';
4036 if (isBoolOrNumber(from) && isBoolOrNumber(to))
4042 return variable + u
".toDouble()"_s;
4044 return variable + u
".toBoolean()"_s;
4052 return variable + u
".toString()"_s;
4054 return u
"QJSValue(QJSPrimitiveValue("_s +
variable + u
"))"_s;
4056 return variable + u
".toVariant()"_s;
4058 return u
"static_cast<"_s + to->
internalName() + u
" *>(nullptr)"_s;
4061 if (isJsValue(from)) {
4063 return variable + u
".toPrimitive()"_s;
4065 return variable + u
".toVariant(QJSValue::RetainJSObjects)"_s;
4066 return u
"qjsvalue_cast<"_s + castTargetName(to) + u
">("_s +
variable + u
')';
4078 return u
"QJSPrimitiveValue("_s +
variable + u
')';
4083 return u
"QJSPrimitiveValue(int("_s +
variable + u
"))"_s;
4085 return u
"QJSPrimitiveValue(double("_s +
variable + u
"))"_s;
4090 return u
"aotContext->engine->toScriptValue("_s +
variable + u
')';
4094 return u
"QQmlListReference("_s +
variable + u
", aotContext->qmlEngine())"_s;
4095 return u
"aotContext->engine->fromVariant<"_s + castTargetName(to) + u
">("_s
4100 return u
"QVariant::fromValue("_s +
variable + u
')';
4104 return variable + u
".toString()"_s;
4109 return u
"QUrl("_s +
variable + u
')';
4114 return u
"QString::fromUtf8("_s +
variable + u
')';
4122 for (
const auto &originType : {
4127 for (
const auto &targetType : {
4134 return u
"aotContext->engine->coerceValue<%1, %2>(%3)"_s.arg(
4135 originType->internalName(), targetType->internalName(),
variable);
4142 const auto retrieveFromPrimitive = [&](
4146 return expression + u
".toBoolean()"_s;
4148 return expression + u
".toInteger()"_s;
4150 return u
"uint("_s + expression + u
".toInteger())"_s;
4152 return expression + u
".toDouble()"_s;
4154 return u
"float("_s + expression + u
".toDouble())"_s;
4156 return expression + u
".toString()"_s;
4160 if (!retrieveFromPrimitive(from, u
"x"_s).isEmpty()) {
4161 const QString retrieve = retrieveFromPrimitive(
4168 return u
"aotContext->engine->coerceValue<"_s + castTargetName(from) + u
", "
4169 + castTargetName(to) + u
">("_s +
variable + u
')';
4177 Q_ASSERT(retrieveFromPrimitive(from, u
"x"_s).isEmpty());
4193 bool isExtension =
false;
4198 const auto argumentTypes = ctor.parameters();
4204 && from->
accessSemantics() == QQmlJSScope::AccessSemantics::Sequence) {
4209 return u
"[&](auto &&l){ return QJSList(&l, aotContext->engine).toString(); }("_s
4232 reject(u
"internal conversion into unsupported wrapper type."_s);
4236 bool isExtension =
false;
4238 reject(u
"populating "_s + containedTo->internalName()
4239 + u
" from "_s + containedFrom->internalName());
4242 containedTo, containedFrom, &isExtension); ctor.isValid()) {
4243 const auto argumentTypes = ctor.parameters();
4263 return u
"[&](){ auto arg = " +
input
4264 + u
"; return aotContext->constructValueType("_s +
metaType(containedTo)
4266 isExtension ? containedTo->extensionType().scope : containedTo)
4268 + u
", "_s + argPointer + u
"); }()"_s;
4285 reject(u
"internal conversion with incompatible or ambiguous types: %1 -> %2"_s
4292 setError(u
"Cannot generate efficient code for %1"_s.arg(thing));
4296 : accumulatorOut(
generator->m_state.accumulatorOut())
4297 , accumulatorVariableIn(
generator->m_state.accumulatorVariableIn)
4298 , accumulatorVariableOut(
generator->m_state.accumulatorVariableOut)
4301 if (accumulatorVariableOut.
isEmpty())
4311 if (!resolver->
equals(origStored, stored)
4316 generator->m_state.accumulatorVariableOut = storable ? u
"retrieved"_s :
QString();
4320 generator->m_body += origStored->augmentedInternalName() + u
' '
4321 +
generator->m_state.accumulatorVariableOut + u
";\n";
4323 }
else if (
generator->m_state.accumulatorVariableIn ==
generator->m_state.accumulatorVariableOut
4330 generator->m_state.accumulatorVariableIn
4331 =
generator->m_state.accumulatorVariableIn + u
"_moved"_s;
4334 + u
" = std::move("_s +
generator->m_state.accumulatorVariableOut + u
");\n"_s;
4340 if (accumulatorVariableOut !=
generator->m_state.accumulatorVariableOut) {
4342 generator->m_state.accumulatorOut(), accumulatorOut,
4343 u
"std::move("_s +
generator->m_state.accumulatorVariableOut + u
')') + u
";\n"_s;
4346 generator->m_state.accumulatorVariableOut = accumulatorVariableOut;
4347 }
else if (accumulatorVariableIn !=
generator->m_state.accumulatorVariableIn) {
4349 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.
const_iterator constBegin() const
iterator find(const Key &key)
const_iterator constEnd() const
T value(const Key &key, const T &defaultValue) const
const_iterator cbegin() const noexcept
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.
const_iterator constBegin() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
T value(const Key &key) const noexcept
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
const_iterator cend() const noexcept
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_IteratorClose() override
void generate_GetLookup(int index) override
void generate_StoreNameSloppy(int nameIndex) override
void generate_Shl(int lhs) override
void generate_LoadName(int nameIndex) 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_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
QString compositeMetaType(const QString &elementName) const
void generate_Decrement() override
void generate_Increment() override
void generate_CmpEqNull() override
void generate_DeleteProperty(int base, int index) override
void generate_IteratorNext(int value, int offset) override
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, QQmlJS::DiagnosticMessage *error, bool basicBlocksValidationFailed)
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
QString compositeListMetaType(const QString &elementName) const
void generate_BitAnd(int lhs) override
void generate_IteratorNextForYieldStar(int iterator, int object, int offset) 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
QQmlJSCodeGenerator(const QV4::Compiler::Context *compilerContext, const QV4::Compiler::JSUnitGenerator *unitGenerator, const QQmlJSTypeResolver *typeResolver, QQmlJSLogger *logger, BasicBlocks basicBlocks, InstructionAnnotations annotations)
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 generateReturnError()
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
QQmlJSRegisterContent lookupType(int lookupIndex) 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_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
QString lookupVariable(int lookupIndex) const
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
InstructionAnnotations m_annotations
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
bool isImportNamespace() const
ContentVariant variant() const
QQmlJSScope::ConstPtr type() const
QQmlJSScope::ConstPtr storedType() const
QQmlJSMetaEnum enumeration() const
@ ExtensionObjectProperty
int resultLookupIndex() const
QString enumMember() const
bool isEnumeration() const
AnnotatedScope extensionType() const
ScopeType scopeType() const
QString internalName() const
bool isReferenceType() const
AccessSemantics accessSemantics() const
bool isListProperty() const
static QQmlJSScope::ConstPtr nonCompositeBaseType(const QQmlJSScope::ConstPtr &type)
QString augmentedInternalName() const
QQmlJSMetaProperty property(const QString &name) 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
QQmlJSMetaMethod selectConstructor(const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument, bool *isExtension) const
QQmlJSScope::ConstPtr int64Type() const
QQmlJSScope::ConstPtr stringType() const
QQmlJSScope::ConstPtr listPropertyType() const
QQmlJSScope::ConstPtr nullType() const
QQmlJSScope::ConstPtr timeType() const
QQmlJSScope::ConstPtr mathObject() const
QQmlJSScope::ConstPtr genericType(const QQmlJSScope::ConstPtr &type, ComponentIsGeneric allowComponent=ComponentIsGeneric::No) const
QQmlJSScope::ConstPtr uint64Type() 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 consoleObject() const
QQmlJSScope::ConstPtr boolType() const
QQmlJSScope::ConstPtr qObjectListType() const
QQmlJSScope::ConstPtr jsGlobalObject() const
bool registerContains(const QQmlJSRegisterContent ®, const QQmlJSScope::ConstPtr &type) const
QString nameForType(const QQmlJSScope::ConstPtr &type) const
bool inherits(const QQmlJSScope::ConstPtr &derived, const QQmlJSScope::ConstPtr &base) 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 int16Type() const
QQmlJSRegisterContent builtinType(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr jsValueType() const
QQmlJSRegisterContent globalType(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr originalType(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr sizeType() 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
QQmlJSScope::ConstPtr extractNonVoidFromOptionalType(const QQmlJSRegisterContent &content) const
QQmlJSScope::ConstPtr int8Type() const
bool isTriviallyCopyable(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr int32Type() const
QQmlJSScope::ConstPtr variantListType() const
QQmlJSScope::ConstPtr voidType() const
QQmlJSScope::ConstPtr forOfIteratorPtr() const
QQmlJSScope::ConstPtr metaObjectType() const
QQmlJSScope::ConstPtr forInIteratorPtr() const
QQmlJSScope::ConstPtr realType() const
bool isOptionalType(const QQmlJSRegisterContent &content) 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, int lookupIndex=QQmlJSRegisterContent::InvalidLookupIndex, QQmlJSScopesByIdOptions options=Default) const
bool isNativeArrayIndex(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr qObjectType() const
QQmlJSScope::ConstPtr varType() const
QQmlJSScope::ConstPtr variantMapType() const
QQmlJSScope::ConstPtr floatType() const
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool isEmpty() const noexcept
Returns true if the string has no characters; 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
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
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)
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
GLsizei GLsizei GLchar * source
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)
static bool isStrict(const QmlIR::Document *doc)
static QString internalName(const QQmlJSScope::ConstPtr &scope)
bool canStrictlyCompareWithVar(const QQmlJSTypeResolver *typeResolver, const QQmlJSScope::ConstPtr &lhsType, const QQmlJSScope::ConstPtr &rhsType)
bool canCompareWithQObject(const QQmlJSTypeResolver *typeResolver, const QQmlJSScope::ConstPtr &lhsType, const QQmlJSScope::ConstPtr &rhsType)
bool canCompareWithQUrl(const QQmlJSTypeResolver *typeResolver, const QQmlJSScope::ConstPtr &lhsType, const QQmlJSScope::ConstPtr &rhsType)
#define Q_ASSERT_X(cond, x, msg)
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
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
QQmlJSRegisterContent returnType
const QQmlJSRegisterContent & accumulatorIn() const
The accumulatorIn is the input register of the current instruction.
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
The readAccumulator is the register content expected by the current instruction.
const QQmlJSRegisterContent & accumulatorOut() const
The accumulatorOut is the output register of the current instruction.
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)