Reputation: 1978
I'm trying to call a method on an object from inside my compiled llvm JIT code.
I've read the answer here ( Can I bind an existing method to a LLVM Function* and use it from JIT-compiled code? ) but my case is slightly different, as my method requires an argument.
If I'm understanding everything correctly, I need to wrap my method with a function, but how can I store the pointer to my instance to use as the first argument when calling?
Here's a short example (omited some irrelevant parts)
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);
}
Any help would be greatly appreciated.
Upvotes: 1
Views: 1082
Reputation: 1978
The argument type ended up being:
llvm::Type::getIntNTy(context, sizeof(uintptr_t)*8)
And the value was set with:
llvm::Value *instance = llvm::ConstantInt::get(llvm::Type::getIntNTy(context, sizeof(uintptr_t)*8), (uintptr_t) this);
This ensured that the pointer size was always correct for the compiled platform.
Upvotes: 2
Reputation: 26868
Seems to me like your question can be summed up by:
How to convert some object pointer in my code to an LLVM
Value
?
And your approach is correct - create a constant int with the value of the pointer as casted to an integer. Your error is just an incorrect usage of APInt
's constructor - and in fact you don't need an APInt
to start with, you can just do ConstantInt::get(context, (uintptr_t)this)
(which works by constructing an APInt
itself, as you can see in its implementation).
Upvotes: 1