5#ifndef QV4INSTR_MOTH_P_H
6#define QV4INSTR_MOTH_P_H
19#include <private/qv4staticvalue_p.h>
20#include <private/qv4compileddata_p.h>
25#define INSTRUCTION(op, name, nargs, ...)
26 op##_INSTRUCTION(name, nargs, __VA_ARGS__)
32#define INSTR_LoadConst(op) INSTRUCTION(op, LoadConst, 1
, index)
37#define INSTR_LoadUndefined(op) INSTRUCTION(op, LoadUndefined, 0
)
39#define INSTR_MoveConst(op) INSTRUCTION(op, MoveConst, 2
, constIndex, destTemp)
42#define INSTR_MoveReg(op) INSTRUCTION(op, MoveReg, 2
, srcReg, destReg)
43#define INSTR_LoadImport(op) INSTRUCTION(op, LoadImport, 1
, index)
44#define INSTR_LoadLocal(op) INSTRUCTION(op, LoadLocal, 1
, index)
45#define INSTR_StoreLocal(op) INSTRUCTION(op, StoreLocal, 1
, index)
46#define INSTR_LoadScopedLocal(op) INSTRUCTION(op, LoadScopedLocal, 2
, scope, index)
47#define INSTR_StoreScopedLocal(op) INSTRUCTION(op, StoreScopedLocal, 2
, scope, index)
48#define INSTR_LoadRuntimeString(op) INSTRUCTION(op, LoadRuntimeString, 1
, stringId)
49#define INSTR_MoveRegExp(op) INSTRUCTION(op, MoveRegExp, 2
, regExpId, destReg)
50#define INSTR_LoadClosure(op) INSTRUCTION(op, LoadClosure, 1
, value)
52#define INSTR_LoadGlobalLookup(op) INSTRUCTION(op, LoadGlobalLookup, 1
, index)
53#define INSTR_LoadQmlContextPropertyLookup(op) INSTRUCTION(op, LoadQmlContextPropertyLookup, 1
, index)
54#define INSTR_StoreNameSloppy(op) INSTRUCTION(op, StoreNameSloppy, 1
, name)
55#define INSTR_StoreNameStrict(op) INSTRUCTION(op, StoreNameStrict, 1
, name)
56#define INSTR_LoadProperty(op) INSTRUCTION(op, LoadProperty, 1
, name)
57#define INSTR_LoadOptionalProperty(op) INSTRUCTION(op, LoadOptionalProperty, 2
, name, offset)
58#define INSTR_GetLookup(op) INSTRUCTION(op, GetLookup, 1
, index)
59#define INSTR_GetOptionalLookup(op) INSTRUCTION(op, GetOptionalLookup, 2
, index, offset)
63#define INSTR_IteratorNextForYieldStar(op) INSTRUCTION(op, IteratorNextForYieldStar, 3
, iterator, object, offset)
64#define INSTR_StoreProperty(op) INSTRUCTION(op, StoreProperty, 2
, name, base)
65#define INSTR_SetLookup(op) INSTRUCTION(op, SetLookup, 2
, index, base)
66#define INSTR_LoadSuperProperty(op) INSTRUCTION(op, LoadSuperProperty, 1
, property)
67#define INSTR_StoreSuperProperty(op) INSTRUCTION(op, StoreSuperProperty, 1
, property)
68#define INSTR_LoadElement(op) INSTRUCTION(op, LoadElement, 1
, base)
69#define INSTR_StoreElement(op) INSTRUCTION(op, StoreElement, 2
, base, index)
70#define INSTR_CallValue(op) INSTRUCTION(op, CallValue, 3
, name, argc, argv)
71#define INSTR_CallWithReceiver(op) INSTRUCTION(op, CallWithReceiver, 4
, name, thisObject, argc, argv)
72#define INSTR_CallProperty(op) INSTRUCTION(op, CallProperty, 4
, name, base, argc, argv)
73#define INSTR_CallPropertyLookup(op) INSTRUCTION(op, CallPropertyLookup, 4
, lookupIndex, base, argc, argv)
74#define INSTR_CallName(op) INSTRUCTION(op, CallName, 3
, name, argc, argv)
75#define INSTR_CallPossiblyDirectEval(op) INSTRUCTION(op, CallPossiblyDirectEval, 2
, argc, argv)
76#define INSTR_CallGlobalLookup(op) INSTRUCTION(op, CallGlobalLookup, 3
, index, argc, argv)
77#define INSTR_CallQmlContextPropertyLookup(op) INSTRUCTION(op, CallQmlContextPropertyLookup, 3
, index, argc, argv)
78#define INSTR_CallWithSpread(op) INSTRUCTION(op, CallWithSpread, 4
, func, thisObject, argc, argv)
79#define INSTR_Construct(op) INSTRUCTION(op, Construct, 3
, func, argc, argv)
80#define INSTR_ConstructWithSpread(op) INSTRUCTION(op, ConstructWithSpread, 3
, func, argc, argv)
81#define INSTR_SetUnwindHandler(op) INSTRUCTION(op, SetUnwindHandler, 1
, offset)
82#define INSTR_UnwindDispatch(op) INSTRUCTION(op, UnwindDispatch, 0
)
83#define INSTR_UnwindToLabel(op) INSTRUCTION(op, UnwindToLabel, 2
, level, offset)
84#define INSTR_DeadTemporalZoneCheck(op) INSTRUCTION(op, DeadTemporalZoneCheck, 1
, name)
85#define INSTR_ThrowException(op) INSTRUCTION(op, ThrowException, 0
)
86#define INSTR_GetException(op) INSTRUCTION(op, GetException, 0
)
87#define INSTR_SetException(op) INSTRUCTION(op, SetException, 0
)
88#define INSTR_CreateCallContext(op) INSTRUCTION(op, CreateCallContext, 0
)
89#define INSTR_PushCatchContext(op) INSTRUCTION(op, PushCatchContext, 2
, index, name)
90#define INSTR_PushWithContext(op) INSTRUCTION(op, PushWithContext, 0
)
91#define INSTR_PushBlockContext(op) INSTRUCTION(op, PushBlockContext, 1
, index)
92#define INSTR_CloneBlockContext(op) INSTRUCTION(op, CloneBlockContext, 0
)
93#define INSTR_PushScriptContext(op) INSTRUCTION(op, PushScriptContext, 1
, index)
94#define INSTR_PopScriptContext(op) INSTRUCTION(op, PopScriptContext, 0
)
96#define INSTR_GetIterator(op) INSTRUCTION(op, GetIterator, 1
, iterator)
97#define INSTR_IteratorNext(op) INSTRUCTION(op, IteratorNext, 2
, value, offset)
98#define INSTR_IteratorClose(op) INSTRUCTION(op, IteratorClose, 0
)
99#define INSTR_DestructureRestElement(op) INSTRUCTION(op, DestructureRestElement, 0
)
100#define INSTR_DeleteProperty(op) INSTRUCTION(op, DeleteProperty, 2
, base, index)
104#define INSTR_DeclareVar(op) INSTRUCTION(op, DeclareVar, 2
, varName, isDeletable)
105#define INSTR_DefineArray(op) INSTRUCTION(op, DefineArray, 2
, argc, args)
106#define INSTR_DefineObjectLiteral(op) INSTRUCTION(op, DefineObjectLiteral, 3
, internalClassId, argc, args)
107#define INSTR_CreateClass(op) INSTRUCTION(op, CreateClass, 3
, classIndex, heritage, computedNames)
108#define INSTR_CreateMappedArgumentsObject(op) INSTRUCTION(op, CreateMappedArgumentsObject, 0
)
109#define INSTR_CreateUnmappedArgumentsObject(op) INSTRUCTION(op, CreateUnmappedArgumentsObject, 0
)
110#define INSTR_CreateRestParameter(op) INSTRUCTION(op, CreateRestParameter, 1
, argIndex)
111#define INSTR_ConvertThisToObject(op) INSTRUCTION(op, ConvertThisToObject, 0
)
112#define INSTR_LoadSuperConstructor(op) INSTRUCTION(op, LoadSuperConstructor, 0
)
117#define INSTR_JumpNotUndefined(op) INSTRUCTION(op, JumpNotUndefined, 1
, offset)
118#define INSTR_JumpNoException(op) INSTRUCTION(op, JumpNoException, 1
, offset)
119#define INSTR_CheckException(op) INSTRUCTION(op, CheckException, 0
)
130#define INSTR_CmpStrictEqual(op) INSTRUCTION(op, CmpStrictEqual, 1
, lhs)
131#define INSTR_CmpStrictNotEqual(op) INSTRUCTION(op, CmpStrictNotEqual, 1
, lhs)
133#define INSTR_CmpInstanceOf(op) INSTRUCTION(op, CmpInstanceOf, 1
, lhs)
159#define INSTR_InitializeBlockDeadTemporalZone(op) INSTRUCTION(op, InitializeBlockDeadTemporalZone, 2
, firstReg, count)
160#define INSTR_ThrowOnNullOrUndefined(op) INSTRUCTION(op, ThrowOnNullOrUndefined, 0
)
161#define INSTR_GetTemplateObject(op) INSTRUCTION(op, GetTemplateObject, 1
, index)
162#define INSTR_TailCall(op) INSTRUCTION(op, TailCall, 4
, func, thisObject, argc, argv)
164#define FOR_EACH_MOTH_INSTR_ALL(F)
168#define FOR_EACH_MOTH_INSTR(F)
191 F(LoadQmlContextPropertyLookup)
197 F(LoadOptionalProperty)
203 F(StoreSuperProperty)
204 F(ConvertThisToObject)
254 F(CallPropertyLookup)
256 F(CallPossiblyDirectEval)
258 F(CallQmlContextPropertyLookup)
261 F(ConstructWithSpread)
265 F(DeadTemporalZoneCheck)
278 F(DestructureRestElement)
285 F(DefineObjectLiteral)
286 F(CreateMappedArgumentsObject)
287 F(CreateUnmappedArgumentsObject)
288 F(CreateRestParameter)
292 F(IteratorNextForYieldStar)
294 F(LoadSuperConstructor)
297 F(InitializeBlockDeadTemporalZone)
298 F(ThrowOnNullOrUndefined)
303#define MOTH_NUM_INSTRUCTIONS() (static_cast<int>(Moth::Instr::Type::Debug_Wide) + 1
)
306#if defined(Q_OS_WASM) && !defined(__asmjs)
310# define MOTH_COMPUTED_GOTO
314#define MOTH_INSTR_ALIGN_MASK (alignof(QV4::Moth::Instr) - 1
)
316#define MOTH_INSTR_ENUM(I) I, I##_Wide,
317#define MOTH_INSTR_SIZE(I) (sizeof(QV4::Moth::Instr::instr_##I))
319#define MOTH_EXPAND_FOR_MSVC(x) x
320#define MOTH_DEFINE_ARGS(nargs, ...)
323#define MOTH_DEFINE_ARGS0()
324#define MOTH_DEFINE_ARGS1(arg)
326#define MOTH_DEFINE_ARGS2(arg1, arg2)
329#define MOTH_DEFINE_ARGS3(arg1, arg2, arg3)
333#define MOTH_DEFINE_ARGS4(arg1, arg2, arg3, arg4)
338#define MOTH_DEFINE_ARGS5(arg1, arg2, arg3, arg4, arg5)
345#define MOTH_COLLECT_ENUMS(instr)
346 INSTR_##instr(MOTH_GET_ENUM)
347#define MOTH_GET_ENUM_INSTRUCTION(name, ...)
350#define MOTH_EMIT_STRUCTS(instr)
351 INSTR_##instr(MOTH_EMIT_STRUCT)
352#define MOTH_EMIT_STRUCT_INSTRUCTION(name, nargs, ...)
353 struct instr_##name {
357#define MOTH_EMIT_INSTR_MEMBERS(instr)
358 INSTR_##instr(MOTH_EMIT_INSTR_MEMBER)
359#define MOTH_EMIT_INSTR_MEMBER_INSTRUCTION(name, nargs, ...)
362#define MOTH_COLLECT_NARGS(instr)
363 INSTR_##instr(MOTH_COLLECT_ARG_COUNT)
364#define MOTH_COLLECT_ARG_COUNT_INSTRUCTION(name, nargs, ...)
367#define MOTH_DECODE_ARG(arg, type, nargs, offset)
368 arg = qFromLittleEndian<type>(qFromUnaligned<type>(reinterpret_cast<const type *>(code) - nargs + offset));
369#define MOTH_ADJUST_CODE(type, nargs)
370 code += static_cast<quintptr>(nargs*sizeof(type) + 1
)
372#define MOTH_DECODE_INSTRUCTION(name, nargs, ...)
384#define MOTH_DECODE_WITH_BASE_INSTRUCTION(name, nargs, ...)
386 const char *base_ptr;
399#define MOTH_DECODE_ARGS(name, type, nargs, ...)
402#define MOTH_DECODE_ARGS0(name, type, nargs, dummy)
403#define MOTH_DECODE_ARGS1(name, type, nargs, arg)
405#define MOTH_DECODE_ARGS2(name, type, nargs, arg1, arg2)
408#define MOTH_DECODE_ARGS3(name, type, nargs, arg1, arg2, arg3)
411#define MOTH_DECODE_ARGS4(name, type, nargs, arg1, arg2, arg3, arg4)
414#define MOTH_DECODE_ARGS5(name, type, nargs, arg1, arg2, arg3, arg4, arg5)
418#ifdef MOTH_COMPUTED_GOTO
420#define COLLECT_LABELS(instr)
421 INSTR_##instr(GET_LABEL)
422 INSTR_##instr(GET_LABEL_WIDE)
423#define GET_LABEL_INSTRUCTION(name, ...)
425#define GET_LABEL_WIDE_INSTRUCTION(name, ...)
428#define MOTH_JUMP_TABLE
429 static const void *jumpTable[] = {
430 FOR_EACH_MOTH_INSTR_ALL(COLLECT_LABELS)
433#define MOTH_DISPATCH_SINGLE()
434 goto *jumpTable[*reinterpret_cast<const uchar *>(code)];
436#define MOTH_DISPATCH()
437 MOTH_DISPATCH_SINGLE()
440 MOTH_DISPATCH_SINGLE()
443 goto *jumpTable[0x100
| *reinterpret_cast<const uchar *>(code)];
445#define MOTH_JUMP_TABLE
447#define MOTH_INSTR_CASE_AND_JUMP(instr)
448 INSTR_##instr(GET_CASE_AND_JUMP)
449 INSTR_##instr(GET_CASE_AND_JUMP_WIDE)
450#define GET_CASE_AND_JUMP_INSTRUCTION(name, ...)
451 case Instr::Type::name: goto op_byte_##name;
452#define GET_CASE_AND_JUMP_WIDE_INSTRUCTION(name, ...)
453 case Instr::Type::name##_Wide: goto op_int_##name;
455#define MOTH_DISPATCH()
456 Instr::Type type = Instr::Type(static_cast<uchar>(*code));
459 case Instr::Type::Nop:
461 type = Instr::Type(static_cast<uchar>(*code));
463 case Instr::Type::Nop_Wide:
465 type = Instr::Type(0x100
| static_cast<uchar>(*code));
484 Q_ASSERT(index >= 0);
505 const char *bytecode,
int len,
int nLocals,
int nFormals,
int startLine = 1,
506 const QList<CompiledData::CodeOffsetToLineAndStatement> &lineAndStatementNumberMapping =
509 const QByteArray &bytecode,
int nLocals,
int nFormals,
int startLine = 1,
510 const QList<CompiledData::CodeOffsetToLineAndStatement> &lineAndStatementNumberMapping =
513 return dumpBytecode(bytecode.constData(), bytecode.size(), nLocals, nFormals, startLine,
514 lineAndStatementNumberMapping);
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
601 static Type unpack(
const uchar *c) {
if (c[0] == 0x1)
return Type(0x100 + c[1]);
return Type(c[0]); }
603 if (uint(t) >= 256) {
605 c[1] = uint(t) &0xff;
608 c[0] = uchar(uint(t));
630QT_WARNING_DISABLE_GCC(
"-Wuninitialized")
632#define MOTH_INSTR_META_TEMPLATE(I)
633 template<> struct InstrMeta<int(Instr::Type::I)> {
635 typedef Instr::instr_##I DataType;
636 static const DataType &data(const Instr &instr) { return instr.I; }
637 static void setData(Instr &instr, const DataType &v)
638 { memcpy(reinterpret_cast<char *>(&instr.I),
639 reinterpret_cast<const char *>(&v),
643#undef MOTH_INSTR_META_TEMPLATE
652#define MOTH_INSTR_DATA_TYPEDEF(I) typedef InstrData<int(Instr::Type::I)> I;
654#undef MOTH_INSTR_DATA_TYPEDEF
static StackSlot createRegister(int index)
Combined button and popup list for selecting options.
QString dumpBytecode(const char *code, int len, int nLocals, int nFormals, int, const QList< CompiledData::CodeOffsetToLineAndStatement > &lineAndStatementNumberMapping)
bool operator==(const StackSlot &l, const StackSlot &r)
QString dumpRegister(int reg, int nFormals)
QString dumpBytecode(const char *code, int len, int nLocals, int nFormals, int beginOffset, int endOffset, const QList< CompiledData::CodeOffsetToLineAndStatement > &lineAndStatementNumberMapping)
QString dumpBytecode(const QByteArray &bytecode, int nLocals, int nFormals, int startLine=1, const QList< CompiledData::CodeOffsetToLineAndStatement > &lineAndStatementNumberMapping=QList< CompiledData::CodeOffsetToLineAndStatement >())
bool operator!=(const StackSlot &l, const StackSlot &r)
QString dumpArguments(int argc, int argv, int nFormals)
#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)