in plugins/experimental/wasm/lib/src/wasmedge/wasmedge.cc [455:499]
void WasmEdge::registerHostFunctionImpl(std::string_view module_name,
std::string_view function_name, R (*function)(Args...)) {
auto it = host_modules_.find(std::string(module_name));
if (it == host_modules_.end()) {
host_modules_.emplace(module_name, std::make_unique<HostModuleData>(module_name));
it = host_modules_.find(std::string(module_name));
}
auto data = std::make_unique<HostFuncData>(module_name, function_name);
auto *func_type = newWasmEdgeFuncType<R, std::tuple<Args...>>();
data->vm_ = this;
data->raw_func_ = reinterpret_cast<void *>(function);
data->callback_ = [](void *data, const WasmEdge_CallingFrameContext * /*CallFrameCxt*/,
const WasmEdge_Value *Params, WasmEdge_Value *Returns) -> WasmEdge_Result {
auto *func_data = reinterpret_cast<HostFuncData *>(data);
const bool log = func_data->vm_->cmpLogLevel(LogLevel::trace);
if (log) {
func_data->vm_->integration()->trace("[vm->host] " + func_data->modname_ + "." +
func_data->name_ + "(" +
printValues(Params, sizeof...(Args)) + ")");
}
auto args = convValTypesToArgsTuple<std::tuple<Args...>>(Params);
auto fn = reinterpret_cast<R (*)(Args...)>(func_data->raw_func_);
R res = std::apply(fn, args);
Returns[0] = makeVal<R>(res);
if (log) {
func_data->vm_->integration()->trace("[vm<-host] " + func_data->modname_ + "." +
func_data->name_ + " return: " + std::to_string(res));
}
return WasmEdge_Result_Success;
};
auto *hostfunc_cxt = WasmEdge_FunctionInstanceCreate(func_type, data->callback_, data.get(), 0);
WasmEdge_FunctionTypeDelete(func_type);
if (hostfunc_cxt == nullptr) {
fail(FailState::MissingFunction, "Failed to allocate host function instance");
return;
}
WasmEdge_ModuleInstanceAddFunction(
it->second->cxt_, WasmEdge_StringWrap(function_name.data(), function_name.length()),
hostfunc_cxt);
host_functions_.insert_or_assign(std::string(module_name) + "." + std::string(function_name),
std::move(data));
}