[svn r323] Branching out of inline asm works.

Renamed emit_finallyblocks to DtoFinallyBlocks and moved to llvmhelpers.
Added enclosingtryfinally to AsmBlockStatement, so branches out of asm blocks respect finallys.
Refactored some GotoStatement code into DtoGoto.
This commit is contained in:
Christian Kamm
2008-06-25 20:39:09 +02:00
parent 37a74d1975
commit 7b37093cff
7 changed files with 175 additions and 98 deletions

View File

@@ -150,6 +150,54 @@ void DtoAssert(Loc* loc, DValue* msg)
gIR->ir->CreateUnreachable();
}
/****************************************************************************************/
/*////////////////////////////////////////////////////////////////////////////////////////
// GOTO HELPER
////////////////////////////////////////////////////////////////////////////////////////*/
void DtoGoto(Loc* loc, LabelDsymbol* target, TryFinallyStatement* enclosingtryfinally)
{
assert(!gIR->scopereturned());
if (target->statement->llvmBB == NULL)
target->statement->llvmBB = llvm::BasicBlock::Create("label", gIR->topfunc());
// find finallys between goto and label
TryFinallyStatement* endfinally = enclosingtryfinally;
while(endfinally != NULL && endfinally != target->statement->enclosingtryfinally) {
endfinally = endfinally->enclosingtryfinally;
}
// error if didn't find tf statement of label
if(endfinally != target->statement->enclosingtryfinally)
error("cannot goto into try block", loc->toChars());
// emit code for finallys between goto and label
DtoFinallyBlocks(enclosingtryfinally, endfinally);
llvm::BranchInst::Create(target->statement->llvmBB, gIR->scopebb());
}
/****************************************************************************************/
/*////////////////////////////////////////////////////////////////////////////////////////
// TRY FINALLY HELPER
////////////////////////////////////////////////////////////////////////////////////////*/
void DtoFinallyBlocks(TryFinallyStatement* start, TryFinallyStatement* end)
{
// verify that end encloses start
TryFinallyStatement* endfinally = start;
while(endfinally != NULL && endfinally != end) {
endfinally = endfinally->enclosingtryfinally;
}
assert(endfinally == end);
// emit code for finallys between start and end
TryFinallyStatement* tf = start;
while(tf != end) {
tf->finalbody->toIR(gIR);
tf = tf->enclosingtryfinally;
}
}
/****************************************************************************************/
/*////////////////////////////////////////////////////////////////////////////////////////
// NESTED VARIABLE HELPERS