void WasmEdge::getModuleFunctionImpl()

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