forked from WasmEdge/WasmEdge
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Rust] Introduced new host function storing design for the single-thr…
…ead scenario (WasmEdge#1648) * [Rust][feat](lib): Introduced global variable for storing non-thread-safe host functions. * [Rust][feat](function): Implemented new API. * [Rust][feat](examples): Added new example. * [Rust][refactor](vm): Refactored APIs. * [Rust SDK][feat](function, import): Introduced new APIs for storing single-thread host functions. * [Rust SDK][feat](examples): Added new example. * [Rust][fix](lib): Fixed review issue. Signed-off-by: Xin Liu <[email protected]>
- Loading branch information
Showing
10 changed files
with
355 additions
and
10 deletions.
There are no files selected for viewing
75 changes: 75 additions & 0 deletions
75
bindings/rust/wasmedge-sdk/examples/hostfunc_call_chain.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
//! This example demonstrates how to implement hostfunc call chaining, namely call | ||
//! another hostfunc in the current hostfunc. | ||
//! | ||
//! To run this example, use the following command: | ||
//! | ||
//! ```bash | ||
//! cd /wasmedge-root-dir/bindings/rust/ | ||
//! | ||
//! cargo run -p wasmedge-sdk --example hostfunc_call_chain -- --nocapture | ||
//! ``` | ||
//! | ||
//! The following info will be printed out in the terminal: | ||
//! | ||
//! ```bash | ||
//! There is layer1! | ||
//! There is layer2! | ||
//! ``` | ||
use std::sync::{Arc, Mutex}; | ||
use wasmedge_sdk::{params, ImportObjectBuilder, Module, Vm, WasmValue}; | ||
use wasmedge_types::wat2wasm; | ||
|
||
struct Wrapper(*const Vm); | ||
unsafe impl Send for Wrapper {} | ||
|
||
#[cfg_attr(test, test)] | ||
fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
let vm = Vm::new(None)?; | ||
|
||
let host_layer1 = |_: Vec<WasmValue>| -> Result<Vec<WasmValue>, u8> { | ||
println!("There is layer1!"); | ||
Ok(vec![]) | ||
}; | ||
|
||
let s = Arc::new(Mutex::new(Wrapper(&vm as *const Vm))); | ||
let host_layer2 = move |_: Vec<WasmValue>| -> Result<Vec<WasmValue>, u8> { | ||
unsafe { | ||
(*s.lock().unwrap().0) | ||
.run_func(None, "layer1", params!()) | ||
.unwrap(); | ||
} | ||
println!("There is layer2!"); | ||
Ok(vec![]) | ||
}; | ||
|
||
let import = ImportObjectBuilder::new() | ||
.with_func_single_thread::<(), ()>("layer1", host_layer1)? | ||
.with_func_single_thread::<(), ()>("layer2", host_layer2)? | ||
.build("host")?; | ||
|
||
let vm = vm.register_import_module(import)?; | ||
|
||
let wasm_bytes = wat2wasm( | ||
br#" | ||
(module | ||
(import "host" "layer1" (func $host_layer1)) | ||
(import "host" "layer2" (func $host_layer2)) | ||
(func (export "layer1") | ||
call $host_layer1) | ||
(func (export "layer2") | ||
call $host_layer2) | ||
) | ||
"#, | ||
)?; | ||
|
||
let module = Module::from_bytes(None, wasm_bytes)?; | ||
|
||
// register the wasm module into vm | ||
let vm = vm.register_module(None, module)?; | ||
|
||
vm.run_func(None, "layer2", params!())?; | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
bindings/rust/wasmedge-sys/examples/call_hostfunc_chain.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
//! This example demonstrates how to implement hostfunc call chaining, namely call | ||
//! another hostfunc in the current hostfunc. | ||
//! | ||
//! To run this example, use the following command: | ||
//! | ||
//! ```bash | ||
//! cd /wasmedge-root-dir/bindings/rust/ | ||
//! | ||
//! cargo run -p wasmedge-sys --example call_hostfunc_chain -- --nocapture | ||
//! ``` | ||
//! | ||
//! The following info will be printed out in the terminal: | ||
//! | ||
//! ```bash | ||
//! There is layer1! | ||
//! There is layer2! | ||
//! ``` | ||
use std::sync::{Arc, Mutex}; | ||
use wasmedge_sys::*; | ||
use wasmedge_types::wat2wasm; | ||
|
||
struct Wrapper(*const Vm); | ||
unsafe impl Send for Wrapper {} | ||
|
||
#[cfg_attr(test, test)] | ||
fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
let wasm_bytes = wat2wasm( | ||
br#" | ||
(module | ||
(import "host" "layer1" (func $host_layer1)) | ||
(import "host" "layer2" (func $host_layer2)) | ||
(func (export "layer1") | ||
call $host_layer1) | ||
(func (export "layer2") | ||
call $host_layer2) | ||
) | ||
"#, | ||
)?; | ||
|
||
let mut vm = Vm::create(None, None)?; | ||
vm.load_wasm_from_bytes(&wasm_bytes)?; | ||
vm.validate()?; | ||
|
||
let host_layer1 = |_: Vec<WasmValue>| -> Result<Vec<WasmValue>, u8> { | ||
println!("There is layer1!"); | ||
Ok(vec![]) | ||
}; | ||
|
||
let s = Arc::new(Mutex::new(Wrapper(&vm as *const Vm))); | ||
let host_layer2 = move |_: Vec<WasmValue>| -> Result<Vec<WasmValue>, u8> { | ||
unsafe { | ||
(*s.lock().unwrap().0).run_function("layer1", []).unwrap(); | ||
} | ||
println!("There is layer2!"); | ||
Ok(vec![]) | ||
}; | ||
|
||
let func_ty = FuncType::create(vec![], vec![]).unwrap(); | ||
let host_layer1 = Function::create_single_thread(&func_ty, Box::new(host_layer1), 0)?; | ||
let host_layer2 = Function::create_single_thread(&func_ty, Box::new(host_layer2), 0)?; | ||
|
||
let mut import = ImportModule::create("host")?; | ||
import.add_func("layer1", host_layer1); | ||
import.add_func("layer2", host_layer2); | ||
|
||
vm.register_wasm_from_import(ImportObject::Import(import))?; | ||
vm.instantiate()?; | ||
|
||
vm.run_function("layer2", [])?; | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.