diff options
author | Lars Knoll <lars.knoll@digia.com> | 2012-12-02 10:29:59 -0800 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-12-02 20:14:28 +0100 |
commit | d8530fedc2cc75c1abc8452dac18b8e81d61d6d5 (patch) | |
tree | e4b4947b2b53287c5aa53cab18d28b0958186719 /qv4codegen_p.h | |
parent | 11c4b283e45c08dee5b29391617486ef9f891fda (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.h | 12 |
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; |