[LLVMdev] Using JIT code to code a program to call C++

Paul J. Lucas paul at lucasmail.org
Wed Mar 14 17:02:37 PDT 2012


My project has a C++ library that I want to allow the user to use via some programming language to be JIT'd to call functions in said library.  For the sake of simplicity, assume the library has classes like:

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

I'm aware that LLVM doesn't know anything about C++ and that one way to call C++ functions is to wrap them in C thunks:

	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"

The first problem is how to allocate an item from LLVM.  I know how to create StructTypes and add fields to them, but I don't have to have to parallel the C++ class layout -- that's tedious and error-prone.

The idea I got was simply to add a char[sizeof(T)] as the only field to a StructType for a C++ class type:

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

I would think that, because it's a StructType, the alignment would be correct and the sizeof(item) would get the size right.  Will that work?  Is there a better way?

The second problem is that, unlike the C++ class hierarchy, there's no inheritance relationship between StructTypes.  If I create a Function that takes an llvm_iterator_type but try to build a Function object using an llvm_singleton_iterator_type, the LLVM verifyModule() function complains at me:

> Call parameter type does not match function signature!

So then I thought I'd simply use void* everywhere:

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

but verifyModule() still complains at me because, apparently, there's no automatic casting to void* types in LLVM.  How can I solve this problem?

- Paul





More information about the llvm-dev mailing list