void V8::getModuleFunctionImpl()

in plugins/experimental/wasm/lib/src/v8/v8.cc [600:648]


void V8::getModuleFunctionImpl(std::string_view function_name,
                               std::function<void(ContextBase *, Args...)> *function) {
  auto it = module_functions_.find(std::string(function_name));
  if (it == module_functions_.end()) {
    *function = nullptr;
    return;
  }
  const wasm::Func *func = it->second.get();
  auto arg_valtypes = convertArgsTupleToValTypes<std::tuple<Args...>>();
  auto result_valtypes = convertArgsTupleToValTypes<std::tuple<>>();
  if (!equalValTypes(func->type()->params(), arg_valtypes) ||
      !equalValTypes(func->type()->results(), result_valtypes)) {
    fail(FailState::UnableToInitializeCode,
         "Bad function signature for: " + std::string(function_name) +
             ", want: " + printValTypes(arg_valtypes) + " -> " + printValTypes(result_valtypes) +
             ", but the module exports: " + printValTypes(func->type()->params()) + " -> " +
             printValTypes(func->type()->results()));
    *function = nullptr;
    return;
  }
  *function = [func, function_name, this](ContextBase *context, Args... args) -> void {
    const bool log = cmpLogLevel(LogLevel::trace);
    SaveRestoreContext saved_context(context);
    wasm::own<wasm::Trap> trap = nullptr;

    // Workaround for MSVC++ not supporting zero-sized arrays.
    if constexpr (sizeof...(args) > 0) {
      wasm::Val params[] = {makeVal(args)...};
      if (log) {
        integration()->trace("[host->vm] " + std::string(function_name) + "(" +
                             printValues(params, sizeof...(Args)) + ")");
      }
      trap = func->call(params, nullptr);
    } else {
      if (log) {
        integration()->trace("[host->vm] " + std::string(function_name) + "()");
      }
      trap = func->call(nullptr, nullptr);
    }

    if (trap) {
      fail(FailState::RuntimeError, getFailMessage(std::string(function_name), std::move(trap)));
      return;
    }
    if (log) {
      integration()->trace("[host<-vm] " + std::string(function_name) + " return: void");
    }
  };
}