aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4bytecodegenerator_p.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-06-16 15:30:23 +0200
committerLars Knoll <lars.knoll@qt.io>2017-06-20 10:03:53 +0000
commit1c13f23a093147152b3d61632d52bf264e05c2c0 (patch)
tree8f4f3baabb1d1341905d5ccbbc9beff55876c20a /src/qml/compiler/qv4bytecodegenerator_p.h
parent84501b6f4c469c2009e94d4439542806952f7713 (diff)
Proper exception handling
Implement exception handling, and make it conformant with the spec. Change-Id: I6d8222617180f96f628f18e11444488e50e5c043 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.h60
1 files changed, 48 insertions, 12 deletions
diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h
index 0ce20d98d9..448320491e 100644
--- a/src/qml/compiler/qv4bytecodegenerator_p.h
+++ b/src/qml/compiler/qv4bytecodegenerator_p.h
@@ -56,23 +56,37 @@ public:
: function(function) {}
struct Label {
- BytecodeGenerator *generator = 0;
- int index = -1;
+ enum LinkMode {
+ LinkNow,
+ LinkLater
+ };
+ Label() = default;
+ Label(BytecodeGenerator *generator, LinkMode mode = LinkNow)
+ : generator(generator),
+ index(generator->labels.size()) {
+ generator->labels.append(mode == LinkNow ? generator->instructions.size() : -1);
+ }
void link() {
Q_ASSERT(index >= 0);
Q_ASSERT(generator->labels[index] == -1);
generator->labels[index] = generator->instructions.size();
}
+
+ BytecodeGenerator *generator = 0;
+ int index = -1;
};
struct Jump {
Jump(BytecodeGenerator *generator, int instruction, int offset)
: generator(generator),
- index(generator->jumps.size())
- {
+ index(generator->jumps.size()) {
generator->jumps.append({ instruction, offset, -1 });
}
+ ~Jump() {
+ Q_ASSERT(generator->jumps[index].linkedLabel != -1);
+ }
+
BytecodeGenerator *generator;
int index;
@@ -87,16 +101,27 @@ public:
}
};
+ struct ExceptionHandler : public Label {
+ ExceptionHandler(BytecodeGenerator *generator)
+ : Label(generator, LinkLater)
+ {
+ }
+ ~ExceptionHandler()
+ {
+ Q_ASSERT(generator->currentExceptionHandler != this);
+ }
+ };
+
Label label() {
- Label l = { this, labels.size() };
- labels.append(instructions.size());
- return l;
+ return Label(this, Label::LinkNow);
}
Label newLabel() {
- Label l = { this, labels.size() };
- labels.append(-1);
- return l;
+ return Label(this, Label::LinkLater);
+ }
+
+ ExceptionHandler newExceptionHandler() {
+ return ExceptionHandler(this);
}
template<int InstrT>
@@ -144,12 +169,20 @@ public:
return addJumpInstruction(data);
}
- Q_REQUIRED_RESULT Jump setExceptionHandler()
+ void setExceptionHandler(ExceptionHandler *handler)
{
+ currentExceptionHandler = handler;
Instruction::SetExceptionHandler data;
- return addJumpInstruction(data);
+ data.offset = 0;
+ if (!handler)
+ addInstruction(data);
+ else
+ addJumpInstruction(data).link(*handler);
}
+ ExceptionHandler *exceptionHandler() const {
+ return currentExceptionHandler;
+ }
unsigned newTemp();
@@ -158,6 +191,8 @@ public:
private:
friend struct Jump;
+ friend struct Label;
+ friend struct ExceptionHandler;
template<int InstrT>
Jump addJumpInstruction(const InstrData<InstrT> &data)
@@ -189,6 +224,7 @@ private:
QVector<int> labels;
QVector<JumpData> jumps;
IR::Function *function; // ### remove me at some point
+ ExceptionHandler *currentExceptionHandler;
};
}