aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4bytecodegenerator_p.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-06-13 10:06:03 +0200
committerErik Verbruggen <erik.verbruggen@qt.io>2017-06-19 13:36:00 +0000
commit5e9551ec5b1a782882f93310f8f07be51bb17bf7 (patch)
tree6db063718c5b6d602e2bc152a5a74843a5df16a1 /src/qml/compiler/qv4bytecodegenerator_p.h
parent4d329ef984d0f64b9446321ef63fc5a70cd103cd (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.h71
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
};