diff --git a/__wasm/wasmtime/examples/gcd.rs b/__wasm/wasmtime/examples/gcd.rs new file mode 100644 index 0000000..1ef876a --- /dev/null +++ b/__wasm/wasmtime/examples/gcd.rs @@ -0,0 +1,46 @@ +use anyhow::Result; +use wasmtime::*; + +// https://docs.wasmtime.dev/examples-rust-gcd.html +fn main() -> Result<()> { + // Load our WebAssembly (parsed WAT in our case), and then load it into a + // `Module` which is attached to a `Store` cache. After we've got that we + // can instantiate it. + let mut store = Store::<()>::default(); + let module = Module::new(store.engine(), r#" + (module + (func $gcd (param i32 i32) (result i32) + (local i32) + block ;; label = @1 + block ;; label = @2 + local.get 0 + br_if 0 (;@2;) + local.get 1 + local.set 2 + br 1 (;@1;) + end + loop ;; label = @2 + local.get 1 + local.get 0 + local.tee 2 + i32.rem_u + local.set 0 + local.get 2 + local.set 1 + local.get 0 + br_if 0 (;@2;) + end + end + local.get 2 + ) + (export "gcd" (func $gcd)) + ) + "#)?; + let instance = Instance::new(&mut store, &module, &[])?; + + // Invoke `gcd` export + let gcd = instance.get_typed_func::<(i32, i32), i32>(&mut store, "gcd")?; + + println!("gcd(6, 27) = {}", gcd.call(&mut store, (6, 27))?); + Ok(()) +} \ No newline at end of file diff --git a/__wasm/wasmtime/examples/memory.rs b/__wasm/wasmtime/examples/memory.rs new file mode 100644 index 0000000..2a58f08 --- /dev/null +++ b/__wasm/wasmtime/examples/memory.rs @@ -0,0 +1,81 @@ +use anyhow::Result; +use wasmtime::*; + +// https://docs.wasmtime.dev/examples-rust-memory.html +fn main() -> Result<()> { + // Create our `store_fn` context and then compile a module and create an + // instance from the compiled module all in one go. + let mut store: Store<()> = Store::default(); + let module = Module::new(store.engine(), r#" + (module + (memory (export "memory") 2 3) + + (func (export "size") (result i32) (memory.size)) + (func (export "load") (param i32) (result i32) + (i32.load8_s (local.get 0)) + ) + (func (export "store") (param i32 i32) + (i32.store8 (local.get 0) (local.get 1)) + ) + + (data (i32.const 0x1000) "\01\02\03\04") + ) + "#)?; + let instance = Instance::new(&mut store, &module, &[])?; + + // load_fn up our exports from the instance + let memory = instance + .get_memory(&mut store, "memory") + .ok_or(anyhow::format_err!("failed to find `memory` export"))?; + let size = instance.get_typed_func::<(), i32>(&mut store, "size")?; + let load_fn = instance.get_typed_func::(&mut store, "load")?; + let store_fn = instance.get_typed_func::<(i32, i32), ()>(&mut store, "store")?; + + println!("Checking memory..."); + assert_eq!(memory.size(&store), 2); + assert_eq!(memory.data_size(&store), 0x20000); + assert_eq!(memory.data_mut(&mut store)[0], 0); + assert_eq!(memory.data_mut(&mut store)[0x1000], 1); + assert_eq!(memory.data_mut(&mut store)[0x1003], 4); + + assert_eq!(size.call(&mut store, ())?, 2); + assert_eq!(load_fn.call(&mut store, 0)?, 0); + assert_eq!(load_fn.call(&mut store, 0x1000)?, 1); + assert_eq!(load_fn.call(&mut store, 0x1003)?, 4); + assert_eq!(load_fn.call(&mut store, 0x1ffff)?, 0); + assert!(load_fn.call(&mut store, 0x20000).is_err()); // out of bounds trap + + println!("Mutating memory..."); + memory.data_mut(&mut store)[0x1003] = 5; + + store_fn.call(&mut store, (0x1002, 6))?; + assert!(store_fn.call(&mut store, (0x20000, 0)).is_err()); // out of bounds trap + + assert_eq!(memory.data(&store)[0x1002], 6); + assert_eq!(memory.data(&store)[0x1003], 5); + assert_eq!(load_fn.call(&mut store, 0x1002)?, 6); + assert_eq!(load_fn.call(&mut store, 0x1003)?, 5); + + // Grow memory. + println!("Growing memory..."); + memory.grow(&mut store, 1)?; + assert_eq!(memory.size(&store), 3); + assert_eq!(memory.data_size(&store), 0x30000); + + assert_eq!(load_fn.call(&mut store, 0x20000)?, 0); + store_fn.call(&mut store, (0x20000, 0))?; + assert!(load_fn.call(&mut store, 0x30000).is_err()); + assert!(store_fn.call(&mut store, (0x30000, 0)).is_err()); + + assert!(memory.grow(&mut store, 1).is_err()); + assert!(memory.grow(&mut store, 0).is_ok()); + + println!("Creating stand-alone memory..."); + let memory_type = MemoryType::new(5, Some(5)); + let memory2 = Memory::new(&mut store, memory_type)?; + assert_eq!(memory2.size(&store), 5); + assert!(memory2.grow(&mut store, 1).is_err()); + assert!(memory2.grow(&mut store, 0).is_ok()); + + Ok(()) +} \ No newline at end of file