4#ifndef QV4INSTR_MOTH_P_H
5#define QV4INSTR_MOTH_P_H
18#include <private/qv4staticvalue_p.h>
19#include <private/qv4compileddata_p.h>
24#define INSTRUCTION(op, name, nargs, ...)
25 op##_INSTRUCTION(name, nargs, __VA_ARGS__)
31#define INSTR_LoadConst(op) INSTRUCTION(op, LoadConst, 1
, index)
36#define INSTR_LoadUndefined(op) INSTRUCTION(op, LoadUndefined, 0
)
38#define INSTR_MoveConst(op) INSTRUCTION(op, MoveConst, 2
, constIndex, destTemp)
41#define INSTR_MoveReg(op) INSTRUCTION(op, MoveReg, 2
, srcReg, destReg)
42#define INSTR_LoadImport(op) INSTRUCTION(op, LoadImport, 1
, index)
43#define INSTR_LoadLocal(op) INSTRUCTION(op, LoadLocal, 1
, index)
44#define INSTR_StoreLocal(op) INSTRUCTION(op, StoreLocal, 1
, index)
45#define INSTR_LoadScopedLocal(op) INSTRUCTION(op, LoadScopedLocal, 2
, scope, index)
46#define INSTR_StoreScopedLocal(op) INSTRUCTION(op, StoreScopedLocal, 2
, scope, index)
47#define INSTR_LoadRuntimeString(op) INSTRUCTION(op, LoadRuntimeString, 1
, stringId)
48#define INSTR_MoveRegExp(op) INSTRUCTION(op, MoveRegExp, 2
, regExpId, destReg)
49#define INSTR_LoadClosure(op) INSTRUCTION(op, LoadClosure, 1
, value)
51#define INSTR_LoadGlobalLookup(op) INSTRUCTION(op, LoadGlobalLookup, 1
, index)
52#define INSTR_LoadQmlContextPropertyLookup(op) INSTRUCTION(op, LoadQmlContextPropertyLookup, 1
, index)
53#define INSTR_StoreNameSloppy(op) INSTRUCTION(op, StoreNameSloppy, 1
, name)
54#define INSTR_StoreNameStrict(op) INSTRUCTION(op, StoreNameStrict, 1
, name)
55#define INSTR_LoadProperty(op) INSTRUCTION(op, LoadProperty, 1
, name)
56#define INSTR_LoadOptionalProperty(op) INSTRUCTION(op, LoadOptionalProperty, 2
, name, offset)
57#define INSTR_GetLookup(op) INSTRUCTION(op, GetLookup, 1
, index)
58#define INSTR_GetOptionalLookup(op) INSTRUCTION(op, GetOptionalLookup, 2
, index, offset)
62#define INSTR_IteratorNextForYieldStar(op) INSTRUCTION(op, IteratorNextForYieldStar, 3
, iterator, object, offset)
63#define INSTR_StoreProperty(op) INSTRUCTION(op, StoreProperty, 2
, name, base)
64#define INSTR_SetLookup(op) INSTRUCTION(op, SetLookup, 2
, index, base)
65#define INSTR_LoadSuperProperty(op) INSTRUCTION(op, LoadSuperProperty, 1
, property)
66#define INSTR_StoreSuperProperty(op) INSTRUCTION(op, StoreSuperProperty, 1
, property)
67#define INSTR_LoadElement(op) INSTRUCTION(op, LoadElement, 1
, base)
68#define INSTR_StoreElement(op) INSTRUCTION(op, StoreElement, 2
, base, index)
69#define INSTR_CallValue(op) INSTRUCTION(op, CallValue, 3
, name, argc, argv)
70#define INSTR_CallWithReceiver(op) INSTRUCTION(op, CallWithReceiver, 4
, name, thisObject, argc, argv)
71#define INSTR_CallProperty(op) INSTRUCTION(op, CallProperty, 4
, name, base, argc, argv)
72#define INSTR_CallPropertyLookup(op) INSTRUCTION(op, CallPropertyLookup, 4
, lookupIndex, base, argc, argv)
73#define INSTR_CallName(op) INSTRUCTION(op, CallName, 3
, name, argc, argv)
74#define INSTR_CallPossiblyDirectEval(op) INSTRUCTION(op, CallPossiblyDirectEval, 2
, argc, argv)
75#define INSTR_CallGlobalLookup(op) INSTRUCTION(op, CallGlobalLookup, 3
, index, argc, argv)
76#define INSTR_CallQmlContextPropertyLookup(op) INSTRUCTION(op, CallQmlContextPropertyLookup, 3
, index, argc, argv)
77#define INSTR_CallWithSpread(op) INSTRUCTION(op, CallWithSpread, 4
, func, thisObject, argc, argv)
78#define INSTR_Construct(op) INSTRUCTION(op, Construct, 3
, func, argc, argv)
79#define INSTR_ConstructWithSpread(op) INSTRUCTION(op, ConstructWithSpread, 3
, func, argc, argv)
80#define INSTR_SetUnwindHandler(op) INSTRUCTION(op, SetUnwindHandler, 1
, offset)
81#define INSTR_UnwindDispatch(op) INSTRUCTION(op, UnwindDispatch, 0
)
82#define INSTR_UnwindToLabel(op) INSTRUCTION(op, UnwindToLabel, 2
, level, offset)
83#define INSTR_DeadTemporalZoneCheck(op) INSTRUCTION(op, DeadTemporalZoneCheck, 1
, name)
84#define INSTR_ThrowException(op) INSTRUCTION(op, ThrowException, 0
)
85#define INSTR_GetException(op) INSTRUCTION(op, GetException, 0
)
86#define INSTR_SetException(op) INSTRUCTION(op, SetException, 0
)
87#define INSTR_CreateCallContext(op) INSTRUCTION(op, CreateCallContext, 0
)
88#define INSTR_PushCatchContext(op) INSTRUCTION(op, PushCatchContext, 2
, index, name)
89#define INSTR_PushWithContext(op) INSTRUCTION(op, PushWithContext, 0
)
90#define INSTR_PushBlockContext(op) INSTRUCTION(op, PushBlockContext, 1
, index)
91#define INSTR_CloneBlockContext(op) INSTRUCTION(op, CloneBlockContext, 0
)
92#define INSTR_PushScriptContext(op) INSTRUCTION(op, PushScriptContext, 1
, index)
93#define INSTR_PopScriptContext(op) INSTRUCTION(op, PopScriptContext, 0
)
95#define INSTR_GetIterator(op) INSTRUCTION(op, GetIterator, 1
, iterator)
96#define INSTR_IteratorNext(op) INSTRUCTION(op, IteratorNext, 2
, value, offset)
97#define INSTR_IteratorClose(op) INSTRUCTION(op, IteratorClose, 0
)
98#define INSTR_DestructureRestElement(op) INSTRUCTION(op, DestructureRestElement, 0
)
99#define INSTR_DeleteProperty(op) INSTRUCTION(op, DeleteProperty, 2
, base, index)
103#define INSTR_DeclareVar(op) INSTRUCTION(op, DeclareVar, 2
, varName, isDeletable)
104#define INSTR_DefineArray(op) INSTRUCTION(op, DefineArray, 2
, argc, args)
105#define INSTR_DefineObjectLiteral(op) INSTRUCTION(op, DefineObjectLiteral, 3
, internalClassId, argc, args)
106#define INSTR_CreateClass(op) INSTRUCTION(op, CreateClass, 3
, classIndex, heritage, computedNames)
107#define INSTR_CreateMappedArgumentsObject(op) INSTRUCTION(op, CreateMappedArgumentsObject, 0
)
108#define INSTR_CreateUnmappedArgumentsObject(op) INSTRUCTION(op, CreateUnmappedArgumentsObject, 0
)
109#define INSTR_CreateRestParameter(op) INSTRUCTION(op, CreateRestParameter, 1
, argIndex)
110#define INSTR_ConvertThisToObject(op) INSTRUCTION(op, ConvertThisToObject, 0
)
111#define INSTR_LoadSuperConstructor(op) INSTRUCTION(op, LoadSuperConstructor, 0
)
116#define INSTR_JumpNotUndefined(op) INSTRUCTION(op, JumpNotUndefined, 1
, offset)
117#define INSTR_JumpNoException(op) INSTRUCTION(op, JumpNoException, 1
, offset)
118#define INSTR_CheckException(op) INSTRUCTION(op, CheckException, 0
)
129#define INSTR_CmpStrictEqual(op) INSTRUCTION(op, CmpStrictEqual, 1
, lhs)
130#define INSTR_CmpStrictNotEqual(op) INSTRUCTION(op, CmpStrictNotEqual, 1
, lhs)
132#define INSTR_CmpInstanceOf(op) INSTRUCTION(op, CmpInstanceOf, 1
, lhs)
158#define INSTR_InitializeBlockDeadTemporalZone(op) INSTRUCTION(op, InitializeBlockDeadTemporalZone, 2
, firstReg, count)
159#define INSTR_ThrowOnNullOrUndefined(op) INSTRUCTION(op, ThrowOnNullOrUndefined, 0
)
160#define INSTR_GetTemplateObject(op) INSTRUCTION(op, GetTemplateObject, 1
, index)
161#define INSTR_TailCall(op) INSTRUCTION(op, TailCall, 4
, func, thisObject, argc, argv)
163#define FOR_EACH_MOTH_INSTR_ALL(F)
167#define FOR_EACH_MOTH_INSTR(F)
190 F(LoadQmlContextPropertyLookup)
196 F(LoadOptionalProperty)
202 F(StoreSuperProperty)
203 F(ConvertThisToObject)
253 F(CallPropertyLookup)
255 F(CallPossiblyDirectEval)
257 F(CallQmlContextPropertyLookup)
260 F(ConstructWithSpread)
264 F(DeadTemporalZoneCheck)
277 F(DestructureRestElement)
284 F(DefineObjectLiteral)
285 F(CreateMappedArgumentsObject)
286 F(CreateUnmappedArgumentsObject)
287 F(CreateRestParameter)
291 F(IteratorNextForYieldStar)
293 F(LoadSuperConstructor)
296 F(InitializeBlockDeadTemporalZone)
297 F(ThrowOnNullOrUndefined)
302#define MOTH_NUM_INSTRUCTIONS() (static_cast<int>(Moth::Instr::Type::Debug_Wide) + 1
)
305#if defined(Q_OS_WASM) && !defined(__asmjs)
309# define MOTH_COMPUTED_GOTO
313#define MOTH_INSTR_ALIGN_MASK (alignof(QV4::Moth::Instr) - 1
)
315#define MOTH_INSTR_ENUM(I) I, I##_Wide,
316#define MOTH_INSTR_SIZE(I) (sizeof(QV4::Moth::Instr::instr_##I))
318#define MOTH_EXPAND_FOR_MSVC(x) x
319#define MOTH_DEFINE_ARGS(nargs, ...)
322#define MOTH_DEFINE_ARGS0()
323#define MOTH_DEFINE_ARGS1(arg)
325#define MOTH_DEFINE_ARGS2(arg1, arg2)
328#define MOTH_DEFINE_ARGS3(arg1, arg2, arg3)
332#define MOTH_DEFINE_ARGS4(arg1, arg2, arg3, arg4)
337#define MOTH_DEFINE_ARGS5(arg1, arg2, arg3, arg4, arg5)
344#define MOTH_COLLECT_ENUMS(instr)
345 INSTR_##instr(MOTH_GET_ENUM)
346#define MOTH_GET_ENUM_INSTRUCTION(name, ...)
349#define MOTH_EMIT_STRUCTS(instr)
350 INSTR_##instr(MOTH_EMIT_STRUCT)
351#define MOTH_EMIT_STRUCT_INSTRUCTION(name, nargs, ...)
352 struct instr_##name {
356#define MOTH_EMIT_INSTR_MEMBERS(instr)
357 INSTR_##instr(MOTH_EMIT_INSTR_MEMBER)
358#define MOTH_EMIT_INSTR_MEMBER_INSTRUCTION(name, nargs, ...)
361#define MOTH_COLLECT_NARGS(instr)
362 INSTR_##instr(MOTH_COLLECT_ARG_COUNT)
363#define MOTH_COLLECT_ARG_COUNT_INSTRUCTION(name, nargs, ...)
366#define MOTH_DECODE_ARG(arg, type, nargs, offset)
367 arg = qFromLittleEndian<type>(qFromUnaligned<type>(reinterpret_cast<const type *>(code) - nargs + offset));
368#define MOTH_ADJUST_CODE(type, nargs)
369 code += static_cast<quintptr>(nargs*sizeof(type) + 1
)
371#define MOTH_DECODE_INSTRUCTION(name, nargs, ...)
383#define MOTH_DECODE_WITH_BASE_INSTRUCTION(name, nargs, ...)
385 const char *base_ptr;
398#define MOTH_DECODE_ARGS(name, type, nargs, ...)
401#define MOTH_DECODE_ARGS0(name, type, nargs, dummy)
402#define MOTH_DECODE_ARGS1(name, type, nargs, arg)
404#define MOTH_DECODE_ARGS2(name, type, nargs, arg1, arg2)
407#define MOTH_DECODE_ARGS3(name, type, nargs, arg1, arg2, arg3)
410#define MOTH_DECODE_ARGS4(name, type, nargs, arg1, arg2, arg3, arg4)
413#define MOTH_DECODE_ARGS5(name, type, nargs, arg1, arg2, arg3, arg4, arg5)
417#ifdef MOTH_COMPUTED_GOTO
419#define COLLECT_LABELS(instr)
420 INSTR_##instr(GET_LABEL)
421 INSTR_##instr(GET_LABEL_WIDE)
422#define GET_LABEL_INSTRUCTION(name, ...)
424#define GET_LABEL_WIDE_INSTRUCTION(name, ...)
427#define MOTH_JUMP_TABLE
428 static const void *jumpTable[] = {
429 FOR_EACH_MOTH_INSTR_ALL(COLLECT_LABELS)
432#define MOTH_DISPATCH_SINGLE()
433 goto *jumpTable[*reinterpret_cast<const uchar *>(code)];
435#define MOTH_DISPATCH()
436 MOTH_DISPATCH_SINGLE()
439 MOTH_DISPATCH_SINGLE()
442 goto *jumpTable[0x100
| *reinterpret_cast<const uchar *>(code)];
444#define MOTH_JUMP_TABLE
446#define MOTH_INSTR_CASE_AND_JUMP(instr)
447 INSTR_##instr(GET_CASE_AND_JUMP)
448 INSTR_##instr(GET_CASE_AND_JUMP_WIDE)
449#define GET_CASE_AND_JUMP_INSTRUCTION(name, ...)
450 case Instr::Type::name: goto op_byte_##name;
451#define GET_CASE_AND_JUMP_WIDE_INSTRUCTION(name, ...)
452 case Instr::Type::name##_Wide: goto op_int_##name;
454#define MOTH_DISPATCH()
455 Instr::Type type = Instr::Type(static_cast<uchar>(*code));
458 case Instr::Type::Nop:
460 type = Instr::Type(static_cast<uchar>(*code));
462 case Instr::Type::Nop_Wide:
464 type = Instr::Type(0x100
| static_cast<uchar>(*code));
483 Q_ASSERT(index >= 0);
504 const char *bytecode,
int len,
int nLocals,
int nFormals,
int startLine = 1,
505 const QVector<CompiledData::CodeOffsetToLineAndStatement> &lineAndStatementNumberMapping =
508 const QByteArray &bytecode,
int nLocals,
int nFormals,
int startLine = 1,
509 const QVector<CompiledData::CodeOffsetToLineAndStatement> &lineAndStatementNumberMapping =
512 return dumpBytecode(bytecode.constData(), bytecode.size(), nLocals, nFormals, startLine,
513 lineAndStatementNumberMapping);
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600 static Type unpack(
const uchar *c) {
if (c[0] == 0x1)
return Type(0x100 + c[1]);
return Type(c[0]); }
602 if (uint(t) >= 256) {
604 c[1] = uint(t) &0xff;
607 c[0] = uchar(uint(t));
629QT_WARNING_DISABLE_GCC(
"-Wuninitialized")
631#define MOTH_INSTR_META_TEMPLATE(I)
632 template<> struct InstrMeta<int(Instr::Type::I)> {
634 typedef Instr::instr_##I DataType;
635 static const DataType &data(const Instr &instr) { return instr.I; }
636 static void setData(Instr &instr, const DataType &v)
637 { memcpy(reinterpret_cast<char *>(&instr.I),
638 reinterpret_cast<const char *>(&v),
642#undef MOTH_INSTR_META_TEMPLATE
651#define MOTH_INSTR_DATA_TYPEDEF(I) typedef InstrData<int(Instr::Type::I)> I;
653#undef MOTH_INSTR_DATA_TYPEDEF
static StackSlot createRegister(int index)
Combined button and popup list for selecting options.
bool operator==(const StackSlot &l, const StackSlot &r)
QString dumpBytecode(const char *code, int len, int nLocals, int nFormals, int, const QVector< CompiledData::CodeOffsetToLineAndStatement > &lineAndStatementNumberMapping)
QString dumpRegister(int reg, int nFormals)
bool operator!=(const StackSlot &l, const StackSlot &r)
QString dumpArguments(int argc, int argv, int nFormals)
QString dumpBytecode(const char *code, int len, int nLocals, int nFormals, int beginOffset, int endOffset, const QVector< CompiledData::CodeOffsetToLineAndStatement > &lineAndStatementNumberMapping)
QString dumpBytecode(const QByteArray &bytecode, int nLocals, int nFormals, int startLine=1, const QVector< CompiledData::CodeOffsetToLineAndStatement > &lineAndStatementNumberMapping=QVector< CompiledData::CodeOffsetToLineAndStatement >())
#define ABSOLUTE_OFFSET()
static QByteArray rawBytes(const char *data, int n)
static QByteArray alignedLineNumber(int line)
#define MOTH_BEGIN_INSTR(instr)
#define MOTH_END_INSTR(instr)
static QByteArray alignedNumber(int n)
#define MOTH_ADJUST_CODE(type, nargs)
#define INSTRUCTION(op, name, nargs,...)
#define MOTH_DECODE_ARG(arg, type, nargs, offset)
#define MOTH_INSTR_SIZE(I)
#define MOTH_DECODE_ARGS3(name, type, nargs, arg1, arg2, arg3)
#define MOTH_DECODE_ARGS1(name, type, nargs, arg)
#define MOTH_DECODE_ARGS2(name, type, nargs, arg1, arg2)
#define FOR_EACH_MOTH_INSTR_ALL(F)
#define MOTH_DECODE_ARGS4(name, type, nargs, arg1, arg2, arg3, arg4)
#define MOTH_DECODE_ARGS(name, type, nargs,...)
#define FOR_EACH_MOTH_INSTR(F)
#define MOTH_DEFINE_ARGS(nargs,...)
#define MOTH_INSTR_CASE_AND_JUMP(instr)
#define MOTH_EXPAND_FOR_MSVC(x)
static const int argumentCount[]
static int size(Instr::Type type)
static int encodedLength(Type t)
static Type wideInstructionType(Type t)
static Type unpack(const uchar *c)
static bool isNarrow(Type t)
static uchar * pack(uchar *c, Type t)
static bool isWide(Type t)
static Type narrowInstructionType(Type t)