void Wamr::getModuleFunctionImpl()

in plugins/experimental/wasm/lib/src/wamr/wamr.cc [633:683]


void Wamr::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 {
    wasm_val_t params_arr[] = {makeVal(args)...};
    const wasm_val_vec_t params = WASM_ARRAY_VEC(params_arr);
    wasm_val_t results_arr[1];
    wasm_val_vec_t results = WASM_ARRAY_VEC(results_arr);
    const bool log = cmpLogLevel(LogLevel::trace);
    if (log) {
      integration()->trace("[host->vm] " + std::string(function_name) + "(" + printValues(&params) +
                           ")");
    }
    SaveRestoreContext saved_context(context);
    WasmTrapPtr trap{wasm_func_call(func, &params, &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;
  };
};