aboutsummaryrefslogtreecommitdiffstats
path: root/qv4codegen_p.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2012-12-02 10:29:59 -0800
committerSimon Hausmann <simon.hausmann@digia.com>2012-12-02 20:14:28 +0100
commitd8530fedc2cc75c1abc8452dac18b8e81d61d6d5 (patch)
treee4b4947b2b53287c5aa53cab18d28b0958186719 /qv4codegen_p.h
parent11c4b283e45c08dee5b29391617486ef9f891fda (diff)
Fix code generation for try statements
The old code was not correctly handling statements as try { return; } finally {...} and others. In addition it was hard to read an maintain. We now keep a stack of try statements inside the code generator. Loops know about their surrounding try statement. Whenever a break, continue or return statement is encountered we now generate code for the finally statements and exception handlers we need to cleanup. Change-Id: I53bcc0587f1e923be00fea9b562453ef1e96b2de Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'qv4codegen_p.h')
-rw-r--r--qv4codegen_p.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/qv4codegen_p.h b/qv4codegen_p.h
index 27c910fd8b..a75c872b58 100644
--- a/qv4codegen_p.h
+++ b/qv4codegen_p.h
@@ -167,12 +167,21 @@ protected:
struct UiMember {
};
+ struct TryCleanup {
+ TryCleanup *parent;
+ AST::Finally *finally;
+
+ TryCleanup(TryCleanup *parent, AST::Finally *finally)
+ : parent(parent), finally(finally) {}
+ };
+
struct Loop {
AST::LabelledStatement *labelledStatement;
AST::Statement *node;
IR::BasicBlock *breakBlock;
IR::BasicBlock *continueBlock;
Loop *parent;
+ TryCleanup *tryCleanup;
Loop(AST::Statement *node, IR::BasicBlock *breakBlock, IR::BasicBlock *continueBlock, Loop *parent)
: labelledStatement(0), node(node), breakBlock(breakBlock), continueBlock(continueBlock), parent(parent) {}
@@ -184,6 +193,7 @@ protected:
void enterLoop(AST::Statement *node, IR::BasicBlock *breakBlock, IR::BasicBlock *continueBlock);
void leaveLoop();
+
IR::Expr *member(IR::Expr *base, const QString *name);
IR::Expr *subscript(IR::Expr *base, IR::Expr *index);
IR::Expr *argument(IR::Expr *expr);
@@ -199,6 +209,7 @@ protected:
int indexOfArgument(const QStringRef &string) const;
void generateFinallyBlock(IR::BasicBlock *finallyBlock, bool exceptionNeedsSaving, AST::Finally *ast, int hasException, IR::BasicBlock *after);
+ void unwindException(TryCleanup *outest);
void statement(AST::Statement *ast);
void statement(AST::ExpressionNode *ast);
@@ -332,6 +343,7 @@ private:
Environment *_env;
Loop *_loop;
AST::LabelledStatement *_labelledStatement;
+ TryCleanup *_tryCleanup;
QHash<AST::Node *, Environment *> _envMap;
QHash<AST::FunctionExpression *, int> _functionMap;
Debugging::Debugger *_debugger;