diff options
-rw-r--r-- | src/qml/compiler/qv4bytecodegenerator.cpp | 21 | ||||
-rw-r--r-- | src/qml/compiler/qv4bytecodegenerator_p.h | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth.cpp | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 24 |
4 files changed, 27 insertions, 22 deletions
diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp index 1d1e98ea58..6efeac2a31 100644 --- a/src/qml/compiler/qv4bytecodegenerator.cpp +++ b/src/qml/compiler/qv4bytecodegenerator.cpp @@ -70,10 +70,9 @@ int BytecodeGenerator::newRegisterArray(int n) void BytecodeGenerator::packInstruction(I &i) { - uchar type = *reinterpret_cast<uchar *>(i.packed); - Q_ASSERT(type >= MOTH_NUM_INSTRUCTIONS()); - if (type >= MOTH_NUM_INSTRUCTIONS()) - type -= MOTH_NUM_INSTRUCTIONS(); + Instr::Type type = Instr::unpack(i.packed); + Q_ASSERT(int(type) < MOTH_NUM_INSTRUCTIONS()); + type = Instr::narrowInstructionType(type); int instructionsAsInts[sizeof(Instr)/sizeof(int)] = {}; int nMembers = Moth::InstrInfo::argumentCount[static_cast<int>(i.type)]; for (int j = 0; j < nMembers; ++j) { @@ -89,10 +88,10 @@ void BytecodeGenerator::packInstruction(I &i) break; } } - char *code = i.packed; + uchar *code = i.packed; switch (width) { case Normal: - *reinterpret_cast<uchar *>(code) = type; + Instr::pack(code, type); ++code; for (int n = 0; n < nMembers; ++n) { qint8 v = static_cast<qint8>(instructionsAsInts[n]); @@ -122,7 +121,7 @@ void BytecodeGenerator::adjustJumpOffsets() // qDebug() << "adjusting jump offset for instruction" << index << i.position << i.size << "offsetForJump" << i.offsetForJump << "target" // << labels.at(i.linkedLabel) << linkedInstruction.position << "jumpOffset" << jumpOffset; uchar type = *reinterpret_cast<const uchar *>(i.packed); - if (type >= MOTH_NUM_INSTRUCTIONS()) { + if (Instr::isWide(Instr::Type(type))) { Q_ASSERT(i.offsetForJump == i.size - 4); qToLittleEndian<qint32>(jumpOffset, c); } else { @@ -177,7 +176,7 @@ void BytecodeGenerator::finalize(Compiler::Context *context) entry.line = currentLine; lineNumbers.append(entry); } - code.append(i.packed, i.size); + code.append(reinterpret_cast<const char *>(i.packed), i.size); } context->code = code; @@ -228,10 +227,10 @@ QT_WARNING_POP if (offsetOfOffset != -1) offsetOfOffset += 1; I instr{type, static_cast<short>(s + 1), 0, currentLine, offsetOfOffset, -1, "\0\0" }; - char *code = instr.packed; - *reinterpret_cast<uchar *>(code) = static_cast<uchar>(MOTH_NUM_INSTRUCTIONS() + static_cast<int>(type)); + uchar *code = instr.packed; + Instr::pack(code, Instr::wideInstructionType(type)); ++code; - Q_ASSERT(MOTH_NUM_INSTRUCTIONS() + static_cast<int>(type) < 256); + Q_ASSERT(static_cast<uint>(Instr::wideInstructionType(type)) < 256); for (int j = 0; j < argCount; ++j) { qToLittleEndian<qint32>(i.argumentsAsInts[j], code); diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h index 78ce3624ea..dca5771356 100644 --- a/src/qml/compiler/qv4bytecodegenerator_p.h +++ b/src/qml/compiler/qv4bytecodegenerator_p.h @@ -279,7 +279,7 @@ private: int line; int offsetForJump; int linkedLabel; - char packed[sizeof(Instr) + 2]; // 2 for instruction and prefix + unsigned char packed[sizeof(Instr) + 2]; // 2 for instruction type }; void compressInstructions(); diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp index 5621b456d5..6773f97c8b 100644 --- a/src/qml/compiler/qv4instr_moth.cpp +++ b/src/qml/compiler/qv4instr_moth.cpp @@ -46,7 +46,7 @@ using namespace QV4::Moth; int InstrInfo::size(Instr::Type type) { -#define MOTH_RETURN_INSTR_SIZE(I) case Instr::Type::I: return InstrMeta<int(Instr::Type::I)>::Size; +#define MOTH_RETURN_INSTR_SIZE(I) case Instr::Type::I: case Instr::Type::I##_Wide: return InstrMeta<int(Instr::Type::I)>::Size; switch (type) { FOR_EACH_MOTH_INSTR(MOTH_RETURN_INSTR_SIZE) } diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index 7c1d4db4ca..29fc28c128 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -321,7 +321,7 @@ QT_BEGIN_NAMESPACE F(Sub) \ F(LoadQmlContext) \ F(LoadQmlImportedScripts) -#define MOTH_NUM_INSTRUCTIONS() (static_cast<int>(Moth::Instr::Type::LoadQmlImportedScripts) + 1) +#define MOTH_NUM_INSTRUCTIONS() (static_cast<int>(Moth::Instr::Type::LoadQmlImportedScripts_Wide)) #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 @@ -332,7 +332,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 @@ -375,7 +375,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>( \ @@ -430,18 +430,16 @@ 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) \ }; #define MOTH_DISPATCH() \ @@ -456,7 +454,7 @@ QT_BEGIN_NAMESPACE #define MOTH_INSTR_CASE_AND_JUMP_WIDE(instr) \ INSTR_##instr(GET_CASE_AND_JUMP_WIDE) #define GET_CASE_AND_JUMP_WIDE_INSTRUCTION(name, ...) \ - case (static_cast<uchar>(Instr::Type::name) + MOTH_NUM_INSTRUCTIONS()): goto op_int_##name; + case (static_cast<uchar>(Instr::Type::name##_Wide)): goto op_int_##name; #define MOTH_DISPATCH() \ switch (static_cast<uchar>(*code)) { \ @@ -507,6 +505,14 @@ union Instr FOR_EACH_MOTH_INSTR(MOTH_INSTR_ENUM) }; + 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 Type unpack(const uchar *c) { return Type(*c); } + static void pack(uchar *c, Type t) { *c = uchar(uint(t)); } + FOR_EACH_MOTH_INSTR(MOTH_EMIT_STRUCTS) FOR_EACH_MOTH_INSTR(MOTH_EMIT_INSTR_MEMBERS) @@ -520,7 +526,7 @@ struct InstrInfo static int size(Instr::Type type); }; -Q_STATIC_ASSERT(MOTH_NUM_INSTRUCTIONS() <= 128); +Q_STATIC_ASSERT(MOTH_NUM_INSTRUCTIONS() <= 256); template<int N> struct InstrMeta { |