2013-11-18 5 views
1

Я пытаюсь вызвать метод для объекта из моего скомпилированного JIT-кода 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); 
} 

Любая помощь будет принята с благодарностью.

ответ

1

Кажется мне, как ваш вопрос можно подвести итог:

Как преобразовать некоторый указатель на объект в моем коде на LLVM Value?

И ваш подход правильный - создайте константу int со значением указателя как отлитого от целого. Ваша ошибка - это просто неправильное использование конструктора - и на самом деле для начала вам не нужен APInt, вы можете просто сделать ConstantInt::get(context, (uintptr_t)this) (что работает, строя собственно , как вы можете видеть в its implementation).

+0

Ах, отлично! Спасибо за вашу помощь! – Shootfast

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); 

Это гарантирует, что размер указателя всегда был правильным для скомпилированного платформы.

Смежные вопросы