我已经创建了一个通过invoke调用另一个Bar2的基本函数Foo1。展开清理基本块中的第一条指令必须是着陆垫:
void bar2()
{
throw;
}
llvm::Function* Bar2Fn = llvm::Function::Create( voidSig , &bar2);
engine->addGlobalMapping( Bar2Fn, (void*)&bar2 );
llvm::InvokeInst* inv = builder.CreateInvoke( Bar2Fn , continueBlock, unwindBlock, llvmArgValues , "invoke");
builder.CreateBr(continueBlock);
builder.SetInsertPoint(unwindBlock);
llvm::LandingPadInst* landPadInst = builder.CreateLandingPad(...);
//add some cleanup code? where??老实说,我不知道我需要在CreateLandingPad的参数之间放些什么,以便获得一个为当前Foo1堆栈对象调用自定义清理代码的基本着陆台。Bar2可能通过调用本身抛出(或重新抛出现有异常)的c++函数抛出。
发布于 2012-11-06 23:00:49
我承认我在这里几乎没有经验,但是你看过异常演示代码示例吗?它似乎包含了您希望找到的序列类型。
基本上,您首先将个性设置为与C++中的行为类似:
llvm::Function *personality = module.getFunction("__gxx_personality_v0");然后创建具有该个性的登陆板,并定义其类型:
llvm::LandingPadInst *caughtResult =
builder.CreateLandingPad(ourCaughtResultType,
personality,
numExceptionsToCatch,
"landingPad");设置要捕获的类型:
for (unsigned i = 0; i < numExceptionsToCatch; ++i) {
// Set up type infos to be caught
caughtResult->addClause(module.getGlobalVariable(
ourTypeInfoNames[exceptionTypesToCatch[i]]));
}并表示它是一个清理处理程序:
caughtResult->setCleanup(true);我相信就是这样;现在你可以得到异常本身了:
llvm::Value *unwindException = builder.CreateExtractValue(caughtResult, 0);从中提取这些代码段的ExceptionDemo.cpp文件包含一个更完整的序列;具体地说,它展示了如何检查捕获的异常的类型根,并在匹配某些内容时分支到特定块-您的清理代码-:
llvm::Value *retTypeInfoIndex = builder.CreateExtractValue(caughtResult, 1);
// FIXME: Redundant storage which, beyond utilizing value of
// caughtResultStore for unwindException storage, may be alleviated
// altogether with a block rearrangement
builder.CreateStore(caughtResult, caughtResultStorage);
builder.CreateStore(unwindException, exceptionStorage);
builder.CreateStore(ourExceptionThrownState, exceptionCaughtFlag);
// Retrieve exception_class member from thrown exception
// (_Unwind_Exception instance). This member tells us whether or not
// the exception is foreign.
llvm::Value *unwindExceptionClass =
builder.CreateLoad(builder.CreateStructGEP(
builder.CreatePointerCast(unwindException,
ourUnwindExceptionType->getPointerTo()),
0));
// Branch to the externalExceptionBlock if the exception is foreign or
// to a catch router if not. Either way the finally block will be run.
builder.CreateCondBr(builder.CreateICmpEQ(unwindExceptionClass,
llvm::ConstantInt::get(builder.getInt64Ty(),
ourBaseExceptionClass)),
exceptionRouteBlock,
externalExceptionBlock);最后,还有一个额外的例子,以及解释,是可用的on the blog post that introduced the new exception handling mechanism。
https://stackoverflow.com/questions/13166552
复制相似问题