in plugins/experimental/wasm/lib/src/wasmtime/wasmtime.cc [632:694]
void Wasmtime::getModuleFunctionImpl(std::string_view function_name,
std::function<R(ContextBase *, Args...)> *function) {
auto it = module_functions_.find(std::string(function_name));
if (it == module_functions_.end()) {
*function = nullptr;
return;
}
WasmValtypeVec exp_args;
WasmValtypeVec exp_returns;
convertArgsTupleToValTypes<std::tuple<Args...>>(exp_args.get());
convertArgsTupleToValTypes<std::tuple<R>>(exp_returns.get());
wasm_func_t *func = it->second.get();
WasmFunctypePtr func_type = wasm_func_type(func);
if (!equalValTypes(wasm_functype_params(func_type.get()), exp_args.get()) ||
!equalValTypes(wasm_functype_results(func_type.get()), exp_returns.get())) {
fail(FailState::UnableToInitializeCode,
"Bad function signature for: " + std::string(function_name) + ", want: " +
printValTypes(exp_args.get()) + " -> " + printValTypes(exp_returns.get()) +
", but the module exports: " + printValTypes(wasm_functype_params(func_type.get())) +
" -> " + printValTypes(wasm_functype_results(func_type.get())));
return;
}
*function = [func, function_name, this](ContextBase *context, Args... args) -> R {
const bool log = cmpLogLevel(LogLevel::trace);
SaveRestoreContext saved_context(context);
wasm_val_t results_arr[1];
wasm_val_vec_t results = WASM_ARRAY_VEC(results_arr);
WasmTrapPtr trap;
// Workaround for MSVC++ not supporting zero-sized arrays.
if constexpr (sizeof...(args) > 0) {
wasm_val_t params_arr[] = {makeVal(args)...};
wasm_val_vec_t params = WASM_ARRAY_VEC(params_arr);
if (log) {
integration()->trace("[host->vm] " + std::string(function_name) + "(" +
printValues(¶ms) + ")");
}
trap.reset(wasm_func_call(func, ¶ms, &results));
} else {
wasm_val_vec_t params = WASM_EMPTY_VEC;
if (log) {
integration()->trace("[host->vm] " + std::string(function_name) + "()");
}
trap.reset(wasm_func_call(func, ¶ms, &results));
}
if (trap) {
WasmByteVec error_message;
wasm_trap_message(trap.get(), error_message.get());
std::string message(error_message.get()->data); // NULL-terminated
fail(FailState::RuntimeError,
"Function: " + std::string(function_name) + " failed: " + message);
return R{};
}
R ret = convertValueTypeToArg<R>(results.data[0]);
if (log) {
integration()->trace("[host<-vm] " + std::string(function_name) +
" return: " + std::to_string(ret));
}
return ret;
};
};