函数指针作为参数调用

时间:2014-06-26 11:30:40

标签: llvm

我正在尝试创建对函数foo的调用,该函数接收函数指针(带有签名void bar(void))作为参数。从This帖子我得到了基本的想法来完成这个。 首先我注册Foo功能。 Bar实际上是一个由LLVM编译的函数,因此不需要注册。

FunctionType* BarType =  FunctionType::get(Type::getVoidTy(getGlobalContext()), false);

Type* FooType[1];
FooType[0] = static_cast<Type*>(BarType)->getPointerTo();
ArrayRef<Type*> FooTypeARef(FooType, 1);

FunctionType* signature = FunctionType::get(Type::getInt32Ty(getGlobalContext()), FooTypeARef, false);
Function* func = Function::Create(signature, Function::ExternalLinkage, "Foo", TheModule);
LLVM_ExecutionEngine()->addGlobalMapping(func, const_cast<void*>(&Foo));

这是实际调用的插入方式(案例I

std::vector<Value*> ArgsV_Foo;
Function *FooFun= LLVM_Module()->getFunction("Foo");
Function* BarFun = LLVM_Module()->getFunction("Bar");

ArgsV_Foo.push_back( BarFun );

LLVM_Builder()->CreateCall(FooFun, ArgsV, "calltmp")

但是,这会在CreateCall内部中止,原因是&#34;调用带有错误签名的函数&#34;。我不确定行ArgsV_Foo.push_back( BarFun )是否正确。

对我来说,一种不同的方法是使用ExecutionEngine来获取指向Bar的指针,但我不明白如何将生成的函数指针转换为llvm::Value* Case II

std::vector<Value*> ArgsV_Foo;
Function *FooFun= LLVM_Module()->getFunction("Foo");
Function* BarFun = LLVM_Module()->getFunction("Bar");

void* BarFunPtr = LLVM_ExecutionEngine()->getPointerToFunction(BarFun);
Value* val = ??
ArgsV_FEFork.push_back(val);

LLVM_Builder()->CreateCall(FooFun, ArgsV, "calltmp")

也许有人知道如何完成第二种情况或确认第一种情况下的分配是正确的(问题出在其他地方)。

1 个答案:

答案 0 :(得分:6)

关于第一种情况:

我不太确定那里发生了什么。例如,你为什么要提升BarType?在任何情况下,检查它的一种简单方法是在所涉及的所有类型上调用->dump()并自行检查差异是什么。

另外,请避免在LLVM对象上使用static_cast - there are more canonical ways to cast

解决第二种情况:

  1. 将函数指针(BarFunPtr)转换为整数。
  2. Create a constant integer in LLVM使用(1)的结果作为值。请记住 - 就J代码而言,您在JITted代码之外计算的任何内容都是常量。
  3. 通过inttoptr将(2)中的常量整数转换为指针。指针的类型应该是匹配bar类型的函数指针。
  4. 使用(3)的结果作为通话目标。
  5. 关于ArrayRef s

    最后,仅供参考,有更简单的方法来创建ArrayRef个实例....特别是您可能对its implicit single-element constructor感兴趣: - )