我正在尝试从已编译的llvm JIT代码中调用对象上的方法。
我已经在这里阅读了答案(Can I bind an existing method to a LLVM Function* and use it from JIT-compiled code?),但我的情况略有不同,因为我的方法需要参数。
如果我正确理解了所有内容,我需要用函数包装我的方法,但是如何将指针存储到我的实例中以作为调用时的第一个参数?
这是一个简短的例子(省略了一些不相关的部分)
class Foo:
{
public:
Foo();
float getValue(char * name);
};
float fooWrap(Foo *foo, char * name)
{
foo->getValue(name);
}
Foo::Foo()
{
// snipped llvm init stuff
std::vector<llvm::Type*> fun_args;
fun_args.push_back(llvm::Type::getInt8Ty(context)); // Pointer to this instance (pretty sure is wrong)
fun_args.push_back(llvm::Type::getInt8PtrTy(context)); // char array *
llvm::FunctionType *FT = llvm::FunctionType::get(llvm::Type::getFloatTy(context), fun_args, false);
llvm::Function * F = llvm::Function::Create(FT, llvm::Function::ExternalLinkage, "foo", module);
engine->addGlobalMapping(F, &fooWrap);
// later
llvm::Value *instance = llvm::ConstantInt::get(context, llvm::APInt((intptr_t) &this)); // wont compile, can't construct APInt from intptr_t
std::vector<llvm::Value*> args;
args.push_back(instance);
args.push_back(builder.CreateGlobalStringPtr("test"));
builder.CreateCall(F, args);
}
非常感谢任何帮助。
答案 0 :(得分:2)
参数类型最终成为:
llvm::Type::getIntNTy(context, sizeof(uintptr_t)*8)
并且值设置为:
llvm::Value *instance = llvm::ConstantInt::get(llvm::Type::getIntNTy(context, sizeof(uintptr_t)*8), (uintptr_t) this);
这确保指针大小始终对编译平台正确。
答案 1 :(得分:1)
在我看来,您的问题可以概括为:
如何将代码中的某些对象指针转换为LLVM
Value
?
你的方法是正确的 - 创建一个常量int,指针的值被转换为一个整数。您的错误只是APInt
构造函数的错误使用 - 实际上您不需要APInt
开头,您可以ConstantInt::get(context, (uintptr_t)this)
(通过构建APInt
本身,正如您在its implementation中看到的那样。)