diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-07-02 13:32:46 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-07-03 11:18:57 +0000 |
commit | a2372fd2c643615687ea3b8b1ccf53d699b6debd (patch) | |
tree | d86a2b3f6ea56d92b70ef25b26dd1f7fa401f260 /src/qml/compiler/qv4bytecodegenerator.cpp | |
parent | 386036e23b67d6aa6d10ff166a1904f18c304a8a (diff) |
Allow for more than 128 bytecode instructions
Instructions always occupy two numbers, an even and the following
odd one, for the single byte and four byte encoding.
An instruction of 0x0 is now a NOP, but 0x1 implies that the
instruction type is using two bytes, and the following byte needs
to be read as well to get the correct instruction type.
Encoding and decoding of those two byte instructions is fully
transparent, and adding more instructions now doesn't require
any special handling.
The first 127 instructions in the FOR_EACH_MOTH_INSTR macro will
get a single byte encoding, the remaining ones will use two bytes.
When adding new instructions, make sure to put often used and fast
instructions into the first 127 instructions, while adding rarely
used (or slow) instructions to the end (before Debug though).
Change-Id: Id772a109641ab68feb228c3abd05f41ae7075e94
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4bytecodegenerator.cpp')
-rw-r--r-- | src/qml/compiler/qv4bytecodegenerator.cpp | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp index 6efeac2a31..7e1f49ee86 100644 --- a/src/qml/compiler/qv4bytecodegenerator.cpp +++ b/src/qml/compiler/qv4bytecodegenerator.cpp @@ -75,8 +75,9 @@ void BytecodeGenerator::packInstruction(I &i) type = Instr::narrowInstructionType(type); int instructionsAsInts[sizeof(Instr)/sizeof(int)] = {}; int nMembers = Moth::InstrInfo::argumentCount[static_cast<int>(i.type)]; + uchar *code = i.packed + Instr::encodedLength(type); for (int j = 0; j < nMembers; ++j) { - instructionsAsInts[j] = qFromLittleEndian<qint32>(i.packed + 1 + j * sizeof(int)); + instructionsAsInts[j] = qFromLittleEndian<qint32>(code + j * sizeof(int)); } enum { Normal, @@ -88,11 +89,10 @@ void BytecodeGenerator::packInstruction(I &i) break; } } - uchar *code = i.packed; + code = i.packed; switch (width) { case Normal: - Instr::pack(code, type); - ++code; + code = Instr::pack(code, type); for (int n = 0; n < nMembers; ++n) { qint8 v = static_cast<qint8>(instructionsAsInts[n]); memcpy(code, &v, 1); @@ -225,12 +225,10 @@ QT_WARNING_POP const int argCount = Moth::InstrInfo::argumentCount[static_cast<int>(type)]; int s = argCount*sizeof(int); if (offsetOfOffset != -1) - offsetOfOffset += 1; - I instr{type, static_cast<short>(s + 1), 0, currentLine, offsetOfOffset, -1, "\0\0" }; + offsetOfOffset += Instr::encodedLength(type); + I instr{type, static_cast<short>(s + Instr::encodedLength(type)), 0, currentLine, offsetOfOffset, -1, "\0\0" }; uchar *code = instr.packed; - Instr::pack(code, Instr::wideInstructionType(type)); - ++code; - Q_ASSERT(static_cast<uint>(Instr::wideInstructionType(type)) < 256); + code = Instr::pack(code, Instr::wideInstructionType(type)); for (int j = 0; j < argCount; ++j) { qToLittleEndian<qint32>(i.argumentsAsInts[j], code); |