There's not much information you get can from compiled_func
- as you wrote, it's just a void*
. But when you write "in general, I do not know what the function signature is", that's not accurate - you've just compiled that function, so you should have access to the LLVM Function
object, which can be queried about its type. It's true that it's an LLVM IR type and not a C++ type, but you can often know which translates to which.
For example, if we borrow code from the tutorial's section on JITting Kaleidoscope:
if (Function *LF = F->Codegen()) {
LF->dump(); // Dump the function for exposition purposes.
// JIT the function, returning a function pointer.
void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
double (*FP)() = (double (*)())(intptr_t)FPtr;
fprintf(stderr, "Evaluated to %f\n", FP());
}
Then yes, FPtr
was "assumed" to be of type double ()
, but there's also LF
of type Function*
here, so you could have done something like:
Type* RetTy = LF->getReturnType();
if (RetTy->isDoubleTy()) {
double (*FP)() = (double (*)())(intptr_t)FPtr;
fprintf(stderr, "Evaluated to %f\n", FP());
} else if (RetTy->isIntegerTy(32)) {
int (*FP)() = (int (*)())(intptr_t)FPtr;
fprintf(stderr, "Evaluated to %d\n", FP());
} else ...
And in much the same way, you can query a function about its parameter types.
A bit cumbersome? You can use your execution engine to invoke the function, via its handy runFunction
method, which receives a vector of GenericValue
s and returns a GenericValue
. You should still query the Function
type to find what the underlying type under each GenericValue
should be.