aboutsummaryrefslogtreecommitdiffstats
path: root/qv4codegen.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2012-12-18 11:01:32 +0100
committerLars Knoll <lars.knoll@digia.com>2012-12-18 11:44:29 +0100
commit328ee44e8a3645623e8400d278563b286d178b2b (patch)
tree5683c0c4f9af2f0fbf131dea2b8b51177259edb4 /qv4codegen.cpp
parent256b8e60ef1690abdfcbf9a75ec302c4ae3d9e36 (diff)
Fix liveness analyses for hidden exception handling TEMPs.
By passing the inCatch/hasException temps to builtin_delete_exception_handler, the TEMPs are marked as alive all through the exception handling block. Change-Id: Ib0f17059e04c03ca98d264759bb2a7e4786ed9be Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'qv4codegen.cpp')
-rw-r--r--qv4codegen.cpp20
1 files changed, 15 insertions, 5 deletions
diff --git a/qv4codegen.cpp b/qv4codegen.cpp
index cf4d94f885..65e7a337ab 100644
--- a/qv4codegen.cpp
+++ b/qv4codegen.cpp
@@ -2208,9 +2208,6 @@ bool Codegen::visit(TryStatement *ast)
// We always need a finally body to clean up the exception handler
IR::BasicBlock *finallyBody = _function->newBasicBlock();
- TryCleanup tcf(_tryCleanup, ast->finallyExpression);
- _tryCleanup = &tcf;
-
int inCatch = 0;
if (catchBody) {
inCatch = _block->newTemp();
@@ -2220,6 +2217,19 @@ bool Codegen::visit(TryStatement *ast)
int hasException = _block->newTemp();
move(_block->TEMP(hasException), _block->CALL(_block->NAME(IR::Name::builtin_create_exception_handler, 0, 0), 0));
+ // Pass the hidden "inCatch" and "hasException" TEMPs to the
+ // builtin_delete_exception_handler, in order to have those TEMPs alive for
+ // the duration of the exception handling block.
+ IR::ExprList *deleteExceptionArgs = _function->New<IR::ExprList>();
+ deleteExceptionArgs->init(_block->TEMP(hasException));
+ if (inCatch) {
+ deleteExceptionArgs->next = _function->New<IR::ExprList>();
+ deleteExceptionArgs->next->init(_block->TEMP(inCatch));
+ }
+
+ TryCleanup tcf(_tryCleanup, ast->finallyExpression, deleteExceptionArgs);
+ _tryCleanup = &tcf;
+
_block->CJUMP(_block->TEMP(hasException), catchBody ? catchBody : finallyBody, tryBody);
_block = tryBody;
@@ -2266,7 +2276,7 @@ bool Codegen::visit(TryStatement *ast)
IR::BasicBlock *after = _function->newBasicBlock();
_block = finallyBody;
- _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_delete_exception_handler, 0, 0), 0));
+ _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_delete_exception_handler, 0, 0), deleteExceptionArgs));
if (ast->finallyExpression && ast->finallyExpression->statement)
statement(ast->finallyExpression->statement);
@@ -2288,7 +2298,7 @@ void Codegen::unwindException(Codegen::TryCleanup *outest)
TryCleanup *tryCleanup = _tryCleanup;
qSwap(_tryCleanup, tryCleanup);
while (_tryCleanup != outest) {
- _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_delete_exception_handler, 0, 0), 0));
+ _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_delete_exception_handler, 0, 0), _tryCleanup->deleteExceptionArgs));
TryCleanup *tc = _tryCleanup;
_tryCleanup = tc->parent;
if (tc->finally && tc->finally->statement)