changeset 1412:3f5ea912149d

Fix #308 by giving finally code emitted by EnclosingTryFinally a different landing pad.
author Christian Kamm <kamm incasoftware de>
date Sat, 23 May 2009 00:23:39 +0200
parents e57859ca8f1e
children f9285cf14c0d
files gen/irstate.h gen/llvmhelpers.cpp gen/llvmhelpers.h gen/statements.cpp ir/irfunction.cpp ir/irfunction.h ir/irlandingpad.cpp
diffstat 7 files changed, 29 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/gen/irstate.h	Fri May 22 21:38:01 2009 +0200
+++ b/gen/irstate.h	Sat May 23 00:23:39 2009 +0200
@@ -175,8 +175,8 @@
 template <typename InputIterator>
 llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name)
 {
-    llvm::BasicBlock* pad;
-    if(pad = func()->landingPad.get())
+    llvm::BasicBlock* pad = func()->landingPad;
+    if(pad)
     {
         // intrinsics don't support invoking and 'nounwind' functions don't need it.
         LLFunction* funcval = llvm::dyn_cast<LLFunction>(Callee);
--- a/gen/llvmhelpers.cpp	Fri May 22 21:38:01 2009 +0200
+++ b/gen/llvmhelpers.cpp	Sat May 23 00:23:39 2009 +0200
@@ -255,7 +255,12 @@
 void EnclosingTryFinally::emitCode(IRState * p)
 {
     if (tf->finalbody)
+    {
+        llvm::BasicBlock* oldpad = p->func()->landingPad;
+        p->func()->landingPad = landingPad;
         tf->finalbody->toIR(p);
+        p->func()->landingPad = oldpad;
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/llvmhelpers.h	Fri May 22 21:38:01 2009 +0200
+++ b/gen/llvmhelpers.h	Sat May 23 00:23:39 2009 +0200
@@ -15,8 +15,10 @@
 struct EnclosingTryFinally : EnclosingHandler
 {
     TryFinallyStatement* tf;
+    llvm::BasicBlock* landingPad;
     void emitCode(IRState* p);
-    EnclosingTryFinally(TryFinallyStatement* _tf) : tf(_tf) {}
+    EnclosingTryFinally(TryFinallyStatement* _tf, llvm::BasicBlock* _pad) 
+    : tf(_tf), landingPad(_pad) {}
 };
 struct EnclosingVolatile : EnclosingHandler
 {
--- a/gen/statements.cpp	Fri May 22 21:38:01 2009 +0200
+++ b/gen/statements.cpp	Sat May 23 00:23:39 2009 +0200
@@ -592,8 +592,10 @@
     p->scope() = IRScope(landingpadbb, endbb);
 
     assert(finalbody);
-    gIR->func()->landingPad.addFinally(finalbody);
-    gIR->func()->landingPad.push(landingpadbb);
+    gIR->func()->targetScopes.push_back(IRTargetScope(this,new EnclosingTryFinally(this,gIR->func()->landingPad),NULL,NULL));
+    gIR->func()->landingPadInfo.addFinally(finalbody);
+    gIR->func()->landingPadInfo.push(landingpadbb);
+    gIR->func()->landingPad = gIR->func()->landingPadInfo.get();
 
     //
     // do the try block
@@ -601,15 +603,15 @@
     p->scope() = IRScope(trybb,finallybb);
 
     assert(body);
-    p->func()->targetScopes.push_back(IRTargetScope(this,new EnclosingTryFinally(this),NULL,NULL));
     body->toIR(p);
-    p->func()->targetScopes.pop_back();
 
     // terminate try BB
     if (!p->scopereturned())
         llvm::BranchInst::Create(finallybb, p->scopebb());
 
-    gIR->func()->landingPad.pop();
+    gIR->func()->landingPadInfo.pop();
+    gIR->func()->landingPad = gIR->func()->landingPadInfo.get();
+    gIR->func()->targetScopes.pop_back();
 
     //
     // do finally block
@@ -658,10 +660,11 @@
     for (int i = 0; i < catches->dim; i++)
     {
         Catch *c = (Catch *)catches->data[i];
-        gIR->func()->landingPad.addCatch(c, endbb);
+        gIR->func()->landingPadInfo.addCatch(c, endbb);
     }
 
-    gIR->func()->landingPad.push(landingpadbb);
+    gIR->func()->landingPadInfo.push(landingpadbb);
+    gIR->func()->landingPad = gIR->func()->landingPadInfo.get();
 
     //
     // do the try block
@@ -674,7 +677,8 @@
     if (!gIR->scopereturned())
         llvm::BranchInst::Create(endbb, p->scopebb());
 
-    gIR->func()->landingPad.pop();
+    gIR->func()->landingPadInfo.pop();
+    gIR->func()->landingPad = gIR->func()->landingPadInfo.get();
 
     // rewrite the scope
     p->scope() = IRScope(endbb,oldend);
--- a/ir/irfunction.cpp	Fri May 22 21:38:01 2009 +0200
+++ b/ir/irfunction.cpp	Sat May 23 00:23:39 2009 +0200
@@ -117,6 +117,8 @@
     _arguments = NULL;
     _argptr = NULL;
     
+    landingPad = NULL;
+    
     nextUnique.push(0);
 }
 
--- a/ir/irfunction.h	Fri May 22 21:38:01 2009 +0200
+++ b/ir/irfunction.h	Sat May 23 00:23:39 2009 +0200
@@ -70,7 +70,8 @@
     LabelToBBMap labelToBB;
 
     // landing pads for try statements
-    IRLandingPad landingPad;
+    IRLandingPad landingPadInfo;
+    llvm::BasicBlock* landingPad;
 
     // loop blocks
     typedef std::vector<IRTargetScope> TargetScopeVec;
--- a/ir/irlandingpad.cpp	Fri May 22 21:38:01 2009 +0200
+++ b/ir/irlandingpad.cpp	Sat May 23 00:23:39 2009 +0200
@@ -24,7 +24,7 @@
     #endif
             assert(!catchstmt->var->ir.irLocal);
             catchstmt->var->ir.irLocal = new IrLocal(catchstmt->var);
-            LLValue* catch_var = gIR->func()->landingPad.getExceptionStorage();
+            LLValue* catch_var = gIR->func()->landingPadInfo.getExceptionStorage();
             catchstmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchstmt->var->type)));
         }
 
@@ -32,8 +32,8 @@
         DtoDeclarationExp(catchstmt->var);
 
         // the exception will only be stored in catch_var. copy it over if necessary
-        if(catchstmt->var->ir.irLocal->value != gIR->func()->landingPad.getExceptionStorage()) {
-            LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->landingPad.getExceptionStorage()), DtoType(catchstmt->var->type));
+        if(catchstmt->var->ir.irLocal->value != gIR->func()->landingPadInfo.getExceptionStorage()) {
+            LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->landingPadInfo.getExceptionStorage()), DtoType(catchstmt->var->type));
             DtoStore(exc, catchstmt->var->ir.irLocal->value);
         }
     }