From 3eefa3cba106e93f80501c817afcbe94b897d2c1 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Wed, 18 Jan 2023 23:57:29 +0800 Subject: [PATCH] feat: update examples --- __wasm/wasmtime/examples/example1.rs | 2 +- __wasm/wasmtime/examples/example2.rs | 4 +- __wasm/wasmtime/examples/example3.rs | 76 +++++++++++++++++++--------- 3 files changed, 54 insertions(+), 28 deletions(-) diff --git a/__wasm/wasmtime/examples/example1.rs b/__wasm/wasmtime/examples/example1.rs index 10fb87a..ad3c5f9 100644 --- a/__wasm/wasmtime/examples/example1.rs +++ b/__wasm/wasmtime/examples/example1.rs @@ -28,7 +28,7 @@ fn main() -> Result<()> { // this case we're using `4` for. let mut store = Store::new(&engine, 4); let instance = linker.instantiate(&mut store, &module)?; - let hello = instance.get_typed_func::<(), (), _>(&mut store, "hello")?; + let hello = instance.get_typed_func::<(), ()>(&mut store, "hello")?; // And finally we can call the wasm! hello.call(&mut store, ())?; diff --git a/__wasm/wasmtime/examples/example2.rs b/__wasm/wasmtime/examples/example2.rs index ce9e455..370f141 100644 --- a/__wasm/wasmtime/examples/example2.rs +++ b/__wasm/wasmtime/examples/example2.rs @@ -38,11 +38,11 @@ fn main() -> Result<()> { // println!("memory size: {}", memory.size(&store)); let msg = "hatter".as_bytes(); - let malloc_fn = instance.get_typed_func::(&mut store, "__wbindgen_malloc")?; + let malloc_fn = instance.get_typed_func::(&mut store, "__wbindgen_malloc")?; let msg_ptr = malloc_fn.call(&mut store, msg.len() as i32)?; memory.write(&mut store, msg_ptr as usize, msg)?; - let greet_fn = instance.get_typed_func::<(i32, i32), (), _>(&mut store, "greet")?; + let greet_fn = instance.get_typed_func::<(i32, i32), ()>(&mut store, "greet")?; greet_fn.call(&mut store, (msg_ptr, msg.len() as i32))?; Ok(()) diff --git a/__wasm/wasmtime/examples/example3.rs b/__wasm/wasmtime/examples/example3.rs index 0ae8118..8ea3858 100644 --- a/__wasm/wasmtime/examples/example3.rs +++ b/__wasm/wasmtime/examples/example3.rs @@ -1,37 +1,63 @@ use anyhow::Result; use wasmtime::*; +struct MyState { + name: String, + count: usize, +} + fn main() -> Result<()> { - // Modules can be compiled through either the text or binary format + // First the wasm module needs to be compiled. This is done with a global + // "compilation environment" within an `Engine`. Note that engines can be + // further configured through `Config` if desired instead of using the + // default like this is here. + println!("Compiling module..."); let engine = Engine::default(); - let wat = r#" - (module - (import "host" "hello" (func $host_hello (param i32))) + let module = Module::new(&engine, r#" + (module + (func $hello (import "" "hello")) + (func (export "run") (call $hello)) + )"#).unwrap(); - (func (export "hello") - i32.const 3 - call $host_hello) - ) - "#; - let module = Module::new(&engine, wat)?; + // After a module is compiled we create a `Store` which will contain + // instantiated modules and other items like host functions. A Store + // contains an arbitrary piece of host information, and we use `MyState` + // here. + println!("Initializing..."); + let mut store = Store::new( + &engine, + MyState { + name: "hello, world!".to_string(), + count: 0, + }, + ); - // Create a `Linker` which will be later used to instantiate this module. - // Host functionality is defined by name within the `Linker`. - let mut linker = Linker::new(&engine); - linker.func_wrap("host", "hello", |caller: Caller<'_, u32>, param: i32| { - println!("Got {} from WebAssembly", param); - println!("my host state is: {}", caller.data()); - })?; + // Our wasm module we'll be instantiating requires one imported function. + // the function takes no parameters and returns no results. We create a host + // implementation of that function here, and the `caller` parameter here is + // used to get access to our original `MyState` value. + println!("Creating callback..."); + let hello_func = Func::wrap(&mut store, |mut caller: Caller<'_, MyState>| { + println!("Calling back..."); + println!("> {}", caller.data().name); + caller.data_mut().count += 1; + }); - // All wasm objects operate within the context of a "store". Each - // `Store` has a type parameter to store host-specific data, which in - // this case we're using `4` for. - let mut store = Store::new(&engine, 4); - let instance = linker.instantiate(&mut store, &module)?; - let hello = instance.get_typed_func::<(), ()>(&mut store, "hello")?; + // Once we've got that all set up we can then move to the instantiation + // phase, pairing together a compiled module as well as a set of imports. + // Note that this is where the wasm `start` function, if any, would run. + println!("Instantiating module..."); + let imports = [hello_func.into()]; + let instance = Instance::new(&mut store, &module, &imports)?; - // And finally we can call the wasm! - hello.call(&mut store, ())?; + // Next we poke around a bit to extract the `run` function from the module. + println!("Extracting export..."); + let run = instance.get_typed_func::<(), ()>(&mut store, "run")?; + // And last but not least we can call it! + println!("Calling export..."); + run.call(&mut store, ())?; + + println!("Done."); Ok(()) } \ No newline at end of file