6#include <QtCore/QCoreApplication>
7#include <QtCore/QStringList>
8#include <QtCore/QStack>
9#include <QtCore/qurl.h>
10#include <QtCore/qloggingcategory.h>
12#include <private/qqmljsast_p.h>
13#include <private/qqmljslexer_p.h>
14#include <private/qqmljsparser_p.h>
15#include <private/qv4staticvalue_p.h>
16#include <private/qv4compilercontext_p.h>
17#include <private/qv4compilercontrolflow_p.h>
18#include <private/qv4bytecodegenerator_p.h>
19#include <private/qv4compilerscanfunctions_p.h>
20#include <private/qv4stringtoarrayindex_p.h>
21#include <private/qqmljsdiagnosticmessage_p.h>
45 qCWarning(lcQmlUsedBeforeDeclared).nospace().noquote()
46 <<
fileName <<
":" << accessLocation.startLine <<
":" << accessLocation.startColumn
47 <<
" Variable \"" <<
name <<
"\" is used before its declaration at "
57 case Statement::Kind_ConditionalExpression:
58 case Statement::Kind_ForEachStatement:
59 case Statement::Kind_ForStatement:
60 case Statement::Kind_IfStatement:
61 case Statement::Kind_WhileStatement:
72 RegisterScope scope(
this);
79 Instruction::LoadRuntimeString
load;
88 Instruction::ThrowException throwException;
98 jsUnitGenerator(jsUnitGenerator),
100 storeSourceLocations(storeSourceLocations),
101 _fileNameIsUrl(
false),
115 "encodeURIComponent",
132 "decodeURIComponent",
224 for (
const auto &
entry: moduleContext->exportEntries) {
225 if (
entry.moduleRequest.isEmpty()) {
258 return functionIndex;
282 int intVal =
v.integerValue();
283 if (intVal && intVal != std::numeric_limits<int>::min())
287 }
else if (
v.isDouble()) {
306 Instruction::UMinus uminus = {};
312 Instruction::UPlus uplus = {};
318 Instruction::UNot unot;
324 Instruction::UCompl ucompl;
332 Instruction::UPlus uplus = {};
335 Instruction::Increment inc = {};
347 Instruction::Increment inc = {};
358 Instruction::UPlus uplus = {};
361 Instruction::Decrement
dec = {};
373 Instruction::Decrement
dec = {};
424 if (
result.loadTriggersSideEffect())
425 result.loadInAccumulator();
445 if (
r.format() ==
ex) {
450 r.result().loadInAccumulator();
451 if (
r.trueBlockFollowsCondition())
474 if (
it->statement->kind == Statement::Kind_BreakStatement ||
475 it->statement->kind == Statement::Kind_ContinueStatement)
477 if (
it->statement->kind == Statement::Kind_EmptyStatement ||
478 it->statement->kind == Statement::Kind_VariableDeclaration ||
479 it->statement->kind == Statement::Kind_FunctionDeclaration)
481 if (
it->statement->kind == Statement::Kind_Block) {
496 if (
it->statement->kind == Statement::Kind_BreakStatement ||
497 it->statement->kind == Statement::Kind_ContinueStatement)
499 if (
it->statement->kind == Statement::Kind_ThrowStatement ||
500 it->statement->kind == Statement::Kind_ReturnStatement)
501 return it->statement;
502 if (
it->statement->kind == Statement::Kind_EmptyStatement ||
503 it->statement->kind == Statement::Kind_VariableStatement ||
504 it->statement->kind == Statement::Kind_FunctionDeclaration)
506 if (
it->statement->kind == Statement::Kind_Block) {
512 return it->statement;
533 Node *needsCompletion =
nullptr;
547 if (
it->statement == needsCompletion)
553 if (
it->statement == needsCompletion)
555 if (
it->statement->kind == Statement::Kind_ThrowStatement ||
556 it->statement->kind == Statement::Kind_BreakStatement ||
557 it->statement->kind == Statement::Kind_ContinueStatement ||
558 it->statement->kind == Statement::Kind_ReturnStatement)
575 varToStore.storeConsumeAccumulator();
591 if (!
p->bindingIdentifier.isNull())
592 return referenceForName(
p->bindingIdentifier.toString(),
true,
p->firstSourceLocation());
593 if (!
p->bindingTarget ||
p->destructuringPattern())
613 varToStore.isReferenceToConst =
false;
620 if (!baseRef.isValid()) {
626 varToStore.storeConsumeAccumulator();
627 }
else if (baseRef == varToStore) {
628 baseRef.loadInAccumulator();
636 varToStore.storeConsumeAccumulator();
639 baseRef.loadInAccumulator();
648 varToStore.storeConsumeAccumulator();
650 }
else if (baseRef != varToStore && baseRef.isValid()) {
651 baseRef.loadInAccumulator();
652 varToStore.storeConsumeAccumulator();
658 if (!varToStore.isStackSlot())
659 varToStore = varToStore.storeOnStack();
666 varToStore.loadInAccumulator();
667 Instruction::ToObject toObject;
681 computedName = computedName.storeOnStack();
694 object.loadInAccumulator();
695 Instruction::ThrowOnNullOrUndefined
t;
715 QVarLengthArray<Reference> iteratorValues;
719 Instruction::GetIterator iteratorObjInstr;
720 iteratorObjInstr.iterator =
static_cast<int>(AST::ForEachType::Of);
722 iterator.storeConsumeAccumulator();
729 for (
Elision *elision =
p->elision; elision; elision = elision->next) {
730 iterator.loadInAccumulator();
731 Instruction::IteratorNext
next;
732 if (!ignored.isValid())
734 next.value = ignored.stackSlot();
742 iterator.loadInAccumulator();
743 Instruction::IteratorNext
next;
745 next.value = iteratorValues.back().stackSlot();
762 needsClose.loadInAccumulator();
764 iterator.loadInAccumulator();
765 Instruction::IteratorClose close;
783 iterator.loadInAccumulator();
801 if (
auto *
o = AST::cast<ObjectPattern *>(
p))
803 else if (
auto *
a = AST::cast<ArrayPattern *>(
p))
812 Q_UNREACHABLE_RETURN(
false);
817 Q_UNREACHABLE_RETURN(
false);
822 Q_UNREACHABLE_RETURN(
false);
827 Q_UNREACHABLE_RETURN(
false);
832 Q_UNREACHABLE_RETURN(
false);
837 Q_UNREACHABLE_RETURN(
false);
842 Q_UNREACHABLE_RETURN(
false);
847 Q_UNREACHABLE_RETURN(
false);
852 Q_UNREACHABLE_RETURN(
false);
857 Q_UNREACHABLE_RETURN(
false);
862 Q_UNREACHABLE_RETURN(
false);
867 Q_UNREACHABLE_RETURN(
false);
872 Q_UNREACHABLE_RETURN(
false);
877 Q_UNREACHABLE_RETURN(
false);
900 exportedValue.loadInAccumulator();
905 defaultExportSlot.storeConsumeAccumulator();
918 Q_UNREACHABLE_RETURN(
false);
923 Q_UNREACHABLE_RETURN(
false);
928 Q_UNREACHABLE_RETURN(
false);
933 Q_UNREACHABLE_RETURN(
false);
938 Q_UNREACHABLE_RETURN(
false);
943 Q_UNREACHABLE_RETURN(
false);
948 Q_UNREACHABLE_RETURN(
false);
953 Q_UNREACHABLE_RETURN(
false);
958 Q_UNREACHABLE_RETURN(
false);
963 Q_UNREACHABLE_RETURN(
false);
968 Q_UNREACHABLE_RETURN(
false);
973 Q_UNREACHABLE_RETURN(
false);
984 int nComputedNames = 0;
985 int nStaticComputedNames = 0;
990 for (
auto *member = ast->
elements; member; member = member->next) {
997 if (member->isStatic)
998 ++nStaticComputedNames;
1003 if (
p->type == PatternProperty::Getter)
1005 else if (
p->type == PatternProperty::Setter)
1009 if (member->isStatic) {
1014 jsClass.staticMethods <<
m;
1025 constructor = member;
1026 jsClass.constructorIndex =
m.functionIndex;
1030 jsClass.methods <<
m;
1050 int currentStaticName = computedNames;
1051 int currentNonStaticName = computedNames + nStaticComputedNames;
1053 for (
auto *member = ast->
elements; member; member = member->next) {
1062 computedName.storeOnStack(member->isStatic ? currentStaticName++ : currentNonStaticName++);
1065 Instruction::CreateClass createClass;
1066 createClass.classIndex = classIndex;
1067 createClass.heritage = heritage.
stackSlot();
1068 createClass.computedNames = computedNames;
1074 ctor.isReferenceToConst =
false;
1075 (
void) ctor.storeRetainAccumulator();
1087 (
void) outerVar.storeRetainAccumulator();
1098 blockTailCalls.unblock();
1124 (
void)
c.storeOnStack(temp);
1130 (
void)
r.storeOnStack(temp);
1135 for (;
it;
it =
it->next) {
1139 for (
Elision *elision =
it->elision; elision; elision = elision->next)
1155 Instruction::DefineArray call;
1169 array.storeConsumeAccumulator();
1172 auto pushAccumulator = [&]() {
1177 Instruction::Increment inc = {};
1179 index.storeConsumeAccumulator();
1183 for (
Elision *elision =
it->elision; elision; elision = elision->next) {
1210 Instruction::GetIterator iteratorObjInstr;
1211 iteratorObjInstr.iterator =
static_cast<int>(AST::ForEachType::Of);
1213 iterator.storeConsumeAccumulator();
1221 auto cleanup = [
this, iterator,
done]() {
1222 iterator.loadInAccumulator();
1223 Instruction::IteratorClose close;
1231 iterator.loadInAccumulator();
1232 Instruction::IteratorNext
next;
1233 next.value = lhsValue.stackSlot();
1236 lhsValue.loadInAccumulator();
1256 array.loadInAccumulator();
1267 const bool isTailOfChain = traverseOptionalChain(ast);
1272 auto writeSkip = [&]() {
1273 base.loadInAccumulator();
1281 if (
base.isSuper()) {
1292 if (arrayIndex == UINT_MAX) {
1297 optionalChainFinalizer(
ref, isTailOfChain);
1353 blockTailCalls.unblock();
1363 left.loadInAccumulator();
1369 blockTailCalls.unblock();
1373 right.loadInAccumulator();
1394 left.loadInAccumulator();
1400 blockTailCalls.unblock();
1404 right.loadInAccumulator();
1419 Instruction::CmpEqNull cmp;
1422 left.loadInAccumulator();
1427 blockTailCalls.unblock();
1429 left.loadInAccumulator();
1434 right.loadInAccumulator();
1448 right.loadInAccumulator();
1457 if (!
left.isLValue()) {
1464 blockTailCalls.unblock();
1468 r.loadInAccumulator();
1502 if (!
left.isLValue()) {
1523 if (
left.isConstant()) {
1579 right.loadInAccumulator();
1580 Instruction::Add
add;
1587 left.loadInAccumulator();
1588 Instruction::Decrement
dec = {};
1592 right.loadInAccumulator();
1593 Instruction::Sub
sub;
1601 right.loadInAccumulator();
1602 Instruction::Exp exp;
1603 exp.lhs =
left.stackSlot();
1609 right.loadInAccumulator();
1610 Instruction::Mul mul;
1611 mul.lhs =
left.stackSlot();
1617 right.loadInAccumulator();
1618 Instruction::Div div;
1619 div.lhs =
left.stackSlot();
1625 right.loadInAccumulator();
1626 Instruction::Mod mod;
1627 mod.lhs =
left.stackSlot();
1632 if (
right.isConstant()) {
1634 if (
left.isConstant()) {
1638 left.loadInAccumulator();
1639 Instruction::BitAndConst bitAnd;
1640 bitAnd.rhs = rightAsInt;
1643 right.loadInAccumulator();
1644 Instruction::BitAnd bitAnd;
1645 bitAnd.lhs =
left.stackSlot();
1650 if (
right.isConstant()) {
1652 if (
left.isConstant()) {
1656 left.loadInAccumulator();
1657 Instruction::BitOrConst bitOr;
1658 bitOr.rhs = rightAsInt;
1661 right.loadInAccumulator();
1662 Instruction::BitOr bitOr;
1663 bitOr.lhs =
left.stackSlot();
1668 if (
right.isConstant()) {
1670 if (
left.isConstant()) {
1674 left.loadInAccumulator();
1675 Instruction::BitXorConst bitXor;
1676 bitXor.rhs = rightAsInt;
1679 right.loadInAccumulator();
1680 Instruction::BitXor bitXor;
1681 bitXor.lhs =
left.stackSlot();
1686 if (
right.isConstant()) {
1687 left.loadInAccumulator();
1688 Instruction::UShrConst ushr;
1692 right.loadInAccumulator();
1693 Instruction::UShr ushr;
1694 ushr.lhs =
left.stackSlot();
1699 if (
right.isConstant()) {
1700 left.loadInAccumulator();
1701 Instruction::ShrConst shr;
1705 right.loadInAccumulator();
1706 Instruction::Shr shr;
1707 shr.lhs =
left.stackSlot();
1712 if (
right.isConstant()) {
1713 left.loadInAccumulator();
1714 Instruction::ShlConst shl;
1718 right.loadInAccumulator();
1719 Instruction::Shl shl;
1720 shl.lhs =
left.stackSlot();
1725 Instruction::CmpInstanceOf binop;
1727 right.loadInAccumulator();
1728 binop.lhs =
left.stackSlot();
1735 right.loadInAccumulator();
1736 as.lhs =
left.stackSlot();
1741 Instruction::CmpIn binop;
1743 right.loadInAccumulator();
1744 binop.lhs =
left.stackSlot();
1752 Instruction::CmpStrictEqual cmp;
1754 right.loadInAccumulator();
1755 cmp.lhs =
left.stackSlot();
1763 Instruction::CmpStrictNotEqual cmp;
1765 right.loadInAccumulator();
1766 cmp.lhs =
left.stackSlot();
1774 Instruction::CmpEq cmp;
1776 right.loadInAccumulator();
1777 cmp.lhs =
left.stackSlot();
1785 Instruction::CmpNe cmp;
1787 right.loadInAccumulator();
1788 cmp.lhs =
left.stackSlot();
1796 Instruction::CmpGt cmp;
1798 right.loadInAccumulator();
1799 cmp.lhs =
left.stackSlot();
1807 Instruction::CmpGe cmp;
1809 right.loadInAccumulator();
1810 cmp.lhs =
left.stackSlot();
1818 Instruction::CmpLt cmp;
1820 right.loadInAccumulator();
1821 cmp.lhs =
left.stackSlot();
1829 Instruction::CmpLe cmp;
1831 right.loadInAccumulator();
1832 cmp.lhs =
left.stackSlot();
1847 if (
left.isConstant() && !
right.isConstant())
1850 if (
right.isConstant()) {
1852 if (
c.isNull() ||
c.isUndefined()) {
1853 left.loadInAccumulator();
1855 Instruction::CmpEqNull cmp;
1860 Instruction::CmpNeNull cmp;
1865 }
else if (
c.isInt32()) {
1866 left.loadInAccumulator();
1868 Instruction::CmpEqInt cmp;
1869 cmp.lhs =
c.int_32();
1874 Instruction::CmpNeInt cmp;
1875 cmp.lhs =
c.int_32();
1886 right.loadInAccumulator();
1890 Instruction::CmpStrictEqual cmp;
1891 cmp.lhs =
left.stackSlot();
1897 Instruction::CmpStrictNotEqual cmp;
1898 cmp.lhs =
left.stackSlot();
1904 Instruction::CmpEq cmp;
1905 cmp.lhs =
left.stackSlot();
1911 Instruction::CmpNe cmp;
1912 cmp.lhs =
left.stackSlot();
1918 Instruction::CmpGt cmp;
1919 cmp.lhs =
left.stackSlot();
1925 Instruction::CmpGe cmp;
1926 cmp.lhs =
left.stackSlot();
1932 Instruction::CmpLt cmp;
1933 cmp.lhs =
left.stackSlot();
1939 Instruction::CmpLe cmp;
1940 cmp.lhs =
left.stackSlot();
1955 base.elementSubscript.loadInAccumulator();
1956 Codegen::Instruction::LoadElement
load;
1967 const bool isTailOfChain = traverseOptionalChain(ast);
1977 switch (
base.type) {
1983 base.subscriptLoadedForCall =
true;
1999 base.hasSavedCallBaseSlot =
true;
2008 base.loadInAccumulator();
2018 blockTailCalls.unblock();
2026 const int func = [&]() {
2028 return base.element;
2030 if (!
base.isStackSlot()) {
2031 base.storeOnStack(functionObject);
2035 return base.stackSlot();
2038 if (calldata.hasSpread) {
2039 Instruction::CallWithSpread call;
2041 call.thisObject = baseObject.
stackSlot();
2042 call.argc = calldata.argc;
2043 call.argv = calldata.argv;
2046 Instruction::TailCall call;
2048 call.thisObject = baseObject.
stackSlot();
2049 call.argc = calldata.argc;
2050 call.argv = calldata.argv;
2070 if (
base.sourceLocation.isValid())
2076 Instruction::CallPropertyLookup call;
2077 if (
base.hasSavedCallBaseSlot) {
2078 call.base =
base.savedCallBaseSlot;
2082 call.base =
base.propertyBase.stackSlot();
2086 call.argc = calldata.argc;
2087 call.argv = calldata.argv;
2090 Instruction::CallProperty call;
2091 if (
base.hasSavedCallBaseSlot) {
2092 call.base =
base.savedCallBaseSlot;
2093 call.name =
base.savedCallPropertyNameIndex;
2095 call.base =
base.propertyBase.stackSlot();
2096 call.name =
base.propertyNameIndex;
2098 call.argc = calldata.argc;
2099 call.argv = calldata.argv;
2103 Instruction::CallWithReceiver call;
2104 call.thisObject =
base.elementBase.stackSlot();
2105 call.name =
base.element;
2106 call.argc = calldata.argc;
2107 call.argv = calldata.argv;
2111 Instruction::CallPossiblyDirectEval call;
2112 call.argc = calldata.argc;
2113 call.argv = calldata.argv;
2116 if (
base.qmlGlobal) {
2117 Instruction::CallQmlContextPropertyLookup call;
2120 call.argc = calldata.argc;
2121 call.argv = calldata.argv;
2124 Instruction::CallGlobalLookup call;
2127 call.argc = calldata.argc;
2128 call.argv = calldata.argv;
2132 Instruction::CallName call;
2133 call.name =
base.nameAsIndex();
2134 call.argc = calldata.argc;
2135 call.argv = calldata.argv;
2140 if (!
base.isStackSlot()) {
2141 base.storeOnStack(slotForFunction);
2148 Instruction::CallWithReceiver call;
2149 call.name =
base.stackSlot();
2151 call.argc = calldata.argc;
2152 call.argv = calldata.argv;
2156 Instruction::CallValue call;
2157 call.name =
base.stackSlot();
2158 call.argc = calldata.argc;
2159 call.argv = calldata.argv;
2166 bool hasSpread =
false;
2169 if (
it->isSpreadElement) {
2177 return { 0, 0,
false };
2183 if (
it->isSpreadElement) {
2193 if (!argc && !
it->next && !hasSpread) {
2204 return { argc, calldata, hasSpread };
2214 return { 0, 0,
false };
2228 return { argc, calldata,
false };
2243 blockTailCalls.unblock();
2249 ok.loadInAccumulator();
2271 const bool isTailOfChain = traverseOptionalChain(ast);
2280 if (chainActuallyHasOptionals)
2283 switch (expr.
type) {
2304 Instruction::DeleteName del;
2314 if (chainActuallyHasOptionals) {
2321 Instruction::LoadRuntimeString instr;
2325 index.storeConsumeAccumulator();
2326 Instruction::DeleteProperty del;
2328 del.index =
index.stackSlot();
2332 optionalChainFinalizer(
ref, isTailOfChain,
true);
2339 if (chainActuallyHasOptionals) {
2346 Instruction::DeleteProperty del;
2352 optionalChainFinalizer(
ref, isTailOfChain,
true);
2385bool Codegen::traverseOptionalChain(
Node *node)
2390 const auto isOptionalChainableNode = [](
const Node *node) {
2391 return node->kind == Node::Kind_FieldMemberExpression ||
2392 node->kind == Node::Kind_CallExpression ||
2393 node->kind == Node::Kind_ArrayMemberExpression ||
2394 node->kind == Node::Kind_DeleteExpression;
2397 while (isOptionalChainableNode(node)) {
2400 switch (node->kind) {
2401 case Node::Kind_FieldMemberExpression: {
2402 auto *fme = AST::cast<FieldMemberExpression *>(node);
2407 case Node::Kind_CallExpression: {
2408 auto *ce = AST::cast<CallExpression *>(node);
2413 case Node::Kind_ArrayMemberExpression: {
2414 auto *ame = AST::cast<ArrayMemberExpression *>(node);
2419 case Node::Kind_DeleteExpression:
2420 node = AST::cast<DeleteExpression *>(node)->expression;
2430void Codegen::optionalChainFinalizer(
const Reference &expressionResult,
bool tailOfChain,
2431 bool isDeleteExpression)
2437 }
else if (!chainState.actuallyHasOptionals) {
2443 auto savedBaseSlot = -1;
2445 savedBaseSlot = expressionResult.propertyBase.storeOnStack().stackSlot();
2446 expressionResult.loadInAccumulator();
2448 std::optional<Moth::BytecodeGenerator::Jump> jumpToDone;
2449 if (!isDeleteExpression)
2452 for (
auto &
jump : chainState.jumpsToPatch)
2455 if (isDeleteExpression)
2460 if (jumpToDone.has_value())
2461 jumpToDone.value().link();
2477 ref.hasSavedCallBaseSlot =
true;
2478 ref.savedCallBaseSlot = savedBaseSlot;
2479 ref.savedCallPropertyNameIndex = expressionResult.propertyNameIndex;
2490 const bool isTailOfChain = traverseOptionalChain(ast);
2501 r.isReadonly =
true;
2508 optionalChainFinalizer(
ref, isTailOfChain);
2517 if (
base.isSuper()) {
2518 Instruction::LoadRuntimeString
load;
2530 optionalChainFinalizer(
ref, isTailOfChain);
2553 int functionObject = -1, thisObject = -1;
2554 switch (
base.type) {
2560 base.subscriptLoadedForCall =
true;
2580 Q_ASSERT(calldata.argv == templateObjectTemp + 1);
2600 Instruction::GetTemplateObject getTemplateObject;
2601 getTemplateObject.index =
index;
2625 bool throwsReferenceError =
false;
2639 throwsReferenceError =
true;
2642 if (resolved.
isInjected && accessLocation.isValid()) {
2643 qCWarning(lcQmlInjectedParameter).nospace().noquote()
2644 <<
url().
toString() <<
":" << accessLocation.startLine
2645 <<
":" << accessLocation.startColumn <<
" Parameter \"" <<
name
2646 <<
"\" is not declared."
2647 <<
" Injection of parameters into signal handlers is deprecated."
2648 <<
" Use JavaScript functions with formal parameters instead.";
2652 switch (resolved.
type) {
2659 default: Q_UNREACHABLE();
2662 r.isVolatile =
true;
2664 r.isReferenceToConst = resolved.
isConst;
2667 r.sourceLocation = accessLocation;
2668 r.throwsReferenceError = throwsReferenceError;
2675 r.sourceLocation = accessLocation;
2683 if (closureId >= 0) {
2684 Instruction::LoadClosure
load;
2685 load.value = closureId;
2712 Reference constructor;
2713 if (
base.isSuper()) {
2714 Instruction::LoadSuperConstructor super;
2718 constructor =
base.storeOnStack();
2728 constructor.loadInAccumulator();
2730 if (calldata.hasSpread) {
2731 Instruction::ConstructWithSpread
create;
2732 create.func = constructor.stackSlot();
2733 create.argc = calldata.argc;
2734 create.argv = calldata.argv;
2737 Instruction::Construct
create;
2738 create.func = constructor.stackSlot();
2739 create.argc = calldata.argc;
2740 create.argv = calldata.argv;
2761 if (
base.isSuper()) {
2766 handleConstruct(
base,
nullptr);
2781 if (
base.isSuper()) {
2839 (
void)
arg.storeOnStack(temp);
2844 for (;
it;
it =
it->next) {
2847 if (cname ||
p->type != PatternProperty::Literal)
2851 if (arrayIndex != UINT_MAX)
2862 value.loadInAccumulator();
2870 for (;
it;
it =
it->next) {
2874 if (
p->type == PatternProperty::Method)
2876 else if (
p->type == PatternProperty::Getter)
2878 else if (
p->type == PatternProperty::Setter)
2889 name.loadInAccumulator();
2893 uint arrayIndex = QV4::String::toArrayIndex(
name);
2894 if (arrayIndex != UINT_MAX) {
2899 Instruction::LoadRuntimeString instr;
2907 if (
p->type != PatternProperty::Literal) {
2919 value.loadInAccumulator();
2925 Instruction::DefineObjectLiteral call;
2926 call.internalClassId = classId;
3016 r.isReadonly =
true;
3019 Instruction::MoveRegExp instr;
3021 instr.destReg =
r.stackSlot();
3032 r.isReadonly =
true;
3035 Instruction::LoadRuntimeString instr;
3048 Instruction::LoadRuntimeString instr;
3055 Instruction::StoreReg store;
3068 Instruction::Add instr;
3075 Instruction::Add instr;
3081 r.isReadonly =
true;
3094 if (parentContext->isArrowFunction) {
3096 r.isReadonly =
true;
3141 Instruction::TypeofName instr;
3146 Instruction::TypeofValue instr;
3208 auto innerMostCurentFunctionContext =
_context;
3209 while (innerMostCurentFunctionContext && innerMostCurentFunctionContext->contextType !=
ContextType::Function)
3210 innerMostCurentFunctionContext = innerMostCurentFunctionContext->
parent;
3212 Q_ASSERT(innerMostCurentFunctionContext);
3214 if (!innerMostCurentFunctionContext->isGenerator) {
3232 Instruction::GetIterator getIterator;
3233 getIterator.iterator =
static_cast<int>(AST::ForEachType::Of);
3235 iterator.storeConsumeAccumulator();
3236 Instruction::LoadUndefined
load;
3244 lhsValue.loadInAccumulator();
3245 Instruction::YieldStar yield;
3250 Instruction::IteratorNextForYieldStar
next;
3251 next.object = lhsValue.stackSlot();
3252 next.iterator = iterator.stackSlot();
3256 lhsValue.loadInAccumulator();
3263 lhsValue.loadInAccumulator();
3269 Instruction::Yield yield;
3271 Instruction::Resume
resume;
3283 if (AST::cast<ReturnStatement *>(node))
3285 if (AST::cast<ThrowStatement *>(node))
3287 if (
Program *
p = AST::cast<Program *>(node))
3294 if (
Block *
b = AST::cast<Block *>(node)) {
3295 Context *blockContext =
module->contextMap.value(node);
3296 if (blockContext->requiresExecutionContext)
3302 if (
IfStatement *is = AST::cast<IfStatement *>(node))
3339 && cast<FunctionExpression *>(cast<ExpressionStatement *>(body->
statement)->expression);
3356 bool _inFormalParameterList =
false;
3359 int returnAddress = -1;
3393 Instruction::CreateRestParameter rest;
3394 rest.argIndex = argc;
3396 arg.storeConsumeAccumulator();
3404 formals = formals->
next;
3410 Instruction::Yield yield;
3425 Instruction::LoadReg
load;
3486 if (!
target.linkLabel.isValid()) {
3513 if (!
target.linkLabel.isValid()) {
3547 if (!AST::cast<FalseLiteral *>(ast->
expression))
3555 if (AST::cast<TrueLiteral *>(ast->
expression)) {
3559 }
else if (AST::cast<FalseLiteral *>(ast->
expression)) {
3617 Instruction::GetIterator iteratorObjInstr;
3618 iteratorObjInstr.iterator =
static_cast<int>(ast->
type);
3620 iterator.storeConsumeAccumulator();
3628 std::function<
void()> cleanup;
3629 if (ast->
type == ForEachType::Of) {
3631 cleanup = [iterator,
this,
done]() {
3632 iterator.loadInAccumulator();
3633 Instruction::IteratorClose close;
3643 iterator.loadInAccumulator();
3644 Instruction::IteratorNext
next;
3645 next.value = lhsValue.stackSlot();
3677 blockTailCalls.unblock();
3720 blockTailCalls.unblock();
3722 blockTailCalls.reblock();
3727 Instruction::CloneBlockContext clone;
3750 blockTailCalls.unblock();
3790 if (AST::cast<AST::SwitchStatement *>(ast->
statement) ||
3791 AST::cast<AST::WhileStatement *>(ast->
statement) ||
3792 AST::cast<AST::DoWhileStatement *>(ast->
statement) ||
3793 AST::cast<AST::ForStatement *>(ast->
statement) ||
3794 AST::cast<AST::ForEachStatement *>(ast->
statement)) {
3809 if (
target.linkLabel.isValid() &&
target.unwindLevel) {
3864 QHash<Node *, BytecodeGenerator::Label> blockMap;
3899 blockTailCalls.unblock();
3902 blockMap[clause].link();
3909 blockMap[clause].link();
3916 blockMap[clause].link();
3942 Instruction::ThrowException instr;
4004 if (AST::cast<FalseLiteral *>(ast->
expression))
4017 if (!AST::cast<TrueLiteral *>(ast->
expression)) {
4042 src =
src.storeOnStack();
4043 src.loadInAccumulator();
4047 blockTailCalls.unblock();
4096 bool isArgOrEval =
false;
4103 isArgOrEval =
r.isArgOrEval;
4136 bool generateUnitData)
4138 return QQmlRefPointer<QV4::CompiledData::CompilationUnit>(
4146 const QDateTime &sourceTimeStamp, QList<QQmlJS::DiagnosticMessage> *diagnostics)
4150 lexer.
setCode(sourceCode, 1,
false);
4151 QQmlJS::Parser parser(&ee);
4153 const bool parsed = parser.parseModule();
4156 *diagnostics = parser.diagnosticMessages();
4159 return QQmlRefPointer<CompiledData::CompilationUnit>();
4166 diagnostics->clear();
4173 compilerModule.sourceTimeStamp = sourceTimeStamp;
4175 Codegen cg(&jsGenerator,
true);
4179 *diagnostics << cg.
error();
4180 return QQmlRefPointer<CompiledData::CompilationUnit>();
4217 collectIdentifiers(locs.specificLocations, e->
base);
4223 collectIdentifiers(locs.specificLocations, e->
base);
4229 collectIdentifiers(locs.specificLocations, e->
expression);
4235 collectIdentifiers(locs.specificLocations, e->
expression);
4253 collectIdentifiers(locs.specificLocations, e);
4267 void collectIdentifiers(QList<QStringView> &
ids,
AST::Node *node) {
4270 QList<QStringView> &
ids;
4279 ids.append(ie->name);
4283 void throwRecursionDepthError() final
4289 node->
accept(&collector);
4295 VolatileMemoryLocationScanner scanner(
this);
4296 return scanner.scan(ast);
4308 return other.isAccumulator();
4359 return property ==
other.property;
4361 return theStackSlot ==
other.theStackSlot;
4365 return nameAsIndex() ==
other.nameAsIndex();
4367 return propertyBase ==
other.propertyBase && propertyNameIndex ==
other.propertyNameIndex;
4369 return elementBase ==
other.elementBase &&
other.subscriptLoadedForCall
4370 ? (subscriptLoadedForCall && element ==
other.element)
4371 : (!subscriptLoadedForCall && elementSubscript ==
other.elementSubscript);
4392 loadInAccumulator();
4407 if (!propertyBase.isStackSlot()) {
4414 if (!elementSubscript.isStackSlot()) {
4434 RValue rval = propertyBase;
4435 if (!rval.isValid())
4437 if (rval.isAccumulator())
4439 if (rval.isStackSlot())
4454{
return doStoreOnStack(-1); }
4457{ doStoreOnStack(slotIndex); }
4463 if (isStackSlot() && slotIndex == -1 && !(stackSlotIsLocalOrArgument && isVolatile) && !requiresTDZCheck)
4466 if (isStackSlot() && !requiresTDZCheck) {
4468 Instruction::MoveReg move;
4469 move.srcReg = stackSlot();
4471 codegen->bytecodeGenerator->addInstruction(move);
4477 Instruction::MoveConst move;
4478 move.constIndex = codegen->registerConstant(
constant);
4479 move.destTemp = slot.stackSlot();
4480 codegen->bytecodeGenerator->addInstruction(move);
4482 loadInAccumulator();
4483 slot.storeConsumeAccumulator();
4489 if (throwsReferenceError) {
4490 codegen->generateThrowException(
QStringLiteral(
"ReferenceError"),
4496 Instruction::DeadTemporalZoneCheck check;
4497 check.name = codegen->registerString(
name);
4498 codegen->bytecodeGenerator->addInstruction(check);
4501void Codegen::Reference::tdzCheckStackSlot(
Moth::StackSlot slot,
bool requiresCheck,
bool throwsReferenceError)
const {
4504 Instruction::LoadReg
load;
4506 codegen->bytecodeGenerator->addInstruction(
load);
4507 tdzCheck(
true, throwsReferenceError);
4512 if (storeWipesAccumulator()) {
4515 tmp.storeAccumulator();
4544void Codegen::Reference::storeAccumulator()
const
4546 if (throwsReferenceError) {
4547 codegen->generateThrowException(
QStringLiteral(
"ReferenceError"),
4552 if (isReferenceToConst) {
4560 Q_UNREACHABLE_RETURN();
4562 Instruction::StoreSuperProperty store;
4563 store.property =
property.stackSlot();
4564 codegen->bytecodeGenerator->addInstruction(store);
4567 Instruction::StoreReg store;
4568 store.reg = theStackSlot;
4569 codegen->bytecodeGenerator->addInstruction(store);
4574 Instruction::StoreLocal store;
4575 store.index =
index;
4576 codegen->bytecodeGenerator->addInstruction(store);
4578 Instruction::StoreScopedLocal store;
4579 store.index =
index;
4580 store.scope = scope;
4581 codegen->bytecodeGenerator->addInstruction(store);
4586 Context *
c = codegen->currentContext();
4588 Instruction::StoreNameStrict store;
4589 store.
name = nameAsIndex();
4590 codegen->bytecodeGenerator->addInstruction(store);
4592 Instruction::StoreNameSloppy store;
4593 store.name = nameAsIndex();
4594 codegen->bytecodeGenerator->addInstruction(store);
4598 if (codegen->useFastLookups) {
4599 Instruction::SetLookup store;
4600 store.base = propertyBase.stackSlot();
4601 store.index = codegen->registerSetterLookup(propertyNameIndex);
4602 codegen->bytecodeGenerator->addInstruction(store);
4604 Instruction::StoreProperty store;
4605 store.base = propertyBase.stackSlot();
4606 store.name = propertyNameIndex;
4607 codegen->bytecodeGenerator->addInstruction(store);
4611 Instruction::StoreElement store;
4612 store.base = elementBase;
4613 store.index = elementSubscript.stackSlot();
4614 codegen->bytecodeGenerator->addInstruction(store);
4632 Q_UNREACHABLE_RETURN();
4634 tdzCheckStackSlot(
property, subscriptRequiresTDZCheck,
false);
4635 Instruction::LoadSuperProperty
load;
4636 load.property =
property.stackSlot();
4637 codegen->bytecodeGenerator->addInstruction(
load);
4643 Instruction::LoadNull
load;
4644 codegen->bytecodeGenerator->addInstruction(
load);
4646 Instruction::LoadTrue
load;
4647 codegen->bytecodeGenerator->addInstruction(
load);
4649 Instruction::LoadFalse
load;
4650 codegen->bytecodeGenerator->addInstruction(
load);
4652 Instruction::LoadUndefined
load;
4653 codegen->bytecodeGenerator->addInstruction(
load);
4657 double d =
p.asDouble();
4658 int i = QJSNumberCoercion::toInteger(
d);
4659 if (
d ==
i && (
d != 0 || !std::signbit(
d))) {
4661 Instruction::LoadZero
load;
4662 codegen->bytecodeGenerator->addInstruction(
load);
4665 Instruction::LoadInt
load;
4667 codegen->bytecodeGenerator->addInstruction(
load);
4671 Instruction::LoadConst
load;
4673 codegen->bytecodeGenerator->addInstruction(
load);
4678 Instruction::LoadReg
load;
4679 load.reg = stackSlot();
4680 codegen->bytecodeGenerator->addInstruction(
load);
4681 tdzCheck(requiresTDZCheck, throwsReferenceError);
4685 Instruction::LoadLocal
load;
4687 codegen->bytecodeGenerator->addInstruction(
load);
4689 Instruction::LoadScopedLocal
load;
4692 codegen->bytecodeGenerator->addInstruction(
load);
4694 tdzCheck(requiresTDZCheck, throwsReferenceError);
4713 if (sourceLocation.isValid())
4714 codegen->bytecodeGenerator->setLocation(sourceLocation);
4718 Instruction::LoadQmlContextPropertyLookup
load;
4719 load.index = codegen->registerQmlContextPropertyGetterLookup(
4721 codegen->bytecodeGenerator->addInstruction(
load);
4723 Instruction::LoadGlobalLookup
load;
4724 load.index = codegen->registerGlobalGetterLookup(
4726 codegen->bytecodeGenerator->addInstruction(
load);
4729 Instruction::LoadName
load;
4730 load.name = nameAsIndex();
4731 codegen->bytecodeGenerator->addInstruction(
load);
4735 propertyBase.loadInAccumulator();
4736 tdzCheck(requiresTDZCheck, throwsReferenceError);
4738 if (sourceLocation.isValid())
4739 codegen->bytecodeGenerator->setLocation(sourceLocation);
4741 if (codegen->useFastLookups) {
4742 if (optionalChainJumpsToPatch && isOptional) {
4743 auto jump = codegen->bytecodeGenerator->jumpOptionalLookup(
4744 codegen->registerGetterLookup(
4746 optionalChainJumpsToPatch->emplace_back(std::move(
jump));
4748 Instruction::GetLookup
load;
4749 load.index = codegen->registerGetterLookup(
4751 codegen->bytecodeGenerator->addInstruction(
load);
4754 if (optionalChainJumpsToPatch && isOptional) {
4755 auto jump = codegen->bytecodeGenerator->jumpOptionalProperty(propertyNameIndex);
4756 optionalChainJumpsToPatch->emplace_back(std::move(
jump));
4758 Instruction::LoadProperty
load;
4759 load.name = propertyNameIndex;
4760 codegen->bytecodeGenerator->addInstruction(
load);
4765 Instruction::LoadImport
load;
4767 codegen->bytecodeGenerator->addInstruction(
load);
4768 tdzCheck(requiresTDZCheck, throwsReferenceError);
4771 tdzCheckStackSlot(elementBase, requiresTDZCheck, throwsReferenceError);
4772 elementSubscript.loadInAccumulator();
4773 tdzCheck(subscriptRequiresTDZCheck,
false);
4774 Instruction::LoadElement
load;
4775 load.base = elementBase;
4776 codegen->bytecodeGenerator->addInstruction(
load);
void reportVarUsedBeforeDeclaration(const QString &name, const QString &fileName, QQmlJS::SourceLocation declarationLocation, QQmlJS::SourceLocation accessLocation) override
void throwRecursionDepthError() override
bool visit(FieldMemberExpression *) override
bool visit(PostDecrementExpression *e) override
VolatileMemoryLocationScanner(Codegen *parent)
bool visit(BinaryExpression *e) override
Codegen::VolatileMemoryLocations scan(AST::Node *s)
bool visit(ArrayMemberExpression *) override
bool visit(PreDecrementExpression *e) override
bool visit(PreIncrementExpression *e) override
bool visit(PostIncrementExpression *e) override
\inmodule QtCore\reentrant
qsizetype size() const noexcept
ExpressionNode * expression
PatternElementList * elements
quint16 recursionDepth() const
SourceLocation operatorToken
StatementList * statements
SourceLocation lastSourceLocation() const override
CaseClauses * moreClauses
DefaultClause * defaultClause
ExpressionNode * expression
StatementList * statements
SourceLocation firstSourceLocation() const override
ExpressionNode * heritage
ClassElementList * elements
ExpressionNode * expression
SourceLocation lastSourceLocation() const override
StatementList * statements
SourceLocation deleteToken
ExpressionNode * expression
ExpressionNode * expression
SourceLocation semicolonToken
Node * variableStatementOrDeclaration
ExpressionNode * expression
SourceLocation lastSourceLocation() const override
ExpressionNode * expression
ExpressionNode * expression
VariableDeclarationList * declarations
ExpressionNode * initialiser
ExpressionNode * condition
FormalParameterList * formals
FunctionExpression * asFunctionDefinition() override
SourceLocation firstSourceLocation() const override
ExpressionNode * expression
SourceLocation firstSourceLocation() const override
ExpressionNode * expression
ExpressionNode * expression
virtual SourceLocation firstSourceLocation() const =0
void accept(BaseVisitor *visitor)
virtual SourceLocation lastSourceLocation() const =0
virtual ExpressionNode * expressionCast()
virtual Pattern * patternCast()
ExpressionNode * expression
PatternPropertyList * properties
PatternElementList * next
PatternPropertyList * propertyList() const
PatternElementList * elementList() const
QStringView bindingIdentifier
ExpressionNode * initializer
TypeAnnotation * typeAnnotation
Pattern * destructuringPattern() const
ExpressionNode * bindingTarget
bool isLexicallyScoped() const
Pattern * patternCast() override
SourceLocation decrementToken
SourceLocation incrementToken
SourceLocation decrementToken
ExpressionNode * expression
ExpressionNode * expression
SourceLocation incrementToken
StatementList * statements
ExpressionNode * expression
SourceLocation returnToken
ExpressionNode * expression
TemplateLiteral * templateLiteral
ExpressionNode * expression
ExpressionNode * expression
ExpressionNode * expression
Finally * finallyExpression
SourceLocation firstSourceLocation() const override
ExpressionNode * expression
ExpressionNode * expression
ExpressionNode * expression
VariableDeclarationList * declarations
ExpressionNode * expression
ExpressionNode * expression
SourceLocation whileToken
ExpressionNode * expression
SourceLocation firstSourceLocation() const override
ExpressionNode * expression
void setCode(const QString &code, int lineno, bool qmlMode=true, CodeContinuation codeContinuation=CodeContinuation::Reset)
bool remove(const T &value)
const_iterator constBegin() const noexcept
const_iterator constEnd() const noexcept
bool contains(const T &value) const
iterator insert(const T &value)
constexpr bool isEmpty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
QString toString() const
Returns a deep copy of this string view's data as a QString.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
virtual void reportVarUsedBeforeDeclaration(const QString &name, const QString &fileName, QQmlJS::SourceLocation declarationLocation, QQmlJS::SourceLocation accessLocation)
Moth::StackSlot theStackSlot
void loadInAccumulator() const
static RValue fromStackSlot(Codegen *codegen, Moth::StackSlot stackSlot)
Q_REQUIRED_RESULT RValue storeOnStack() const
static RValue fromAccumulator(Codegen *codegen)
bool operator==(const RValue &other) const
static RValue fromConst(Codegen *codegen, QV4::ReturnedValue value)
QV4::ReturnedValue constant
Moth::StackSlot stackSlot() const
bool trueBlockFollowsCondition() const
const BytecodeGenerator::Label * iffalse() const
const Reference & result() const
const BytecodeGenerator::Label * iftrue() const
bool isVolatile(QStringView name)
void handleTryCatch(QQmlJS::AST::TryStatement *ast)
virtual void throwSyntaxError(const QQmlJS::SourceLocation &loc, const QString &detail)
QQmlJS::AST::LabelledStatement * _labelledStatement
QSet< QString > m_globalNames
VolatileMemoryLocations _volatileMemoryLocations
Moth::BytecodeGenerator::Label * _returnLabel
CodegenWarningInterface * _interface
bool handleTaggedTemplate(Reference base, QQmlJS::AST::TaggedTemplate *ast)
BytecodeGenerator * bytecodeGenerator
void variableDeclarationList(QQmlJS::AST::VariableDeclarationList *ast)
void destructurePropertyList(const Reference &object, QQmlJS::AST::PatternPropertyList *bindingList, bool isDefinition=false)
Arguments pushArgs(QQmlJS::AST::ArgumentList *args)
void condition(QQmlJS::AST::ExpressionNode *ast, const BytecodeGenerator::Label *iftrue, const BytecodeGenerator::Label *iffalse, bool trueBlockFollowsCondition)
bool _tailCallsAreAllowed
void initializeAndDestructureBindingElement(QQmlJS::AST::PatternElement *e, const Reference &baseRef=Reference(), bool isDefinition=false)
Reference referenceForPropertyName(const Codegen::Reference &object, QQmlJS::AST::PropertyName *name)
void enterContext(QQmlJS::AST::Node *node)
void destructureElementList(const Reference &array, QQmlJS::AST::PatternElementList *bindingList, bool isDefinition=false)
QQmlRefPointer< QV4::CompiledData::CompilationUnit > generateCompilationUnit(bool generateUnitData=true)
void accept(QQmlJS::AST::Node *node)
int registerString(const QString &name)
void emitReturn(const Reference &expr)
int registerQmlContextPropertyGetterLookup(int nameIndex, JSUnitGenerator::LookupMode mode)
void generateFromProgram(const QString &fileName, const QString &finalUrl, const QString &sourceCode, QQmlJS::AST::Program *ast, Module *module, ContextType contextType=ContextType::Global)
bool exprAccept(Format f)
QQmlJS::DiagnosticMessage error() const
Reference referenceForName(const QString &name, bool lhs, const QQmlJS::SourceLocation &accessLocation=QQmlJS::SourceLocation())
static const char * s_globalNames[]
void clearExprResultName()
QV4::Compiler::JSUnitGenerator * jsUnitGenerator
void variableDeclaration(QQmlJS::AST::PatternElement *ast)
int registerGetterLookup(int nameIndex, JSUnitGenerator::LookupMode mode)
void destructurePattern(QQmlJS::AST::Pattern *p, const Reference &rhs)
QSet< QQmlJS::AST::Node * > m_seenOptionalChainNodes
virtual int defineFunction(const QString &name, QQmlJS::AST::Node *ast, QQmlJS::AST::FormalParameterList *formals, QQmlJS::AST::StatementList *body)
void setExprResult(const Reference &result)
int registerGlobalGetterLookup(int nameIndex, JSUnitGenerator::LookupMode mode)
bool storeSourceLocations
bool functionEndsWithReturn
bool visit(QQmlJS::AST::ArgumentList *ast) override
ErrorType errorType() const
void endVisit(QQmlJS::AST::CallExpression *ast) override
Reference targetForPatternElement(QQmlJS::AST::PatternElement *p)
Reference unop(UnaryOperation op, const Reference &expr)
Codegen(QV4::Compiler::JSUnitGenerator *jsUnitGenerator, bool strict, CodegenWarningInterface *iface=defaultCodegenWarningInterface(), bool storeSourceLocations=false)
Reference binopHelper(QQmlJS::AST::BinaryExpression *ast, QSOperator::Op oper, Reference &left, Reference &right)
void handleTryFinally(QQmlJS::AST::TryStatement *ast)
QQmlJS::DiagnosticMessage _error
void handleCall(Reference &base, Arguments calldata, int slotForFunction, int slotForThisObject, bool optional=false)
void program(QQmlJS::AST::Program *ast)
static QQmlRefPointer< QV4::CompiledData::CompilationUnit > compileModule(bool debugMode, const QString &url, const QString &sourceCode, const QDateTime &sourceTimeStamp, QList< QQmlJS::DiagnosticMessage > *diagnostics)
void createTemplateObject(QQmlJS::AST::TemplateLiteral *t)
void pushExpr(Result &&expr)
const Result & currentExpr() const
Reference expression(QQmlJS::AST::ExpressionNode *ast, const QString &name=QString())
std::stack< OptionalChainState > m_optionalChainsStates
bool throwSyntaxErrorOnEvalOrArgumentsInStrictMode(const Reference &r, const QQmlJS::SourceLocation &loc)
Arguments pushTemplateArgs(QQmlJS::AST::TemplateLiteral *args)
Reference jumpBinop(QSOperator::Op oper, Reference &left, Reference &right)
void statement(QQmlJS::AST::Statement *ast)
Context * enterBlock(QQmlJS::AST::Node *node)
ControlFlow * controlFlow
void statementList(QQmlJS::AST::StatementList *ast)
bool inFormalParameterList
void generateFromModule(const QString &fileName, const QString &finalUrl, const QString &sourceCode, QQmlJS::AST::ESModule *ast, Module *module)
virtual void throwReferenceError(const QQmlJS::SourceLocation &loc, const QString &detail)
Context * _functionContext
void throwRecursionDepthError() override
Reference exprResult() const
void loadClosure(int index)
Q_REQUIRED_RESULT Jump jumpFalse()
Jump addJumpInstruction(const InstrData< InstrT > &data)
void setLocation(const QQmlJS::SourceLocation &loc)
void jumpStrictEqual(const StackSlot &lhs, const Label &target)
Q_REQUIRED_RESULT Jump jumpTrue()
Q_REQUIRED_RESULT Jump jumpNotUndefined()
void addInstruction(const InstrData< InstrT > &data)
void incrementStatement()
void addLoopStart(const Label &start)
Q_REQUIRED_RESULT Jump jump()
void addCJumpInstruction(bool jumpOnFalse, const Label *trueLabel, const Label *falseLabel)
void finalize(Compiler::Context *context)
int newRegisterArray(int n)
void unwindToLabel(int level, const Label &target)
int registerCount() const
static StackSlot createRegister(int index)
QSet< QString >::iterator it
QList< QVariant > arguments
std::list< QString >::iterator Name
Combined button and popup list for selecting options.
QString dumpBytecode(const char *code, int len, int nLocals, int nFormals, int, const QVector< CompiledData::CodeOffsetToLineAndStatement > &lineAndStatementNumberMapping)
uint stringToArrayIndex(const T *ch, const T *end)
#define QT_WARNING_DISABLE_GCC(text)
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 return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
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 * sub
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static void jump(QtMsgType t, const QMessageLogContext &context, const QString &m)
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qInf()
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qQNaN()
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLenum GLsizei const GLuint * ids
static void add(QPainterPath &path, const QWingedEdge &list, int edge, QPathEdge::Traversal traversal)
static QString toLocalFile(const QString &url)
Members members(const Members &candidates, QTypeRevision maxMajorVersion, Postprocess &&process)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
QT_BEGIN_NAMESPACE constexpr void qSwap(T &value1, T &value2) noexcept(std::is_nothrow_swappable_v< T >)
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept
#define Q_UNIMPLEMENTED()
static Node * completionStatement(StatementList *list)
static CompletionState completionState(StatementList *list)
static QSOperator::Op baseOp(int op)
static bool endsWithReturn(Module *module, Node *node)
static void setJumpOutLocation(QV4::Moth::BytecodeGenerator *bytecodeGenerator, const Statement *body, const SourceLocation &fallback)
static const QV4::Value & constant(Function *function, int index)
QUrl url("example.com")
[constructor-url-reference]
\inmodule QtCore \reentrant
static Reference fromScopedLocal(Codegen *cg, int index, int scope)
static Reference fromImport(Codegen *cg, int index)
Moth::StackSlot stackSlot() const
bool operator==(const Reference &other) const
quint32 hasSavedCallBaseSlot
Q_REQUIRED_RESULT Reference storeRetainAccumulator() const
static Reference fromConst(Codegen *cg, QV4::ReturnedValue constant)
static Reference fromName(Codegen *cg, const QString &name)
Q_REQUIRED_RESULT Reference baseObject() const
static Reference fromMember(const Reference &baseRef, const QString &name, QQmlJS::SourceLocation sourceLocation=QQmlJS::SourceLocation(), bool isOptional=false, std::vector< Moth::BytecodeGenerator::Jump > *optionalChainJumpsToPatch=nullptr)
Reference storeConsumeAccumulator() const
static Reference fromAccumulator(Codegen *cg)
static Reference fromSuperProperty(const Reference &property)
static Reference fromStackSlot(Codegen *cg, int tempIndex=-1, bool isLocal=false)
void loadInAccumulator() const
QV4::ReturnedValue constant
Moth::StackSlot elementBase
int savedCallPropertyNameIndex
Reference asLValue() const
quint32 stackSlotIsLocalOrArgument
static Reference fromSubscript(const Reference &baseRef, const Reference &subscript)
enum QV4::Compiler::Codegen::Reference::Type type
static Q_REQUIRED_RESULT Reference storeConstOnStack(Codegen *cg, QV4::ReturnedValue constant)
bool storeWipesAccumulator() const
Q_REQUIRED_RESULT Reference storeOnStack() const
static Reference fromThis(Codegen *cg)
static Reference fromSuper(Codegen *cg)
QQmlJS::SourceLocation declarationLocation
void emitBlockFooter(Compiler::Codegen *codegen)
void emitBlockHeader(Compiler::Codegen *codegen)
QQmlJS::AST::BoundNames arguments
bool canHaveTailCalls() const
bool requiresExecutionContext
ResolvedName resolveName(const QString &name, const QQmlJS::SourceLocation &accessLocation)
QString localNameForDefaultExport
bool requiresImplicitReturnValue() const
int registerCountInFunction
QVector< CompiledData::CodeOffsetToLineAndStatement > lineAndStatementNumberMapping
UnwindTarget unwindTarget(UnwindType type, const QString &label=QString())
virtual QString label() const
static bool lessThan(const ExportEntry &lhs, const ExportEntry &rhs)
int registerJSClass(const QStringList &members)
int registerRegExp(QQmlJS::AST::RegExpLiteral *regexp)
QV4::CompiledData::Unit * generateUnit(GeneratorOption option=GenerateWithStringTable)
QString codeGeneratorName
QString stringForIndex(int index) const
QVector< ImportEntry > importEntries
QVector< ExportEntry > localExportEntries
QHash< QQmlJS::AST::Node *, Context * > contextMap
QList< Context * > functions
QVector< TemplateObject > templateObjects
QStringList moduleRequests
QVector< ExportEntry > starExportEntries
QVector< ExportEntry > indirectExportEntries
QList< Context * > blocks
static ReturnedValue smallestNumber(double d)
static constexpr ReturnedValue undefined()
static constexpr ReturnedValue null()
static constexpr StaticValue emptyValue()
static constexpr StaticValue fromReturnedValue(ReturnedValue val)