首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在llvm上编写一个简单的清理登陆台

在llvm上编写一个简单的清理登陆台
EN

Stack Overflow用户
提问于 2012-11-01 03:58:55
回答 1查看 1.7K关注 0票数 12

我已经创建了一个通过invoke调用另一个Bar2的基本函数Foo1。展开清理基本块中的第一条指令必须是着陆垫:

代码语言:javascript
复制
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++函数抛出。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-06 23:00:49

我承认我在这里几乎没有经验,但是你看过异常演示代码示例吗?它似乎包含了您希望找到的序列类型。

基本上,您首先将个性设置为与C++中的行为类似:

代码语言:javascript
复制
llvm::Function *personality = module.getFunction("__gxx_personality_v0");

然后创建具有该个性的登陆板,并定义其类型:

代码语言:javascript
复制
llvm::LandingPadInst *caughtResult = 
  builder.CreateLandingPad(ourCaughtResultType,
                           personality,
                           numExceptionsToCatch,
                           "landingPad");

设置要捕获的类型:

代码语言:javascript
复制
for (unsigned i = 0; i < numExceptionsToCatch; ++i) {
  // Set up type infos to be caught
  caughtResult->addClause(module.getGlobalVariable(
                          ourTypeInfoNames[exceptionTypesToCatch[i]]));
}

并表示它是一个清理处理程序:

代码语言:javascript
复制
caughtResult->setCleanup(true);

我相信就是这样;现在你可以得到异常本身了:

代码语言:javascript
复制
llvm::Value *unwindException = builder.CreateExtractValue(caughtResult, 0);

从中提取这些代码段的ExceptionDemo.cpp文件包含一个更完整的序列;具体地说,它展示了如何检查捕获的异常的类型根,并在匹配某些内容时分支到特定块-您的清理代码-:

代码语言:javascript
复制
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

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13166552

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档