33 const QV4::Compiler::Context *compilerContext,
34 const QV4::Compiler::JSUnitGenerator *unitGenerator,
35 const QQmlJSTypeResolver *typeResolver, QQmlJSLogger *logger,
36 const BasicBlocks &basicBlocks,
const InstructionAnnotations &annotations);
37 ~QQmlJSCodeGenerator() =
default;
39 QQmlJSAotFunction run(
const Function *function,
bool basicBlocksValidationFailed);
42 struct CodegenState :
public State
44 QString accumulatorVariableIn;
45 QString accumulatorVariableOut;
51 struct Q_QMLCOMPILER_EXPORT AccumulatorConverter
53 Q_DISABLE_COPY_MOVE(AccumulatorConverter);
54 AccumulatorConverter(QQmlJSCodeGenerator *generator);
55 ~AccumulatorConverter();
58 const QQmlJSRegisterContent accumulatorOut;
59 const QString accumulatorVariableIn;
60 const QString accumulatorVariableOut;
61 QQmlJSCodeGenerator *generator =
nullptr;
64 virtual QString metaObject(
const QQmlJSScope::ConstPtr &objectType);
65 virtual QString metaType(
const QQmlJSScope::ConstPtr &type);
67 void generate_Ret() override;
68 void generate_Debug() override;
69 void generate_LoadConst(
int index) override;
70 void generate_LoadZero() override;
71 void generate_LoadTrue() override;
72 void generate_LoadFalse() override;
73 void generate_LoadNull() override;
74 void generate_LoadUndefined() override;
75 void generate_LoadInt(
int value) override;
76 void generate_MoveConst(
int constIndex,
int destTemp) override;
77 void generate_LoadReg(
int reg) override;
78 void generate_StoreReg(
int reg) override;
79 void generate_MoveReg(
int srcReg,
int destReg) override;
80 void generate_LoadImport(
int index) override;
81 void generate_LoadLocal(
int index) override;
82 void generate_StoreLocal(
int index) override;
83 void generate_LoadScopedLocal(
int scope,
int index) override;
84 void generate_StoreScopedLocal(
int scope,
int index) override;
85 void generate_LoadRuntimeString(
int stringId) override;
86 void generate_MoveRegExp(
int regExpId,
int destReg) override;
87 void generate_LoadClosure(
int value) override;
88 void generate_LoadName(
int nameIndex) override;
89 void generate_LoadGlobalLookup(
int index) override;
90 void generate_LoadQmlContextPropertyLookup(
int index) override;
91 void generate_StoreNameSloppy(
int nameIndex) override;
92 void generate_StoreNameStrict(
int name) override;
93 void generate_LoadElement(
int base) override;
94 void generate_StoreElement(
int base,
int index) override;
95 void generate_LoadProperty(
int nameIndex) override;
96 void generate_LoadOptionalProperty(
int name,
int offset) override;
97 void generate_GetLookup(
int index) override;
98 void generate_GetOptionalLookup(
int index,
int offset) override;
99 void generate_StoreProperty(
int name,
int baseReg) override;
100 void generate_SetLookup(
int index,
int base) override;
101 void generate_LoadSuperProperty(
int property) override;
102 void generate_StoreSuperProperty(
int property) override;
103 void generate_Yield() override;
104 void generate_YieldStar() override;
105 void generate_Resume(
int) override;
107 void generate_CallValue(
int name,
int argc,
int argv) override;
108 void generate_CallWithReceiver(
int name,
int thisObject,
int argc,
int argv) override;
109 void generate_CallProperty(
int name,
int base,
int argc,
int argv) override;
110 void generate_CallPropertyLookup(
int lookupIndex,
int base,
int argc,
int argv) override;
111 void generate_CallName(
int name,
int argc,
int argv) override;
112 void generate_CallPossiblyDirectEval(
int argc,
int argv) override;
113 void generate_CallGlobalLookup(
int index,
int argc,
int argv) override;
114 void generate_CallQmlContextPropertyLookup(
int index,
int argc,
int argv) override;
115 void generate_CallWithSpread(
int func,
int thisObject,
int argc,
int argv) override;
116 void generate_TailCall(
int func,
int thisObject,
int argc,
int argv) override;
117 void generate_Construct(
int func,
int argc,
int argv) override;
118 void generate_ConstructWithSpread(
int func,
int argc,
int argv) override;
119 void generate_SetUnwindHandler(
int offset) override;
120 void generate_UnwindDispatch() override;
121 void generate_UnwindToLabel(
int level,
int offset) override;
122 void generate_DeadTemporalZoneCheck(
int name) override;
123 void generate_ThrowException() override;
124 void generate_GetException() override;
125 void generate_SetException() override;
126 void generate_CreateCallContext() override;
127 void generate_PushCatchContext(
int index,
int name) override;
128 void generate_PushWithContext() override;
129 void generate_PushBlockContext(
int index) override;
130 void generate_CloneBlockContext() override;
131 void generate_PushScriptContext(
int index) override;
132 void generate_PopScriptContext() override;
133 void generate_PopContext() override;
134 void generate_GetIterator(
int iterator) override;
135 void generate_IteratorNext(
int value,
int offset) override;
136 void generate_IteratorNextForYieldStar(
int iterator,
int object,
int offset) override;
137 void generate_IteratorClose() override;
138 void generate_DestructureRestElement() override;
139 void generate_DeleteProperty(
int base,
int index) override;
140 void generate_DeleteName(
int name) override;
141 void generate_TypeofName(
int name) override;
142 void generate_TypeofValue() override;
143 void generate_DeclareVar(
int varName,
int isDeletable) override;
144 void generate_DefineArray(
int argc,
int args) override;
145 void generate_DefineObjectLiteral(
int internalClassId,
int argc,
int args) override;
146 void generate_CreateClass(
int classIndex,
int heritage,
int computedNames) override;
147 void generate_CreateMappedArgumentsObject() override;
148 void generate_CreateUnmappedArgumentsObject() override;
149 void generate_CreateRestParameter(
int argIndex) override;
150 void generate_ConvertThisToObject() override;
151 void generate_LoadSuperConstructor() override;
152 void generate_ToObject() override;
153 void generate_Jump(
int offset) override;
154 void generate_JumpTrue(
int offset) override;
155 void generate_JumpFalse(
int offset) override;
156 void generate_JumpNoException(
int offset) override;
157 void generate_JumpNotUndefined(
int offset) override;
158 void generate_CheckException() override;
159 void generate_CmpEqNull() override;
160 void generate_CmpNeNull() override;
161 void generate_CmpEqInt(
int lhs) override;
162 void generate_CmpNeInt(
int lhs) override;
163 void generate_CmpEq(
int lhs) override;
164 void generate_CmpNe(
int lhs) override;
165 void generate_CmpGt(
int lhs) override;
166 void generate_CmpGe(
int lhs) override;
167 void generate_CmpLt(
int lhs) override;
168 void generate_CmpLe(
int lhs) override;
169 void generate_CmpStrictEqual(
int lhs) override;
170 void generate_CmpStrictNotEqual(
int lhs) override;
171 void generate_CmpIn(
int lhs) override;
172 void generate_CmpInstanceOf(
int lhs) override;
173 void generate_As(
int lhs) override;
174 void generate_UNot() override;
175 void generate_UPlus() override;
176 void generate_UMinus() override;
177 void generate_UCompl() override;
178 void generate_Increment() override;
179 void generate_Decrement() override;
180 void generate_Add(
int lhs) override;
181 void generate_BitAnd(
int lhs) override;
182 void generate_BitOr(
int lhs) override;
183 void generate_BitXor(
int lhs) override;
184 void generate_UShr(
int lhs) override;
185 void generate_Shr(
int lhs) override;
186 void generate_Shl(
int lhs) override;
187 void generate_BitAndConst(
int rhs) override;
188 void generate_BitOrConst(
int rhs) override;
189 void generate_BitXorConst(
int rhs) override;
190 void generate_UShrConst(
int rhs) override;
191 void generate_ShrConst(
int value) override;
192 void generate_ShlConst(
int rhs) override;
193 void generate_Exp(
int lhs) override;
194 void generate_Mul(
int lhs) override;
195 void generate_Div(
int lhs) override;
196 void generate_Mod(
int lhs) override;
197 void generate_Sub(
int lhs) override;
198 void generate_InitializeBlockDeadTemporalZone(
int firstReg,
int count) override;
199 void generate_ThrowOnNullOrUndefined() override;
200 void generate_GetTemplateObject(
int index) override;
202 Verdict startInstruction(QV4::Moth::Instr::Type) override;
203 void endInstruction(QV4::Moth::Instr::Type) override;
205 void addInclude(
const QString &include)
207 Q_ASSERT(!include.isEmpty());
208 m_includes.append(include);
211 QString conversion(QQmlJSRegisterContent from,
212 QQmlJSRegisterContent to,
213 const QString &variable);
215 QString conversion(
const QQmlJSScope::ConstPtr &from,
216 QQmlJSRegisterContent to,
217 const QString &variable)
219 const QQmlJSScope::ConstPtr contained = to.containedType();
220 if (to.storedType() == contained
221 || m_typeResolver->isNumeric(to.storedType())
222 || to.storedType()->isReferenceType()
223 || from == contained) {
230 return convertStored(from, to.storedType(), variable);
232 return convertContained(
234 m_typeResolver->syntheticType(from), m_typeResolver->storedType(from)),
239 QString conversion(QQmlJSRegisterContent from,
240 const QQmlJSScope::ConstPtr &to,
241 const QString &variable)
243 Q_ASSERT(m_typeResolver->storedType(to) == to);
244 return conversion(from, m_pool->storedIn(m_pool->castTo(from, to), to), variable);
247 QString conversion(
const QQmlJSScope::ConstPtr &from,
248 const QQmlJSScope::ConstPtr &to,
249 const QString &variable)
251 return convertStored(from, to, variable);
254 QString convertStored(
const QQmlJSScope::ConstPtr &from,
255 const QQmlJSScope::ConstPtr &to,
256 const QString &variable);
258 QString convertContained(QQmlJSRegisterContent from,
259 QQmlJSRegisterContent to,
260 const QString &variable);
262 void generateReturnError();
263 void reject(
const QString &thing);
264 void skip(
const QString &thing);
267 T reject(
const QString &thing)
273 QString metaTypeFromType(
const QQmlJSScope::ConstPtr &type)
const;
274 QString metaTypeFromName(
const QQmlJSScope::ConstPtr &type)
const;
275 QString compositeMetaType(
const QString &elementName)
const;
276 QString compositeListMetaType(
const QString &elementName)
const;
278 QString contentPointer(QQmlJSRegisterContent content,
const QString &var);
279 QString contentType(QQmlJSRegisterContent content,
const QString &var);
281 void generateSetInstructionPointer();
282 void generateLookup(
const QString &lookup,
const QString &initialization,
283 const QString &resultPreparation = QString());
284 QString getLookupPreparation(
285 QQmlJSRegisterContent content,
const QString &var,
int lookup);
286 void generateEnumLookup(
int index);
288 QString registerVariable(
int index)
const;
289 QString lookupVariable(
int lookupIndex)
const;
290 QString consumedRegisterVariable(
int index)
const;
291 QString consumedAccumulatorVariableIn()
const;
293 QString changedRegisterVariable()
const;
294 QQmlJSRegisterContent registerType(
int index)
const;
295 QQmlJSRegisterContent lookupType(
int lookupIndex)
const;
296 bool shouldMoveRegister(
int index)
const;
299 CodegenState m_state;
301 void resetState() { m_state = CodegenState(); }
304 void generateExceptionCheck();
306 void generateEqualityOperation(
307 QQmlJSRegisterContent lhsContent,
const QString &lhsName,
308 const QString &function,
bool invert) {
309 generateEqualityOperation(
310 lhsContent, m_state.accumulatorIn(), lhsName, m_state.accumulatorVariableIn,
314 void generateEqualityOperation(
315 QQmlJSRegisterContent lhsContent, QQmlJSRegisterContent rhsContent,
316 const QString &lhsName,
const QString &rhsName,
const QString &function,
bool invert);
317 void generateCompareOperation(
int lhs,
const QString &cppOperator);
318 void generateArithmeticOperation(
int lhs,
const QString &cppOperator);
319 void generateShiftOperation(
int lhs,
const QString &cppOperator);
320 void generateArithmeticOperation(
321 const QString &lhs,
const QString &rhs,
const QString &cppOperator);
322 void generateArithmeticConstOperation(
int lhsConst,
const QString &cppOperator);
323 void generateJumpCodeWithTypeConversions(
int relativeOffset);
324 void generateUnaryOperation(
const QString &cppOperator);
325 void generateInPlaceOperation(
const QString &cppOperator);
326 void generateMoveOutVarAfterCall(
const QString &outVar);
327 void generateTypeLookup(
int index);
328 void generateVariantEqualityComparison(
329 QQmlJSRegisterContent nonStorable,
const QString ®isterName,
bool invert);
330 void generateVariantEqualityComparison(
331 QQmlJSRegisterContent storableContent,
const QString &typedRegisterName,
332 const QString &varRegisterName,
bool invert);
333 void generateArrayInitializer(
int argc,
int argv);
334 void generateWriteBack(
int registerIndex);
335 void rejectIfNonQObjectOut(
const QString &error);
336 void rejectIfBadArray();
339 QString eqIntExpression(
int lhsConst);
342 int argc,
int argv,
const QString &callMethodTemplate,
343 const QString &initMethodTemplate, QString *outVar);
345 QString castTargetName(
const QQmlJSScope::ConstPtr &type)
const;
347 bool inlineStringMethod(
const QString &name,
int base,
int argc,
int argv);
348 bool inlineTranslateMethod(
const QString &name,
int argc,
int argv);
349 bool inlineMathMethod(
const QString &name,
int argc,
int argv);
350 bool inlineConsoleMethod(
const QString &name,
int argc,
int argv);
351 bool inlineArrayMethod(
const QString &name,
int base,
int argc,
int argv);
353 void generate_GetLookupHelper(
int index);
355 QString resolveValueTypeContentPointer(
356 const QQmlJSScope::ConstPtr &required, QQmlJSRegisterContent actual,
357 const QString &variable,
const QString &errorMessage);
358 QString resolveQObjectPointer(
359 const QQmlJSScope::ConstPtr &required, QQmlJSRegisterContent actual,
360 const QString &variable,
const QString &errorMessage);
361 bool generateContentPointerCheck(
362 const QQmlJSScope::ConstPtr &required, QQmlJSRegisterContent actual,
363 const QString &variable,
const QString &errorMessage);
365 QString generateCallConstructor(
366 const QQmlJSMetaMethod &ctor,
const QList<QQmlJSRegisterContent> &argumentTypes,
367 const QStringList &arguments,
const QString &metaType,
const QString &metaObject);
369 QString generateVariantMapGetLookup(
const QString &map,
const int nameIndex);
370 QString generateVariantMapSetLookup(
371 const QString &map,
const int nameIndex,
const QQmlJSScope::ConstPtr &property,
372 const QString &variableIn);
374 QQmlJSRegisterContent originalType(QQmlJSRegisterContent tracked)
376 const QQmlJSRegisterContent restored = m_typeResolver->original(tracked);
377 return m_pool->storedIn(
378 restored, m_typeResolver->original(tracked.storage()).containedType());
381 QQmlJSRegisterContent literalType(
const QQmlJSScope::ConstPtr &contained)
383 return m_pool->storedIn(m_typeResolver->literalType(contained), contained);
386 bool isRegisterAffectedBySideEffects(
int registerIndex);
389 QHash<
int, QString> m_labels;
391 const QV4::Compiler::Context *m_context =
nullptr;
393 bool m_skipUntilNextLabel =
false;
395 QStringList m_includes;
397 struct RegisterVariablesValue
399 QString variableName;
400 QQmlJSScope::ConstPtr storedType;
401 int initialRegisterIndex = InvalidRegister;
405 QHash<QQmlJSRegisterContent, RegisterVariablesValue> m_registerVariables;