From e5126f550a2d264c758b7964280682956b2494ff Mon Sep 17 00:00:00 2001 From: Officeyutong Date: Wed, 22 Mar 2023 03:44:09 +0800 Subject: [PATCH] Add support for user-registered host functions (#89) * Add support for user-registered host functions * format the code --- runtime/wasm-bpf-rs/src/runner.rs | 20 ++++++++++++++---- runtime/wasm-bpf-rs/src/tests/mod.rs | 18 ++++++++++++++++ .../wasm-bpf-rs/tests/custom_host_func.wasm | Bin 0 -> 18536 bytes .../tests/custom_host_func/.gitignore | 1 + .../tests/custom_host_func/Makefile | 6 ++++++ .../tests/custom_host_func/README.md | 3 +++ .../tests/custom_host_func/custom_host_func.c | 10 +++++++++ 7 files changed, 54 insertions(+), 4 deletions(-) create mode 100755 runtime/wasm-bpf-rs/tests/custom_host_func.wasm create mode 100644 runtime/wasm-bpf-rs/tests/custom_host_func/.gitignore create mode 100644 runtime/wasm-bpf-rs/tests/custom_host_func/Makefile create mode 100644 runtime/wasm-bpf-rs/tests/custom_host_func/README.md create mode 100644 runtime/wasm-bpf-rs/tests/custom_host_func/custom_host_func.c diff --git a/runtime/wasm-bpf-rs/src/runner.rs b/runtime/wasm-bpf-rs/src/runner.rs index 365f8f7..03a6e96 100644 --- a/runtime/wasm-bpf-rs/src/runner.rs +++ b/runtime/wasm-bpf-rs/src/runner.rs @@ -1,7 +1,7 @@ use std::sync::mpsc; use anyhow::{anyhow, Context}; -use wasmtime::{Engine, Linker, Module, Store, TypedFunc}; +use wasmtime::{Engine, IntoFunc, Linker, Module, Store, TypedFunc}; use wasmtime_wasi::WasiCtxBuilder; use crate::add_bind_function_with_module; @@ -39,6 +39,7 @@ pub struct WasmBpfModuleRunner { /// The linker which will be used pub linker: Linker, operation_tx: mpsc::Sender, + main_module: Module, } impl WasmBpfModuleRunner { @@ -88,14 +89,12 @@ impl WasmBpfModuleRunner { wrapper_poll::bpf_buffer_poll_wrapper, POLL_WRAPPER_FUNCTION_NAME )?; - linker - .module(&mut store, MAIN_MODULE_NAME, &main_module) - .with_context(|| anyhow!("Failed to link main module"))?; Ok(Self { engine, store, linker, operation_tx: tx, + main_module, }) } /// Consume this runner, return a handle to the wasm program, which can control the pause/resume/terminate of the program @@ -104,6 +103,10 @@ impl WasmBpfModuleRunner { pub fn into_engine_and_entry_func( mut self, ) -> anyhow::Result<(WasmProgramHandle, WasmBpfEntryFuncWrapper)> { + self.linker + .module(&mut self.store, MAIN_MODULE_NAME, &self.main_module) + .with_context(|| anyhow!("Failed to link main module"))?; + let func = self .linker .get(&mut self.store, MAIN_MODULE_NAME, "_start") @@ -119,4 +122,13 @@ impl WasmBpfModuleRunner { }, )) } + /// Register a custom host function. It has the similar signature as `wasmtime::linker::Linker::func_wrap` + pub fn register_host_function( + &mut self, + module: &str, + name: &str, + func: impl IntoFunc, + ) -> anyhow::Result<()> { + self.linker.func_wrap(module, name, func).map(|_| ()) + } } diff --git a/runtime/wasm-bpf-rs/src/tests/mod.rs b/runtime/wasm-bpf-rs/src/tests/mod.rs index c5f4ea7..a1f2e5d 100644 --- a/runtime/wasm-bpf-rs/src/tests/mod.rs +++ b/runtime/wasm-bpf-rs/src/tests/mod.rs @@ -1,5 +1,6 @@ use crate::handle::WasmProgramHandle; use crate::pipe::ReadableWritePipe; +use crate::state::CallerType; use super::*; use std::fs::File; @@ -154,3 +155,20 @@ fn test_pause_and_resume_wasm_program() { assert!(tick_count_3 - tick_count_2 >= 2); handle.as_mut().unwrap().terminate().unwrap(); } + +#[test] +fn test_custom_host_function() { + let module_binary = std::fs::read(get_test_file_path("custom_host_func.wasm")).unwrap(); + let args = vec!["test".to_string()]; + let mut runner = + WasmBpfModuleRunner::new(&module_binary[..], &args[..], Config::default()).unwrap(); + runner + .register_host_function("host_func_test", "plus_i32", host_func_plus_i32) + .unwrap(); + let (_, wrapper) = runner.into_engine_and_entry_func().unwrap(); + wrapper.run().unwrap(); +} + +fn host_func_plus_i32(_caller: CallerType, a: i32, b: i32) -> i32 { + a + b +} diff --git a/runtime/wasm-bpf-rs/tests/custom_host_func.wasm b/runtime/wasm-bpf-rs/tests/custom_host_func.wasm new file mode 100755 index 0000000000000000000000000000000000000000..3165402d9410a177a93146e7c6da27e920a96ed5 GIT binary patch literal 18536 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 F{(n`4_f!A? literal 0 HcmV?d00001 diff --git a/runtime/wasm-bpf-rs/tests/custom_host_func/.gitignore b/runtime/wasm-bpf-rs/tests/custom_host_func/.gitignore new file mode 100644 index 0000000..f00b29a --- /dev/null +++ b/runtime/wasm-bpf-rs/tests/custom_host_func/.gitignore @@ -0,0 +1 @@ +custom_host_func.wasm diff --git a/runtime/wasm-bpf-rs/tests/custom_host_func/Makefile b/runtime/wasm-bpf-rs/tests/custom_host_func/Makefile new file mode 100644 index 0000000..88352a6 --- /dev/null +++ b/runtime/wasm-bpf-rs/tests/custom_host_func/Makefile @@ -0,0 +1,6 @@ +WASI_CLANG = /opt/wasi-sdk/bin/clang +WASI_CFLAGS = -O2 --sysroot=/opt/wasi-sdk/share/wasi-sysroot -Wl,--allow-undefined,--export-table + +custom_host_func.wasm: custom_host_func.c + $(WASI_CLANG) $(WASI_CFLAGS) -o $@ $< + cp custom_host_func.wasm .. diff --git a/runtime/wasm-bpf-rs/tests/custom_host_func/README.md b/runtime/wasm-bpf-rs/tests/custom_host_func/README.md new file mode 100644 index 0000000..e3175f0 --- /dev/null +++ b/runtime/wasm-bpf-rs/tests/custom_host_func/README.md @@ -0,0 +1,3 @@ +# Test program for custom host func + +It invokes a host function to calculate `a+b`, and verifies the result. diff --git a/runtime/wasm-bpf-rs/tests/custom_host_func/custom_host_func.c b/runtime/wasm-bpf-rs/tests/custom_host_func/custom_host_func.c new file mode 100644 index 0000000..1814539 --- /dev/null +++ b/runtime/wasm-bpf-rs/tests/custom_host_func/custom_host_func.c @@ -0,0 +1,10 @@ +#include +#include +__attribute__((import_module("host_func_test"), import_name("plus_i32"))) +int32_t +plus_i32(int32_t a, int32_t b); +int main() { + int32_t c = plus_i32(0xABCD, 0x1234); + assert(c == 0xABCD + 0x1234); + return 0; +}