diff options
Diffstat (limited to 'src/qml/compiler/qv4bytecodegenerator.cpp')
-rw-r--r-- | src/qml/compiler/qv4bytecodegenerator.cpp | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp index 4d50654d27..7e1f49ee86 100644 --- a/src/qml/compiler/qv4bytecodegenerator.cpp +++ b/src/qml/compiler/qv4bytecodegenerator.cpp @@ -70,14 +70,14 @@ 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)]; + 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, @@ -89,11 +89,10 @@ void BytecodeGenerator::packInstruction(I &i) break; } } - char *code = i.packed; + code = i.packed; switch (width) { case Normal: - *reinterpret_cast<uchar *>(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); @@ -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; @@ -185,6 +184,25 @@ void BytecodeGenerator::finalize(Compiler::Context *context) } int BytecodeGenerator::addInstructionHelper(Instr::Type type, const Instr &i, int offsetOfOffset) { + if (lastInstrType == int(Instr::Type::StoreReg)) { + if (type == Instr::Type::LoadReg) { + if (i.LoadReg.reg == lastInstr.StoreReg.reg) { + // value is already in the accumulator + return -1; + } + } + if (type == Instr::Type::MoveReg) { + if (i.MoveReg.srcReg == lastInstr.StoreReg.reg) { + Instruction::StoreReg store; + store.reg = i.MoveReg.destReg; + addInstruction(store); + return -1; + } + } + } + lastInstrType = int(type); + lastInstr = i; + #if QT_CONFIG(qml_debug) if (debugMode && type != Instr::Type::Debug) { QT_WARNING_PUSH @@ -207,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" }; - char *code = instr.packed; - *reinterpret_cast<uchar *>(code) = static_cast<uchar>(MOTH_NUM_INSTRUCTIONS() + static_cast<int>(type)); - ++code; - Q_ASSERT(MOTH_NUM_INSTRUCTIONS() + static_cast<int>(type) < 256); + offsetOfOffset += Instr::encodedLength(type); + I instr{type, static_cast<short>(s + Instr::encodedLength(type)), 0, currentLine, offsetOfOffset, -1, "\0\0" }; + uchar *code = instr.packed; + code = Instr::pack(code, Instr::wideInstructionType(type)); for (int j = 0; j < argCount; ++j) { qToLittleEndian<qint32>(i.argumentsAsInts[j], code); |