I'm trying to get MCJIT working but I get the following errors:
Full-featured argument passing not supported yet!
UNREACHABLE executed at MCJIT.cpp:322!
I'm sure the first one will be a problem, but the second one prevents me
from testing anything. I don't know how to fix the problem.
My code works when using the non-MC JIT, and I added to my EngineBuilder:
Reading from a tutorial* I also tried finalizing the engine object:
I'd like to get this working since in the release notes for 3.4 it
indicates exception handling has been removed from the old JIT. I need
exception handling support and would like to get MCJIT working prior to
upgrading to 3.4 later.
MCJIT::runFunction supports only main-style argument passing but not other cases like the JIT.
These types of arguments will work:
(int, char**, char**)
The general case is not supported since it requires creating a small stub function, compiling and running it on the fly, supported by JIT but not MCJIT.
However, with the supported calling sequences, you can probably replace the char** with a void* to a structure so that practically anything can be passed to your function inside the structure.
That makes it more mysterious then since I am indeed only calling a main
function. Perhaps I have to invoke it a different way. Here's my call I
auto main = linker->getModule()->getFunction( "main" );
args.IntVal = llvm::APInt( platform::abi_int_size, 0 );
args.PointerVal = nullptr;
llvm::GenericValue gv = ee->runFunction( main, args );
Something must be wrong with the Function Type. Try to debug into runFunction to see which if condition fails.
Just a guess, if this is on 64 bit system the first argument type may be int64 but needs to be int32.
It was the return type which was i64. I changed it also to my
abi_int_size and it works now. I have to take care of a few other type
translations, but it looks like MCJIT is working now.
Since you know the argument types you can hardcode your own runFunction with the specific types.
You don’t have to go through GenericValues at all, just get the pointer to function and call it with the correct input types.
For example, the code to run int F(int) is:
void *FPtr = getPointerToFunction(F);
assert(FPtr && “Pointer to fn’s code was null after getPointerToFunction”);
int (PF)(int) = (int()(int))(intptr_t)FPtr;
OutputInt = PF(InputInt);