Path: blob/main/crates/wiggle/tests/wasmtime_integration.rs
3088 views
use wasmtime::{Engine, Linker, Module, Store, Val};1use wiggle::GuestMemory;23// from_witx invocation says the func is async. This context doesn't support async!4wiggle::from_witx!({5witx: ["tests/atoms.witx"],6async: {7atoms::{double_int_return_float}8}9});1011pub mod integration {12// The integration invocation says the func is blocking, so it will still work.13wiggle::wasmtime_integration!({14target: crate,15witx: ["tests/atoms.witx"],16block_on: {17atoms::{double_int_return_float}18}19});20}2122pub struct Ctx;23impl wiggle::GuestErrorType for types::Errno {24fn success() -> Self {25types::Errno::Ok26}27}2829impl atoms::Atoms for Ctx {30fn int_float_args(31&mut self,32_: &mut GuestMemory<'_>,33an_int: u32,34an_float: f32,35) -> Result<(), types::Errno> {36println!("INT FLOAT ARGS: {an_int} {an_float}");37Ok(())38}39async fn double_int_return_float(40&mut self,41_: &mut GuestMemory<'_>,42an_int: u32,43) -> Result<types::AliasToFloat, types::Errno> {44Ok((an_int as f32) * 2.0)45}46}4748#[test]49fn test_sync_host_func() {50let engine = Engine::default();51let mut linker = Linker::new(&engine);52integration::add_atoms_to_linker(&mut linker, |cx| cx).unwrap();53let mut store = store(&engine);54let shim_mod = shim_module(&engine);55let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();5657let mut results = [Val::I32(0)];58shim_inst59.get_func(&mut store, "int_float_args_shim")60.unwrap()61.call(&mut store, &[0i32.into(), 123.45f32.into()], &mut results)62.unwrap();6364assert_eq!(65results[0].unwrap_i32(),66types::Errno::Ok as i32,67"int_float_args errno"68);69}7071#[test]72fn test_async_host_func() {73let engine = Engine::default();74let mut linker = Linker::new(&engine);75integration::add_atoms_to_linker(&mut linker, |cx| cx).unwrap();76let mut store = store(&engine);7778let shim_mod = shim_module(&engine);79let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();8081let input: i32 = 123;82let result_location: i32 = 0;8384let mut results = [Val::I32(0)];85shim_inst86.get_func(&mut store, "double_int_return_float_shim")87.unwrap()88.call(89&mut store,90&[input.into(), result_location.into()],91&mut results,92)93.unwrap();9495assert_eq!(96results[0].unwrap_i32(),97types::Errno::Ok as i32,98"double_int_return_float errno"99);100101// The actual result is in memory:102let mem = shim_inst.get_memory(&mut store, "memory").unwrap();103let mut result_bytes: [u8; 4] = [0, 0, 0, 0];104mem.read(&store, result_location as usize, &mut result_bytes)105.unwrap();106let result = f32::from_le_bytes(result_bytes);107assert_eq!((input * 2) as f32, result);108}109110fn store(engine: &Engine) -> Store<Ctx> {111Store::new(engine, Ctx)112}113114// Wiggle expects the caller to have an exported memory. Wasmtime can only115// provide this if the caller is a WebAssembly module, so we need to write116// a shim module:117fn shim_module(engine: &Engine) -> Module {118Module::new(119engine,120r#"121(module122(import "atoms" "int_float_args" (func $int_float_args (param i32 f32) (result i32)))123(import "atoms" "double_int_return_float" (func $double_int_return_float (param i32 i32) (result i32)))124125(memory 1)126(export "memory" (memory 0))127128(func $int_float_args_shim (param i32 f32) (result i32)129local.get 0130local.get 1131call $int_float_args132)133(func $double_int_return_float_shim (param i32 i32) (result i32)134local.get 0135local.get 1136call $double_int_return_float137)138(export "int_float_args_shim" (func $int_float_args_shim))139(export "double_int_return_float_shim" (func $double_int_return_float_shim))140)141"#,142)143.unwrap()144}145146147