2012-03-15 4 views
4

私のプロジェクトには、あるライブラリを使用して、そのライブラリの関数をJITするためのC++ライブラリがあります。LLVM JITコードを使用してC++コードを呼び出すプログラムをエンコードする

:私はLLVMがC++については何も知らないとC++の関数を呼び出すための1つの方法は、Cサンクでそれらをラップすることであることを認識してい

class item { 
public: 
    item(); 
    item(int); 
    ~item(); 
    // ... 
}; 

class item_iterator { 
public: 
    virtual ~item_iterator(); 
    virtual bool next(item *result) = 0; 
}; 

class singleton_iterator : public item_iterator { 
public: 
    singleton_iterator(item const &i); 
    // ... 
}; 

:簡略化のために、ライブラリーを想定などのクラスがあります

extern "C" { 

    void thunk_item_M_new(item *addr) { 
    new(addr) item; 
    } 

    void thunk_singleton_iterator_M_new(singleton_iterator *addr, item *i) { 
    new(addr) singleton_iterator(*i); 
    } 

    bool thunk_iterator_M_next(item_iterator *that, item *result) { 
    return that->next(result); 
    } 

} // extern "C" 

最初の問題は、LLVMからitemを割り当てる方法です。私はStructTypeを作成し、それらにフィールドを追加する方法を知っていますが、C++クラスのレイアウトを並列化する必要はありません。これは退屈でエラーが発生しやすいです。

私が得たアイデアは、C++クラス型のためStructTypeへの唯一のフィールドとしてchar[sizeof(T)]を追加するだけだった:私はそれはStructTypeだから、アライメントが正しいだろう、と思うだろう

StructType *const llvm_item_type = StructType::create(llvm_ctx, "item"); 
vector<Type*> llvm_struct_types; 
llvm_struct_types.push_back(ArrayType::get(IntegerType::get(llvm_ctx, 8), sizeof(item))); 
llvm_item_type->setBody(llvm_struct_types, false); 
PointerType *const llvm_item_ptr_type = PointerType::getUnqual(llvm_item_type); 

sizeof(item)はサイズを正しく取得します。それは働くだろうか?より良い方法がありますか?

第2の問題は、C++クラス階層とは異なり、StructTypeの間に継承関係がないことです。私はllvm_iterator_typeかかりますが、llvm_singleton_iterator_typeを使用してFunctionオブジェクトを構築しようFunctionを作成する場合は、LLVM verifyModule()機能は私に文句を言う:

コールパラメータの型は、関数のシグネチャと一致していません!

Type *const llvm_void_type = Type::getVoidTy(llvm_ctx); 
PointerType *const llvm_void_ptr_type = PointerType::getUnqual(llvm_void_type); 

しかしverifyModule()はまだ私に文句を言い、明らかに、LLVMでvoid*タイプへの自動キャストはありませんので:

だから、私は、私は単にどこでもvoid*を使用しようと思いました。どうすればこの問題を解決できますか?

答えて

5

char[sizeof(T)]を使用することは、StructTypeが正しいサイズになることが合理的な方法であることが判明しました。少なくともLLVMメーリングリストの他の人がこれを行います。

「コールパラメータタイプが関数シグネチャと一致しません!」エラーは、単にすべてのサンクにvoid*を使用し、内部にstatic_castを使用することです。引数をサンクに渡すときは、voidへのキャストはLLVMでは自動ではないので、CreateBitCast()IRBuilder関数を使用してください。

関連する問題