Fix liveness analyses for hidden exception handling TEMPs.
authorErik Verbruggen <erik.verbruggen@digia.com>
Tue, 18 Dec 2012 10:01:32 +0000 (11:01 +0100)
committerLars Knoll <lars.knoll@digia.com>
Tue, 18 Dec 2012 10:44:29 +0000 (11:44 +0100)
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>
qv4codegen.cpp
qv4codegen_p.h

index cf4d94f..65e7a33 100644 (file)
@@ -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)
index b9e0a71..4ee9c5a 100644 (file)
@@ -207,9 +207,11 @@ protected:
     struct TryCleanup {
         TryCleanup *parent;
         AST::Finally *finally;
+        IR::ExprList *deleteExceptionArgs;
 
-        TryCleanup(TryCleanup *parent, AST::Finally *finally)
-            : parent(parent), finally(finally) {}
+        TryCleanup(TryCleanup *parent, AST::Finally *finally, IR::ExprList *deleteExceptionArgs)
+            : parent(parent), finally(finally), deleteExceptionArgs(deleteExceptionArgs)
+        {}
     };
 
     struct Loop {