diff options
Diffstat (limited to 'src/qml/compiler/qv4instr_moth_p.h')
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 226 |
1 files changed, 146 insertions, 80 deletions
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index df9182e924..ce92a31590 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -53,6 +53,8 @@ #include <private/qv4global_p.h> #include <private/qv4value_p.h> #include <private/qv4runtime_p.h> +#include <private/qv4compileddata_p.h> // for CompiledData::CodeOffsetToLine used by the dumper +#include <qendian.h> QT_BEGIN_NAMESPACE @@ -60,6 +62,7 @@ QT_BEGIN_NAMESPACE op##_INSTRUCTION(name, nargs, __VA_ARGS__) /* for all jump instructions, the offset has to come last, to simplify the job of the bytecode generator */ +#define INSTR_Nop(op) INSTRUCTION(op, Nop, 0) #define INSTR_Ret(op) INSTRUCTION(op, Ret, 0) #define INSTR_Debug(op) INSTRUCTION(op, Debug, 0) #define INSTR_LoadConst(op) INSTRUCTION(op, LoadConst, 1, index) @@ -84,19 +87,20 @@ QT_BEGIN_NAMESPACE #define INSTR_LoadGlobalLookup(op) INSTRUCTION(op, LoadGlobalLookup, 1, index) #define INSTR_StoreNameSloppy(op) INSTRUCTION(op, StoreNameSloppy, 1, name) #define INSTR_StoreNameStrict(op) INSTRUCTION(op, StoreNameStrict, 1, name) -#define INSTR_LoadProperty(op) INSTRUCTION(op, LoadProperty, 2, name, base) -#define INSTR_LoadPropertyA(op) INSTRUCTION(op, LoadPropertyA, 1, name) -#define INSTR_GetLookup(op) INSTRUCTION(op, GetLookup, 2, index, base) -#define INSTR_GetLookupA(op) INSTRUCTION(op, GetLookupA, 1, index) +#define INSTR_LoadProperty(op) INSTRUCTION(op, LoadProperty, 1, name) +#define INSTR_GetLookup(op) INSTRUCTION(op, GetLookup, 1, index) #define INSTR_LoadScopeObjectProperty(op) INSTRUCTION(op, LoadScopeObjectProperty, 3, propertyIndex, base, captureRequired) #define INSTR_LoadContextObjectProperty(op) INSTRUCTION(op, LoadContextObjectProperty, 3, propertyIndex, base, captureRequired) #define INSTR_LoadIdObject(op) INSTRUCTION(op, LoadIdObject, 2, index, base) +#define INSTR_Yield(op) INSTRUCTION(op, Yield, 0) +#define INSTR_Resume(op) INSTRUCTION(op, Resume, 1, offset) #define INSTR_StoreProperty(op) INSTRUCTION(op, StoreProperty, 2, name, base) #define INSTR_SetLookup(op) INSTRUCTION(op, SetLookup, 2, index, base) +#define INSTR_LoadSuperProperty(op) INSTRUCTION(op, LoadSuperProperty, 1, property) +#define INSTR_StoreSuperProperty(op) INSTRUCTION(op, StoreSuperProperty, 1, property) #define INSTR_StoreScopeObjectProperty(op) INSTRUCTION(op, StoreScopeObjectProperty, 2, base, propertyIndex) #define INSTR_StoreContextObjectProperty(op) INSTRUCTION(op, StoreContextObjectProperty, 2, base, propertyIndex) -#define INSTR_LoadElement(op) INSTRUCTION(op, LoadElement, 2, base, index) -#define INSTR_LoadElementA(op) INSTRUCTION(op, LoadElementA, 1, base) +#define INSTR_LoadElement(op) INSTRUCTION(op, LoadElement, 1, base) #define INSTR_StoreElement(op) INSTRUCTION(op, StoreElement, 2, base, index) #define INSTR_CallValue(op) INSTRUCTION(op, CallValue, 3, name, argc, argv) #define INSTR_CallProperty(op) INSTRUCTION(op, CallProperty, 4, name, base, argc, argv) @@ -107,32 +111,46 @@ QT_BEGIN_NAMESPACE #define INSTR_CallGlobalLookup(op) INSTRUCTION(op, CallGlobalLookup, 3, index, argc, argv) #define INSTR_CallScopeObjectProperty(op) INSTRUCTION(op, CallScopeObjectProperty, 4, name, base, argc, argv) #define INSTR_CallContextObjectProperty(op) INSTRUCTION(op, CallContextObjectProperty, 4, name, base, argc, argv) -#define INSTR_SetExceptionHandler(op) INSTRUCTION(op, SetExceptionHandler, 1, offset) +#define INSTR_CallWithSpread(op) INSTRUCTION(op, CallWithSpread, 4, func, thisObject, argc, argv) +#define INSTR_Construct(op) INSTRUCTION(op, Construct, 3, func, argc, argv) +#define INSTR_ConstructWithSpread(op) INSTRUCTION(op, ConstructWithSpread, 3, func, argc, argv) +#define INSTR_SetUnwindHandler(op) INSTRUCTION(op, SetUnwindHandler, 1, offset) +#define INSTR_UnwindDispatch(op) INSTRUCTION(op, UnwindDispatch, 0) +#define INSTR_UnwindToLabel(op) INSTRUCTION(op, UnwindToLabel, 2, level, offset) #define INSTR_ThrowException(op) INSTRUCTION(op, ThrowException, 0) #define INSTR_GetException(op) INSTRUCTION(op, GetException, 0) #define INSTR_SetException(op) INSTRUCTION(op, SetException, 0) #define INSTR_CreateCallContext(op) INSTRUCTION(op, CreateCallContext, 0) -#define INSTR_PushCatchContext(op) INSTRUCTION(op, PushCatchContext, 2, name, reg) -#define INSTR_PushWithContext(op) INSTRUCTION(op, PushWithContext, 1, reg) -#define INSTR_PopContext(op) INSTRUCTION(op, PopContext, 1, reg) -#define INSTR_ForeachIteratorObject(op) INSTRUCTION(op, ForeachIteratorObject, 0) -#define INSTR_ForeachNextPropertyName(op) INSTRUCTION(op, ForeachNextPropertyName, 0) -#define INSTR_DeleteMember(op) INSTRUCTION(op, DeleteMember, 2, member, base) -#define INSTR_DeleteSubscript(op) INSTRUCTION(op, DeleteSubscript, 2, base, index) +#define INSTR_PushCatchContext(op) INSTRUCTION(op, PushCatchContext, 2, index, name) +#define INSTR_PushWithContext(op) INSTRUCTION(op, PushWithContext, 0) +#define INSTR_PushBlockContext(op) INSTRUCTION(op, PushBlockContext, 1, index) +#define INSTR_CloneBlockContext(op) INSTRUCTION(op, CloneBlockContext, 0) +#define INSTR_PushScriptContext(op) INSTRUCTION(op, PushScriptContext, 1, index) +#define INSTR_PopScriptContext(op) INSTRUCTION(op, PopScriptContext, 0) +#define INSTR_PopContext(op) INSTRUCTION(op, PopContext, 0) +#define INSTR_GetIterator(op) INSTRUCTION(op, GetIterator, 1, iterator) +#define INSTR_IteratorNext(op) INSTRUCTION(op, IteratorNext, 1, value) +#define INSTR_IteratorClose(op) INSTRUCTION(op, IteratorClose, 1, done) +#define INSTR_DestructureRestElement(op) INSTRUCTION(op, DestructureRestElement, 0) +#define INSTR_DeleteProperty(op) INSTRUCTION(op, DeleteProperty, 2, base, index) #define INSTR_DeleteName(op) INSTRUCTION(op, DeleteName, 1, name) #define INSTR_TypeofName(op) INSTRUCTION(op, TypeofName, 1, name) #define INSTR_TypeofValue(op) INSTRUCTION(op, TypeofValue, 0) #define INSTR_DeclareVar(op) INSTRUCTION(op, DeclareVar, 2, varName, isDeletable) #define INSTR_DefineArray(op) INSTRUCTION(op, DefineArray, 2, argc, args) -// arrayGetterSetterCountAndFlags contains 30 bits for count, 1 bit for needsSparseArray boolean -#define INSTR_DefineObjectLiteral(op) INSTRUCTION(op, DefineObjectLiteral, 4, internalClassId, arrayValueCount, arrayGetterSetterCountAndFlags, args) +#define INSTR_DefineObjectLiteral(op) INSTRUCTION(op, DefineObjectLiteral, 3, internalClassId, argc, args) +#define INSTR_CreateClass(op) INSTRUCTION(op, CreateClass, 3, classIndex, heritage, computedNames) #define INSTR_CreateMappedArgumentsObject(op) INSTRUCTION(op, CreateMappedArgumentsObject, 0) #define INSTR_CreateUnmappedArgumentsObject(op) INSTRUCTION(op, CreateUnmappedArgumentsObject, 0) +#define INSTR_CreateRestParameter(op) INSTRUCTION(op, CreateRestParameter, 1, argIndex) #define INSTR_ConvertThisToObject(op) INSTRUCTION(op, ConvertThisToObject, 0) -#define INSTR_Construct(op) INSTRUCTION(op, Construct, 3, func, argc, argv) +#define INSTR_LoadSuperConstructor(op) INSTRUCTION(op, LoadSuperConstructor, 0) +#define INSTR_ToObject(op) INSTRUCTION(op, ToObject, 0) #define INSTR_Jump(op) INSTRUCTION(op, Jump, 1, offset) #define INSTR_JumpTrue(op) INSTRUCTION(op, JumpTrue, 1, offset) #define INSTR_JumpFalse(op) INSTRUCTION(op, JumpFalse, 1, offset) +#define INSTR_JumpNotUndefined(op) INSTRUCTION(op, JumpNotUndefined, 1, offset) +#define INSTR_JumpNoException(op) INSTRUCTION(op, JumpNoException, 1, offset) #define INSTR_CmpEqNull(op) INSTRUCTION(op, CmpEqNull, 0) #define INSTR_CmpNeNull(op) INSTRUCTION(op, CmpNeNull, 0) #define INSTR_CmpEqInt(op) INSTRUCTION(op, CmpEqInt, 1, lhs) @@ -147,8 +165,6 @@ QT_BEGIN_NAMESPACE #define INSTR_CmpStrictNotEqual(op) INSTRUCTION(op, CmpStrictNotEqual, 1, lhs) #define INSTR_CmpIn(op) INSTRUCTION(op, CmpIn, 1, lhs) #define INSTR_CmpInstanceOf(op) INSTRUCTION(op, CmpInstanceOf, 1, lhs) -#define INSTR_JumpStrictEqualStackSlotInt(op) INSTRUCTION(op, JumpStrictEqualStackSlotInt, 3, lhs, rhs, offset) -#define INSTR_JumpStrictNotEqualStackSlotInt(op) INSTRUCTION(op, JumpStrictNotEqualStackSlotInt, 3, lhs, rhs, offset) #define INSTR_UNot(op) INSTRUCTION(op, UNot, 0) #define INSTR_UPlus(op) INSTRUCTION(op, UPlus, 0) #define INSTR_UMinus(op) INSTRUCTION(op, UMinus, 0) @@ -168,6 +184,7 @@ QT_BEGIN_NAMESPACE #define INSTR_UShrConst(op) INSTRUCTION(op, UShrConst, 1, rhs) #define INSTR_ShrConst(op) INSTRUCTION(op, ShrConst, 1, rhs) #define INSTR_ShlConst(op) INSTRUCTION(op, ShlConst, 1, rhs) +#define INSTR_Exp(op) INSTRUCTION(op, Exp, 1, lhs) #define INSTR_Mul(op) INSTRUCTION(op, Mul, 1, lhs) #define INSTR_Div(op) INSTRUCTION(op, Div, 1, lhs) #define INSTR_Mod(op) INSTRUCTION(op, Mod, 1, lhs) @@ -175,10 +192,12 @@ QT_BEGIN_NAMESPACE #define INSTR_LoadQmlContext(op) INSTRUCTION(op, LoadQmlContext, 1, result) #define INSTR_LoadQmlImportedScripts(op) INSTRUCTION(op, LoadQmlImportedScripts, 1, result) +#define FOR_EACH_MOTH_INSTR_ALL(F) \ + F(Nop) \ + FOR_EACH_MOTH_INSTR(F) #define FOR_EACH_MOTH_INSTR(F) \ F(Ret) \ - F(Debug) \ F(LoadConst) \ F(LoadZero) \ F(LoadTrue) \ @@ -186,6 +205,7 @@ QT_BEGIN_NAMESPACE F(LoadNull) \ F(LoadUndefined) \ F(LoadInt) \ + F(LoadRuntimeString) \ F(MoveConst) \ F(LoadReg) \ F(StoreReg) \ @@ -194,7 +214,6 @@ QT_BEGIN_NAMESPACE F(StoreLocal) \ F(LoadScopedLocal) \ F(StoreScopedLocal) \ - F(LoadRuntimeString) \ F(MoveRegExp) \ F(LoadClosure) \ F(LoadName) \ @@ -202,53 +221,25 @@ QT_BEGIN_NAMESPACE F(StoreNameSloppy) \ F(StoreNameStrict) \ F(LoadElement) \ - F(LoadElementA) \ F(StoreElement) \ F(LoadProperty) \ - F(LoadPropertyA) \ F(GetLookup) \ - F(GetLookupA) \ F(StoreProperty) \ F(SetLookup) \ + F(LoadSuperProperty) \ + F(StoreSuperProperty) \ F(StoreScopeObjectProperty) \ F(StoreContextObjectProperty) \ F(LoadScopeObjectProperty) \ F(LoadContextObjectProperty) \ F(LoadIdObject) \ - F(CallValue) \ - F(CallProperty) \ - F(CallPropertyLookup) \ - F(CallElement) \ - F(CallName) \ - F(CallPossiblyDirectEval) \ - F(CallGlobalLookup) \ - F(CallScopeObjectProperty) \ - F(CallContextObjectProperty) \ - F(SetExceptionHandler) \ - F(ThrowException) \ - F(GetException) \ - F(SetException) \ - F(CreateCallContext) \ - F(PushCatchContext) \ - F(PushWithContext) \ - F(PopContext) \ - F(ForeachIteratorObject) \ - F(ForeachNextPropertyName) \ - F(DeleteMember) \ - F(DeleteSubscript) \ - F(DeleteName) \ - F(TypeofName) \ - F(TypeofValue) \ - F(DeclareVar) \ - F(DefineArray) \ - F(DefineObjectLiteral) \ - F(CreateMappedArgumentsObject) \ - F(CreateUnmappedArgumentsObject) \ F(ConvertThisToObject) \ - F(Construct) \ + F(ToObject) \ F(Jump) \ F(JumpTrue) \ F(JumpFalse) \ + F(JumpNoException) \ + F(JumpNotUndefined) \ F(CmpEqNull) \ F(CmpNeNull) \ F(CmpEqInt) \ @@ -263,8 +254,6 @@ QT_BEGIN_NAMESPACE F(CmpStrictNotEqual) \ F(CmpIn) \ F(CmpInstanceOf) \ - F(JumpStrictEqualStackSlotInt) \ - F(JumpStrictNotEqualStackSlotInt) \ F(UNot) \ F(UPlus) \ F(UMinus) \ @@ -284,13 +273,60 @@ QT_BEGIN_NAMESPACE F(UShrConst) \ F(ShrConst) \ F(ShlConst) \ + F(Exp) \ F(Mul) \ F(Div) \ F(Mod) \ F(Sub) \ + F(CallValue) \ + F(CallProperty) \ + F(CallPropertyLookup) \ + F(CallElement) \ + F(CallName) \ + F(CallPossiblyDirectEval) \ + F(CallGlobalLookup) \ + F(CallScopeObjectProperty) \ + F(CallContextObjectProperty) \ + F(CallWithSpread) \ + F(Construct) \ + F(ConstructWithSpread) \ + F(SetUnwindHandler) \ + F(UnwindDispatch) \ + F(UnwindToLabel) \ + F(ThrowException) \ + F(GetException) \ + F(SetException) \ + F(CreateCallContext) \ + F(PushCatchContext) \ + F(PushWithContext) \ + F(PushBlockContext) \ + F(CloneBlockContext) \ + F(PopContext) \ + F(GetIterator) \ + F(IteratorNext) \ + F(IteratorClose) \ + F(DestructureRestElement) \ + F(DeleteProperty) \ + F(DeleteName) \ + F(TypeofName) \ + F(TypeofValue) \ + F(DeclareVar) \ + F(DefineArray) \ + F(DefineObjectLiteral) \ + F(CreateMappedArgumentsObject) \ + F(CreateUnmappedArgumentsObject) \ + F(CreateRestParameter) \ F(LoadQmlContext) \ - F(LoadQmlImportedScripts) -#define MOTH_NUM_INSTRUCTIONS() (static_cast<int>(Moth::Instr::Type::LoadQmlImportedScripts) + 1) + F(LoadQmlImportedScripts) \ + F(Yield) \ + F(Resume) \ + F(CreateClass) \ + F(LoadSuperConstructor) \ + F(PushScriptContext) \ + F(PopScriptContext) \ + F(Debug) \ + +#define MOTH_NUM_INSTRUCTIONS() (static_cast<int>(Moth::Instr::Type::Debug_Wide) + 1) #if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) // icc before version 1200 doesn't support computed goto, and at least up to version 18.0.0 the @@ -301,7 +337,7 @@ QT_BEGIN_NAMESPACE #define MOTH_INSTR_ALIGN_MASK (Q_ALIGNOF(QV4::Moth::Instr) - 1) -#define MOTH_INSTR_ENUM(I) I, +#define MOTH_INSTR_ENUM(I) I, I##_Wide, #define MOTH_INSTR_SIZE(I) (sizeof(QV4::Moth::Instr::instr_##I)) #define MOTH_EXPAND_FOR_MSVC(x) x @@ -344,7 +380,7 @@ QT_BEGIN_NAMESPACE #define MOTH_COLLECT_NARGS(instr) \ INSTR_##instr(MOTH_COLLECT_ARG_COUNT) #define MOTH_COLLECT_ARG_COUNT_INSTRUCTION(name, nargs, ...) \ - nargs, + nargs, nargs, #define MOTH_DECODE_ARG(arg, type, nargs, offset) \ arg = qFromLittleEndian<type>(qFromUnaligned<type>(reinterpret_cast<const type *>(code) - nargs + offset)); @@ -397,38 +433,53 @@ QT_BEGIN_NAMESPACE #ifdef MOTH_COMPUTED_GOTO /* collect jump labels */ #define COLLECT_LABELS(instr) \ - INSTR_##instr(GET_LABEL) + INSTR_##instr(GET_LABEL) \ + INSTR_##instr(GET_LABEL_WIDE) #define GET_LABEL_INSTRUCTION(name, ...) \ &&op_byte_##name, -#define COLLECT_LABELS_WIDE(instr) \ - INSTR_##instr(GET_LABEL_WIDE) #define GET_LABEL_WIDE_INSTRUCTION(name, ...) \ &&op_int_##name, #define MOTH_JUMP_TABLE \ static const void *jumpTable[] = { \ - FOR_EACH_MOTH_INSTR(COLLECT_LABELS) \ - FOR_EACH_MOTH_INSTR(COLLECT_LABELS_WIDE) \ + FOR_EACH_MOTH_INSTR_ALL(COLLECT_LABELS) \ }; -#define MOTH_DISPATCH() \ +#define MOTH_DISPATCH_SINGLE() \ goto *jumpTable[*reinterpret_cast<const uchar *>(code)]; + +#define MOTH_DISPATCH() \ + MOTH_DISPATCH_SINGLE() \ + op_byte_Nop: \ + ++code; \ + MOTH_DISPATCH_SINGLE() \ + op_int_Nop: /* wide prefix */ \ + ++code; \ + goto *jumpTable[0x100 | *reinterpret_cast<const uchar *>(code)]; #else #define MOTH_JUMP_TABLE #define MOTH_INSTR_CASE_AND_JUMP(instr) \ - INSTR_##instr(GET_CASE_AND_JUMP) -#define GET_CASE_AND_JUMP_INSTRUCTION(name, ...) \ - case static_cast<uchar>(Instr::Type::name): goto op_byte_##name; -#define MOTH_INSTR_CASE_AND_JUMP_WIDE(instr) \ + INSTR_##instr(GET_CASE_AND_JUMP) \ INSTR_##instr(GET_CASE_AND_JUMP_WIDE) +#define GET_CASE_AND_JUMP_INSTRUCTION(name, ...) \ + case Instr::Type::name: goto op_byte_##name; #define GET_CASE_AND_JUMP_WIDE_INSTRUCTION(name, ...) \ - case (static_cast<uchar>(Instr::Type::name) + MOTH_NUM_INSTRUCTIONS()): goto op_int_##name; + case Instr::Type::name##_Wide: goto op_int_##name; #define MOTH_DISPATCH() \ - switch (static_cast<uchar>(*code)) { \ + Instr::Type type = Instr::Type(static_cast<uchar>(*code)); \ + dispatch: \ + switch (type) { \ + case Instr::Type::Nop: \ + ++code; \ + type = Instr::Type(static_cast<uchar>(*code)); \ + goto dispatch; \ + case Instr::Type::Nop_Wide: /* wide prefix */ \ + ++code; \ + type = Instr::Type(0x100 | static_cast<uchar>(*code)); \ + goto dispatch; \ FOR_EACH_MOTH_INSTR(MOTH_INSTR_CASE_AND_JUMP) \ - FOR_EACH_MOTH_INSTR(MOTH_INSTR_CASE_AND_JUMP_WIDE) \ } #endif @@ -471,12 +522,29 @@ inline void dumpBytecode(const QByteArray &bytecode, int nLocals, int nFormals, union Instr { enum class Type { - FOR_EACH_MOTH_INSTR(MOTH_INSTR_ENUM) + FOR_EACH_MOTH_INSTR_ALL(MOTH_INSTR_ENUM) }; - FOR_EACH_MOTH_INSTR(MOTH_EMIT_STRUCTS) + static Type wideInstructionType(Type t) { return Type(int(t) | 1); } + static Type narrowInstructionType(Type t) { return Type(int(t) & ~1); } + static bool isWide(Type t) { return int(t) & 1; } + static bool isNarrow(Type t) { return !(int(t) & 1); } + static int encodedLength(Type t) { return int(t) >= 256 ? 2 : 1; } + + static Type unpack(const uchar *c) { if (c[0] == 0x1) return Type(0x100 + c[1]); return Type(c[0]); } + static uchar *pack(uchar *c, Type t) { + if (uint(t) >= 256) { + c[0] = 0x1; + c[1] = uint(t) &0xff; + return c + 2; + } + c[0] = uchar(uint(t)); + return c + 1; + } + + FOR_EACH_MOTH_INSTR_ALL(MOTH_EMIT_STRUCTS) - FOR_EACH_MOTH_INSTR(MOTH_EMIT_INSTR_MEMBERS) + FOR_EACH_MOTH_INSTR_ALL(MOTH_EMIT_INSTR_MEMBERS) int argumentsAsInts[4]; }; @@ -487,8 +555,6 @@ struct InstrInfo static int size(Instr::Type type); }; -Q_STATIC_ASSERT(MOTH_NUM_INSTRUCTIONS() < 128); - template<int N> struct InstrMeta { }; @@ -506,7 +572,7 @@ QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") reinterpret_cast<const char *>(&v), \ Size); } \ }; -FOR_EACH_MOTH_INSTR(MOTH_INSTR_META_TEMPLATE); +FOR_EACH_MOTH_INSTR_ALL(MOTH_INSTR_META_TEMPLATE); #undef MOTH_INSTR_META_TEMPLATE QT_WARNING_POP @@ -517,7 +583,7 @@ class InstrData : public InstrMeta<InstrType>::DataType struct Instruction { #define MOTH_INSTR_DATA_TYPEDEF(I) typedef InstrData<int(Instr::Type::I)> I; -FOR_EACH_MOTH_INSTR(MOTH_INSTR_DATA_TYPEDEF) +FOR_EACH_MOTH_INSTR_ALL(MOTH_INSTR_DATA_TYPEDEF) #undef MOTH_INSTR_DATA_TYPEDEF private: Instruction(); |