【问题标题】:Using LLVM JIT code to encode a program to call C++ code使用 LLVM JIT 代码对程序进行编码以调用 C++ 代码
【发布时间】:2012-03-15 00:23:25
【问题描述】:

我的项目有一个 C++ 库,我希望允许用户通过某种编程语言使用它,以便 JIT 调用所述库中的函数。为简单起见,假设该库具有如下类:

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 );
  // ...
};

我知道 LLVM 对 C++ 一无所知,调用 C++ 函数的一种方法是将它们包装在 C thunk 中:

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。我知道如何创建 StructTypes 并向它们添加字段,但我不想让 C++ 类布局并行——这很乏味且容易出错。

我的想法只是将char[sizeof(T)] 作为唯一字段添加到 C++ 类类型的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 );

我认为,因为它是StructType,所以对齐方式是正确的,sizeof(item) 的大小会正确。那行得通吗?有没有更好的办法?

第二个问题是,与 C++ 类层次结构不同,StructTypes 之间没有继承关系。如果我创建了一个 Function 接受 llvm_iterator_type 但尝试使用 llvm_singleton_iterator_type 构建 Function 对象,LLVM verifyModule() 函数会向我抱怨:

调用参数类型与函数签名不匹配!

所以我想我会在任何地方都使用void*

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

但是verifyModule() 仍然在抱怨我,因为显然在 LLVM 中没有自动转换为 void* 类型。我该如何解决这个问题?

【问题讨论】:

    标签: c++ llvm jit


    【解决方案1】:

    事实证明,使用char[sizeof(T)] 是使StructTypes 成为正确大小的合理方法——至少LLVM 邮件列表中的另一个人会这样做。

    至于“调用参数类型与函数签名不匹配!”错误,解决方案就是让所有 thunk 使用 void* 并在内部使用 static_casts。将参数传递给 thunk 时,请使用 CreateBitCast() IRBuilder 函数(因为 casts-tovoid 在 LLVM 中不是自动的)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-06
      • 1970-01-01
      • 2021-06-28
      • 1970-01-01
      • 2011-02-17
      • 1970-01-01
      • 1970-01-01
      • 2011-05-24
      相关资源
      最近更新 更多