Mercurial > projects > ldc
changeset 612:d97b017a8aef
Fix issue with EH table indices and nested try-catch.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sun, 21 Sep 2008 17:18:35 +0200 |
parents | 83ca663ecc20 |
children | 19cbc612380a |
files | ir/irlandingpad.cpp ir/irlandingpad.h |
diffstat | 2 files changed, 24 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/ir/irlandingpad.cpp Sun Sep 21 14:45:41 2008 +0200 +++ b/ir/irlandingpad.cpp Sun Sep 21 17:18:35 2008 +0200 @@ -30,8 +30,6 @@ gIR->ir->CreateBr(end); assert(catchstmt->type); - //TODO: Is toBasetype correct here? Should catch handlers with typedefed - // classes behave differently? catchType = catchstmt->type->toBasetype()->isClassHandle(); assert(catchType); DtoForceDeclareDsymbol(catchType); @@ -96,17 +94,11 @@ // build selector arguments LLSmallVector<LLValue*, 6> selectorargs; - selectorargs.push_back(eh_ptr); - llvm::Function* personality_fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_eh_personality"); - LLValue* personality_fn_arg = gIR->ir->CreateBitCast(personality_fn, getPtrToType(LLType::Int8Ty)); - selectorargs.push_back(personality_fn_arg); - + // put in classinfos in the right order bool hasFinally = false; - // associate increasing ints with each unique classdecl encountered - std::map<ClassDeclaration*, int> catchToInt; - std::deque<IRLandingPadInfo>::reverse_iterator it = infos.rbegin(), end = infos.rend(); - for(size_t i = infos.size() - 1; it != end; ++it, --i) + std::deque<IRLandingPadInfo>::iterator it = infos.begin(), end = infos.end(); + for(; it != end; ++it) { if(it->finallyBody) hasFinally = true; @@ -114,17 +106,26 @@ { if(catchToInt.find(it->catchType) == catchToInt.end()) { - int newval = catchToInt.size(); + int newval = 1 + catchToInt.size(); catchToInt[it->catchType] = newval; } assert(it->catchType); assert(it->catchType->ir.irStruct); - selectorargs.push_back(it->catchType->ir.irStruct->classInfo); + selectorargs.insert(selectorargs.begin(), it->catchType->ir.irStruct->classInfo); } } // if there's a finally, the eh table has to have a 0 action if(hasFinally) selectorargs.push_back(llvm::ConstantInt::get(LLType::Int32Ty, 0)); + + // personality fn + llvm::Function* personality_fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_eh_personality"); + LLValue* personality_fn_arg = gIR->ir->CreateBitCast(personality_fn, getPtrToType(LLType::Int8Ty)); + selectorargs.insert(selectorargs.begin(), personality_fn_arg); + + // eh storage target + selectorargs.insert(selectorargs.begin(), eh_ptr); + // if there is a catch and some catch allocated storage, store exception object if(catchToInt.size() && catch_var) { @@ -143,10 +144,11 @@ // emit finallys and switches that branch to catches until there are no more catches // then simply branch to the finally chain llvm::SwitchInst* switchinst = NULL; - for(it = infos.rbegin(); it != end; ++it) + std::deque<IRLandingPadInfo>::reverse_iterator rit, rend = infos.rend(); + for(rit = infos.rbegin(); rit != rend; ++rit) { // if it's a finally, emit its code - if(it->finallyBody) + if(rit->finallyBody) { if(switchinst) switchinst = NULL; @@ -154,7 +156,7 @@ // since this may be emitted multiple times // give the labels a new scope gIR->func()->pushUniqueLabelScope("finally"); - it->finallyBody->toIR(gIR); + rit->finallyBody->toIR(gIR); gIR->func()->popLabelScope(); } // otherwise it's a catch and we'll add a switch case @@ -165,11 +167,12 @@ switchinst = gIR->ir->CreateSwitch(eh_sel, llvm::BasicBlock::Create("switchdefault", gIR->topfunc(), gIR->scopeend()), infos.size()); gIR->scope() = IRScope(switchinst->getDefaultDest(), gIR->scopeend()); } + // dubious comment // catches matched first get the largest switchval, so do size - unique int - llvm::ConstantInt* switchval = llvm::ConstantInt::get(DtoSize_t(), catchToInt.size() - catchToInt[it->catchType]); + llvm::ConstantInt* switchval = llvm::ConstantInt::get(DtoSize_t(), catchToInt[rit->catchType]); // and make sure we don't add the same switchval twice, may happen with nested trys if(!switchinst->findCaseValue(switchval)) - switchinst->addCase(switchval, it->target); + switchinst->addCase(switchval, rit->target); } }
--- a/ir/irlandingpad.h Sun Sep 21 14:45:41 2008 +0200 +++ b/ir/irlandingpad.h Sun Sep 21 17:18:35 2008 +0200 @@ -73,6 +73,9 @@ // the target for invokes std::stack<llvm::BasicBlock*> padBBs; + // associate increasing ints with each unique classdecl encountered + std::map<ClassDeclaration*, int> catchToInt; + // storage for the catch variable LLValue* catch_var; };