aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qv4bytecodegenerator.cpp21
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h2
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp2
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h24
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 {