diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2012-12-18 11:01:32 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@digia.com> | 2012-12-18 11:44:29 +0100 |
commit | 328ee44e8a3645623e8400d278563b286d178b2b (patch) | |
tree | 5683c0c4f9af2f0fbf131dea2b8b51177259edb4 /qv4codegen.cpp | |
parent | 256b8e60ef1690abdfcbf9a75ec302c4ae3d9e36 (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.cpp | 20 |
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) |