33 QQmlJSCodeGenerator(
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 bool noAotValidation);
38 ~QQmlJSCodeGenerator() =
default;
40 QQmlJSAotFunction run(
const Function *function,
bool basicBlocksValidationFailed);
42 LookupSignatures lookupSignatures()
const {
return m_lookupSignaturesRecorder.signatures(); }
45 struct CodegenState :
public State
47 QString accumulatorVariableIn;
48 QString accumulatorVariableOut;
54 struct Q_QMLCOMPILER_EXPORT AccumulatorConverter
56 Q_DISABLE_COPY_MOVE(AccumulatorConverter);
57 AccumulatorConverter(QQmlJSCodeGenerator *generator);
58 ~AccumulatorConverter();
61 const QQmlJSRegisterContent accumulatorOut;
62 const QString accumulatorVariableIn;
63 const QString accumulatorVariableOut;
64 QQmlJSCodeGenerator *generator =
nullptr;
67 virtual QString metaObject(
const QQmlJSScope::ConstPtr &objectType);
68 virtual QString metaType(
const QQmlJSScope::ConstPtr &type);
70 void generate_Ret() override;
71 void generate_Debug() override;
72 void generate_LoadConst(
int index) override;
73 void generate_LoadZero() override;
74 void generate_LoadTrue() override;
75 void generate_LoadFalse() override;
76 void generate_LoadNull() override;
77 void generate_LoadUndefined() override;
78 void generate_LoadInt(
int value) override;
79 void generate_MoveConst(
int constIndex,
int destTemp) override;
80 void generate_LoadReg(
int reg) override;
81 void generate_StoreReg(
int reg) override;
82 void generate_MoveReg(
int srcReg,
int destReg) override;
83 void generate_LoadImport(
int index) override;
84 void generate_LoadLocal(
int index) override;
85 void generate_StoreLocal(
int index) override;
86 void generate_LoadScopedLocal(
int scope,
int index) override;
87 void generate_StoreScopedLocal(
int scope,
int index) override;
88 void generate_LoadRuntimeString(
int stringId) override;
89 void generate_MoveRegExp(
int regExpId,
int destReg) override;
90 void generate_LoadClosure(
int value) override;
91 void generate_LoadName(
int nameIndex) override;
92 void generate_LoadGlobalLookup(
int index) override;
93 void generate_LoadQmlContextPropertyLookup(
int index) override;
94 void generate_StoreNameSloppy(
int nameIndex) override;
95 void generate_StoreNameStrict(
int name) override;
96 void generate_LoadElement(
int base) override;
97 void generate_StoreElement(
int base,
int index) override;
98 void generate_LoadProperty(
int nameIndex) override;
99 void generate_LoadOptionalProperty(
int name,
int offset) override;
100 void generate_GetLookup(
int index) override;
101 void generate_GetOptionalLookup(
int index,
int offset) override;
102 void generate_StoreProperty(
int name,
int baseReg) override;
103 void generate_SetLookup(
int index,
int base) override;
104 void generate_LoadSuperProperty(
int property) override;
105 void generate_StoreSuperProperty(
int property) override;
106 void generate_Yield() override;
107 void generate_YieldStar() override;
108 void generate_Resume(
int) override;
110 void generate_CallValue(
int name,
int argc,
int argv) override;
111 void generate_CallWithReceiver(
int name,
int thisObject,
int argc,
int argv) override;
112 void generate_CallProperty(
int name,
int base,
int argc,
int argv) override;
113 void generate_CallPropertyLookup(
int lookupIndex,
int base,
int argc,
int argv) override;
114 void generate_CallName(
int name,
int argc,
int argv) override;
115 void generate_CallPossiblyDirectEval(
int argc,
int argv) override;
116 void generate_CallGlobalLookup(
int index,
int argc,
int argv) override;
117 void generate_CallQmlContextPropertyLookup(
int index,
int argc,
int argv) override;
118 void generate_CallWithSpread(
int func,
int thisObject,
int argc,
int argv) override;
119 void generate_TailCall(
int func,
int thisObject,
int argc,
int argv) override;
120 void generate_Construct(
int func,
int argc,
int argv) override;
121 void generate_ConstructWithSpread(
int func,
int argc,
int argv) override;
122 void generate_SetUnwindHandler(
int offset) override;
123 void generate_UnwindDispatch() override;
124 void generate_UnwindToLabel(
int level,
int offset) override;
125 void generate_DeadTemporalZoneCheck(
int name) override;
126 void generate_ThrowException() override;
127 void generate_GetException() override;
128 void generate_SetException() override;
129 void generate_CreateCallContext() override;
130 void generate_PushCatchContext(
int index,
int name) override;
131 void generate_PushWithContext() override;
132 void generate_PushBlockContext(
int index) override;
133 void generate_CloneBlockContext() override;
134 void generate_PushScriptContext(
int index) override;
135 void generate_PopScriptContext() override;
136 void generate_PopContext() override;
137 void generate_GetIterator(
int iterator) override;
138 void generate_IteratorNext(
int value,
int offset) override;
139 void generate_IteratorNextForYieldStar(
int iterator,
int object,
int offset) override;
140 void generate_IteratorClose() override;
141 void generate_DestructureRestElement() override;
142 void generate_DeleteProperty(
int base,
int index) override;
143 void generate_DeleteName(
int name) override;
144 void generate_TypeofName(
int name) override;
145 void generate_TypeofValue() override;
146 void generate_DeclareVar(
int varName,
int isDeletable) override;
147 void generate_DefineArray(
int argc,
int args) override;
148 void generate_DefineObjectLiteral(
int internalClassId,
int argc,
int args) override;
149 void generate_CreateClass(
int classIndex,
int heritage,
int computedNames) override;
150 void generate_CreateMappedArgumentsObject() override;
151 void generate_CreateUnmappedArgumentsObject() override;
152 void generate_CreateRestParameter(
int argIndex) override;
153 void generate_ConvertThisToObject() override;
154 void generate_LoadSuperConstructor() override;
155 void generate_ToObject() override;
156 void generate_Jump(
int offset) override;
157 void generate_JumpTrue(
int offset) override;
158 void generate_JumpFalse(
int offset) override;
159 void generate_JumpNoException(
int offset) override;
160 void generate_JumpNotUndefined(
int offset) override;
161 void generate_CheckException() override;
162 void generate_CmpEqNull() override;
163 void generate_CmpNeNull() override;
164 void generate_CmpEqInt(
int lhs) override;
165 void generate_CmpNeInt(
int lhs) override;
166 void generate_CmpEq(
int lhs) override;
167 void generate_CmpNe(
int lhs) override;
168 void generate_CmpGt(
int lhs) override;
169 void generate_CmpGe(
int lhs) override;
170 void generate_CmpLt(
int lhs) override;
171 void generate_CmpLe(
int lhs) override;
172 void generate_CmpStrictEqual(
int lhs) override;
173 void generate_CmpStrictNotEqual(
int lhs) override;
174 void generate_CmpIn(
int lhs) override;
175 void generate_CmpInstanceOf(
int lhs) override;
176 void generate_As(
int lhs) override;
177 void generate_UNot() override;
178 void generate_UPlus() override;
179 void generate_UMinus() override;
180 void generate_UCompl() override;
181 void generate_Increment() override;
182 void generate_Decrement() override;
183 void generate_Add(
int lhs) override;
184 void generate_BitAnd(
int lhs) override;
185 void generate_BitOr(
int lhs) override;
186 void generate_BitXor(
int lhs) override;
187 void generate_UShr(
int lhs) override;
188 void generate_Shr(
int lhs) override;
189 void generate_Shl(
int lhs) override;
190 void generate_BitAndConst(
int rhs) override;
191 void generate_BitOrConst(
int rhs) override;
192 void generate_BitXorConst(
int rhs) override;
193 void generate_UShrConst(
int rhs) override;
194 void generate_ShrConst(
int value) override;
195 void generate_ShlConst(
int rhs) override;
196 void generate_Exp(
int lhs) override;
197 void generate_Mul(
int lhs) override;
198 void generate_Div(
int lhs) override;
199 void generate_Mod(
int lhs) override;
200 void generate_Sub(
int lhs) override;
201 void generate_InitializeBlockDeadTemporalZone(
int firstReg,
int count) override;
202 void generate_ThrowOnNullOrUndefined() override;
203 void generate_GetTemplateObject(
int index) override;
205 Verdict startInstruction(QV4::Moth::Instr::Type) override;
206 void endInstruction(QV4::Moth::Instr::Type) override;
208 void addInclude(
const QString &include)
210 Q_ASSERT(!include.isEmpty());
211 m_includes.append(include);
214 QString conversion(QQmlJSRegisterContent from,
215 QQmlJSRegisterContent to,
216 const QString &variable);
218 QString conversion(
const QQmlJSScope::ConstPtr &from,
219 QQmlJSRegisterContent to,
220 const QString &variable)
222 const QQmlJSScope::ConstPtr contained = to.containedType();
223 if (to.storedType() == contained
224 || m_typeResolver->isNumeric(to.storedType())
225 || to.storedType()->isReferenceType()
226 || from == contained) {
233 return convertStored(from, to.storedType(), variable);
235 return convertContained(
237 m_typeResolver->syntheticType(from), m_typeResolver->storedType(from)),
242 QString conversion(QQmlJSRegisterContent from,
243 const QQmlJSScope::ConstPtr &to,
244 const QString &variable)
246 Q_ASSERT(m_typeResolver->storedType(to) == to);
247 return conversion(from, m_pool->storedIn(m_pool->castTo(from, to), to), variable);
250 QString conversion(
const QQmlJSScope::ConstPtr &from,
251 const QQmlJSScope::ConstPtr &to,
252 const QString &variable)
254 return convertStored(from, to, variable);
257 QString convertStored(
const QQmlJSScope::ConstPtr &from,
258 const QQmlJSScope::ConstPtr &to,
259 const QString &variable);
261 QString convertContained(QQmlJSRegisterContent from,
262 QQmlJSRegisterContent to,
263 const QString &variable);
265 void generateReturnError();
266 void reject(
const QString &thing);
267 void skip(
const QString &thing);
270 T reject(
const QString &thing)
276 QString metaTypeFromType(
const QQmlJSScope::ConstPtr &type)
const;
277 QString metaTypeFromName(
const QQmlJSScope::ConstPtr &type)
const;
278 QString compositeMetaType(
const QString &elementName)
const;
279 QString compositeListMetaType(
const QString &elementName)
const;
281 QString contentPointer(QQmlJSRegisterContent content,
const QString &var);
282 QString contentType(QQmlJSRegisterContent content,
const QString &var);
284 void generateSetInstructionPointer();
285 void generateLookup(
const QString &lookup,
const QString &initialization,
286 const QString &resultPreparation = QString());
287 QString getLookupPreparation(
288 QQmlJSRegisterContent content,
const QString &var,
int lookup);
289 void generateEnumLookup(
int index);
291 QString registerVariable(
int index)
const;
292 QString lookupVariable(
int lookupIndex)
const;
293 QString consumedRegisterVariable(
int index)
const;
294 QString consumedAccumulatorVariableIn()
const;
296 QString changedRegisterVariable()
const;
297 QQmlJSRegisterContent registerType(
int index)
const;
298 QQmlJSRegisterContent lookupType(
int lookupIndex)
const;
299 bool shouldMoveRegister(
int index)
const;
301 void recordPropertyLookup(
const QQmlJSScope::ConstPtr &base,
const QQmlJSMetaProperty &prop);
302 void recordMethodLookup(
const QQmlJSScope::ConstPtr &base,
const QQmlJSMetaMethod &method);
303 void recordEnumKeyLookup(
const QQmlJSScope::ConstPtr &base,
const QQmlJSMetaEnum &metaEnum,
304 const QString &keyName);
307 CodegenState m_state;
309 void resetState() { m_state = CodegenState(); }
312 void generateExceptionCheck();
314 void generateEqualityOperation(
315 QQmlJSRegisterContent lhsContent,
const QString &lhsName,
316 const QString &function,
bool invert) {
317 generateEqualityOperation(
318 lhsContent, m_state.accumulatorIn(), lhsName, m_state.accumulatorVariableIn,
322 void generateEqualityOperation(
323 QQmlJSRegisterContent lhsContent, QQmlJSRegisterContent rhsContent,
324 const QString &lhsName,
const QString &rhsName,
const QString &function,
bool invert);
325 void generateCompareOperation(
int lhs,
const QString &cppOperator);
326 void generateArithmeticOperation(
int lhs,
const QString &cppOperator);
327 void generateShiftOperation(
int lhs,
const QString &cppOperator);
328 void generateArithmeticOperation(
329 const QString &lhs,
const QString &rhs,
const QString &cppOperator);
330 void generateArithmeticConstOperation(
int lhsConst,
const QString &cppOperator);
331 void generateJumpCodeWithTypeConversions(
int relativeOffset);
332 void generateUnaryOperation(
const QString &cppOperator);
333 void generateInPlaceOperation(
const QString &cppOperator);
334 void generateMoveOutVarAfterCall(
const QString &outVar);
335 void generateTypeLookup(
int index);
336 void generateVariantEqualityComparison(
337 QQmlJSRegisterContent nonStorable,
const QString ®isterName,
bool invert);
338 void generateVariantEqualityComparison(
339 QQmlJSRegisterContent storableContent,
const QString &typedRegisterName,
340 const QString &varRegisterName,
bool invert);
341 void generateArrayInitializer(
int argc,
int argv);
342 void generateWriteBack(
int registerIndex);
343 void rejectIfNonQObjectOut(
const QString &error);
344 void rejectIfBadArray();
346 struct GeneratePragmaWarningBlock {
347 Q_DISABLE_COPY_MOVE(GeneratePragmaWarningBlock)
348 GeneratePragmaWarningBlock(QQmlJSCodeGenerator *generator);
349 ~GeneratePragmaWarningBlock();
351 void silenceDivideByZero();
353 QQmlJSCodeGenerator *m_generator;
357 QString eqIntExpression(
int lhsConst);
360 int argc,
int argv,
const QString &callMethodTemplate,
361 const QString &initMethodTemplate, QString *outVar);
363 QString castTargetName(
const QQmlJSScope::ConstPtr &type)
const;
365 bool inlineStringMethod(
const QString &name,
int base,
int argc,
int argv);
366 bool inlineTranslateMethod(
const QString &name,
int argc,
int argv);
367 bool inlineMathMethod(
const QString &name,
int argc,
int argv);
368 bool inlineConsoleMethod(
const QString &name,
int argc,
int argv);
369 bool inlineArrayMethod(
const QString &name,
int base,
int argc,
int argv);
371 void generate_GetLookupHelper(
int index);
373 QString resolveValueTypeContentPointer(
374 const QQmlJSScope::ConstPtr &required, QQmlJSRegisterContent actual,
375 const QString &variable,
const QString &errorMessage);
376 QString resolveQObjectPointer(
377 const QQmlJSScope::ConstPtr &required, QQmlJSRegisterContent actual,
378 const QString &variable,
const QString &errorMessage);
379 bool generateContentPointerCheck(
380 const QQmlJSScope::ConstPtr &required, QQmlJSRegisterContent actual,
381 const QString &variable,
const QString &errorMessage);
383 QString generateCallConstructor(
384 const QQmlJSMetaMethod &ctor,
const QList<QQmlJSRegisterContent> &argumentTypes,
385 const QStringList &arguments,
const QString &metaType,
const QString &metaObject);
387 QString generateVariantMapGetLookup(
const QString &map,
const int nameIndex);
388 QString generateVariantMapSetLookup(
389 const QString &map,
const int nameIndex,
const QQmlJSScope::ConstPtr &property,
390 const QString &variableIn);
392 QQmlJSRegisterContent originalType(QQmlJSRegisterContent tracked)
394 const QQmlJSRegisterContent restored = m_typeResolver->original(tracked);
395 return m_pool->storedIn(
396 restored, m_typeResolver->original(tracked.storage()).containedType());
399 QQmlJSMetaProperty originalProperty(
const QQmlJSRegisterContent ®)
const
401 auto r = m_typeResolver->original(reg);
402 r = m_typeResolver->shadowed(r);
406 QQmlJSMetaMethod originalMethod(
const QQmlJSRegisterContent ®)
const
408 auto r = m_typeResolver->original(reg);
409 r = m_typeResolver->shadowed(r);
410 return r.methodCall();
413 QQmlJSRegisterContent literalType(
const QQmlJSScope::ConstPtr &contained)
415 return m_pool->storedIn(m_typeResolver->literalType(contained), contained);
418 bool isRegisterAffectedBySideEffects(
int registerIndex);
421 QHash<
int, QString> m_labels;
423 const QV4::Compiler::Context *m_context =
nullptr;
425 bool m_skipUntilNextLabel =
false;
427 QStringList m_includes;
429 struct RegisterVariablesValue
431 QString variableName;
432 QQmlJSScope::ConstPtr storedType;
433 int initialRegisterIndex = InvalidRegister;
437 QHash<QQmlJSRegisterContent, RegisterVariablesValue> m_registerVariables;
439 QQmlJSLookupSignaturesRecorder m_lookupSignaturesRecorder;
440 bool m_noAotValidation =
false;