From 5e9551ec5b1a782882f93310f8f07be51bb17bf7 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 13 Jun 2017 10:06:03 +0200 Subject: Rework and implement Jump handling in the bytecode generator Add Label and Jump classes to facilitate the handling, and resolve them to proper offsets at finalize() time. Change-Id: Ic140a3ceb848fb29657a1b156c97b806db6dc434 Reviewed-by: Erik Verbruggen --- src/qml/compiler/qv4bytecodegenerator_p.h | 71 +++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 13 deletions(-) (limited to 'src/qml/compiler/qv4bytecodegenerator_p.h') diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h index 7996374175..5c7480fc89 100644 --- a/src/qml/compiler/qv4bytecodegenerator_p.h +++ b/src/qml/compiler/qv4bytecodegenerator_p.h @@ -55,32 +55,61 @@ public: BytecodeGenerator(IR::Function *function) : function(function) {} - struct CodeRef { - int instructionIndex; + struct Label { + int index; }; - struct Label { - void link(CodeRef r) { - linkedInstructions.append(r.instructionIndex); + struct Jump { + Jump(BytecodeGenerator *generator, int instruction, int offset) + : generator(generator), + index(generator->jumps.size()) + { + generator->jumps.append({ instruction, offset, -1 }); } + BytecodeGenerator *generator; int index; - QVector linkedInstructions; + + void link() { + link(generator->label()); + } + void link(Label l) { + Q_ASSERT(generator->jumps[index].linkedInstruction == -1); + generator->jumps[index].linkedInstruction = l.index; + } }; Label label() { - Label l; - l.index = labels.size(); - return l; + return { instructions.size() }; } template - CodeRef addInstruction(const InstrData &data) + void addInstruction(const InstrData &data) { Instr genericInstr; genericInstr.common.instructionType = static_cast(InstrT); InstrMeta::setDataNoCommon(genericInstr, data); - return { addInstructionHelper(InstrMeta::Size, genericInstr) }; + addInstructionHelper(InstrMeta::Size, genericInstr); + } + + Q_REQUIRED_RESULT Jump addInstruction(const Instruction::Jump &data) + { + return addJumpInstruction(data); + } + + Q_REQUIRED_RESULT Jump addInstruction(const Instruction::SetExceptionHandler &data) + { + return addJumpInstruction(data); + } + + Q_REQUIRED_RESULT Jump addInstruction(const Instruction::JumpEq &data) + { + return addJumpInstruction(data); + } + + Q_REQUIRED_RESULT Jump addInstruction(const Instruction::JumpNe &data) + { + return addJumpInstruction(data); } unsigned newTemp(); @@ -89,20 +118,36 @@ public: QByteArray finalize(); private: + friend struct Jump; + + template + Jump addJumpInstruction(const InstrData &data) + { + Instr genericInstr; + genericInstr.common.instructionType = static_cast(InstrT); + InstrMeta::setDataNoCommon(genericInstr, data); + return Jump(this, addInstructionHelper(InstrMeta::Size, genericInstr), offsetof(InstrData, offset)); + } + int addInstructionHelper(uint size, const Instr &i) { int pos = instructions.size(); instructions.append({size, i}); return pos; } + struct JumpData { + int instructionIndex; + int offset; + int linkedInstruction = -1; + }; + struct I { uint size; Instr instr; }; QVector instructions; - - QVector