diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-06-13 10:06:03 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2017-06-19 13:36:00 +0000 |
commit | 5e9551ec5b1a782882f93310f8f07be51bb17bf7 (patch) | |
tree | 6db063718c5b6d602e2bc152a5a74843a5df16a1 /src/qml/compiler/qv4bytecodegenerator_p.h | |
parent | 4d329ef984d0f64b9446321ef63fc5a70cd103cd (diff) |
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 <erik.verbruggen@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4bytecodegenerator_p.h')
-rw-r--r-- | src/qml/compiler/qv4bytecodegenerator_p.h | 71 |
1 files changed, 58 insertions, 13 deletions
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<int> 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<int InstrT> - CodeRef addInstruction(const InstrData<InstrT> &data) + void addInstruction(const InstrData<InstrT> &data) { Instr genericInstr; genericInstr.common.instructionType = static_cast<Instr::Type>(InstrT); InstrMeta<InstrT>::setDataNoCommon(genericInstr, data); - return { addInstructionHelper(InstrMeta<InstrT>::Size, genericInstr) }; + addInstructionHelper(InstrMeta<InstrT>::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<int InstrT> + Jump addJumpInstruction(const InstrData<InstrT> &data) + { + Instr genericInstr; + genericInstr.common.instructionType = static_cast<Instr::Type>(InstrT); + InstrMeta<InstrT>::setDataNoCommon(genericInstr, data); + return Jump(this, addInstructionHelper(InstrMeta<InstrT>::Size, genericInstr), offsetof(InstrData<InstrT>, 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<I> instructions; - - QVector<Label> labels; + QVector<JumpData> jumps; IR::Function *function; // ### remove me at some point }; |