in plugins/experimental/wasm/lib/src/wasmedge/wasmedge.cc [502:552]
void WasmEdge::getModuleFunctionImpl(std::string_view function_name,
std::function<void(ContextBase *, Args...)> *function) {
auto *func_cxt = WasmEdge_ModuleInstanceFindFunction(
module_.get(), WasmEdge_StringWrap(function_name.data(), function_name.length()));
if (!func_cxt) {
*function = nullptr;
return;
}
std::vector<enum WasmEdge_ValType> exp_args;
std::vector<enum WasmEdge_ValType> exp_returns;
convArgsTupleToValTypes<std::tuple<Args...>>(exp_args);
convArgsTupleToValTypes<std::tuple<>>(exp_returns);
const auto *functype_cxt = WasmEdge_FunctionInstanceGetFunctionType(func_cxt);
std::vector<enum WasmEdge_ValType> act_args(
WasmEdge_FunctionTypeGetParametersLength(functype_cxt));
std::vector<enum WasmEdge_ValType> act_returns(
WasmEdge_FunctionTypeGetReturnsLength(functype_cxt));
WasmEdge_FunctionTypeGetParameters(functype_cxt, act_args.data(), act_args.size());
WasmEdge_FunctionTypeGetReturns(functype_cxt, act_returns.data(), act_returns.size());
if (exp_args != act_args || exp_returns != act_returns) {
fail(FailState::UnableToInitializeCode,
"Bad function signature for: " + std::string(function_name) +
", want: " + printValTypes(exp_args.data(), exp_args.size()) + " -> " +
printValTypes(exp_returns.data(), exp_returns.size()) +
", but the module exports: " + printValTypes(act_args.data(), act_args.size()) +
" -> " + printValTypes(act_returns.data(), act_returns.size()));
return;
}
*function = [function_name, func_cxt, this](ContextBase *context, Args... args) -> void {
WasmEdge_Value params[] = {makeVal(args)...};
const bool log = cmpLogLevel(LogLevel::trace);
if (log) {
integration()->trace("[host->vm] " + std::string(function_name) + "(" +
printValues(params, sizeof...(Args)) + ")");
}
SaveRestoreContext saved_context(context);
WasmEdge_Result res =
WasmEdge_ExecutorInvoke(executor_.get(), func_cxt, params, sizeof...(Args), nullptr, 0);
if (!WasmEdge_ResultOK(res)) {
fail(FailState::RuntimeError, "Function: " + std::string(function_name) +
" failed: " + WasmEdge_ResultGetMessage(res));
return;
}
if (log) {
integration()->trace("[host<-vm] " + std::string(function_name) + " return: void");
}
};
}