私のプロジェクトには、あるライブラリを使用して、そのライブラリの関数を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*
を使用しようと思いました。どうすればこの問題を解決できますか?