Path: blob/main/crates/wiggle/tests/wasmtime_async.rs
3090 views
use wasmtime::{Engine, Linker, Module, Store, Val};1use wiggle::GuestMemory;23wiggle::from_witx!({4witx: ["tests/atoms.witx"],5async: {6atoms::{double_int_return_float}7}8});910pub struct Ctx;11impl wiggle::GuestErrorType for types::Errno {12fn success() -> Self {13types::Errno::Ok14}15}1617impl atoms::Atoms for Ctx {18fn int_float_args(19&mut self,20_: &mut GuestMemory<'_>,21an_int: u32,22an_float: f32,23) -> Result<(), types::Errno> {24println!("INT FLOAT ARGS: {an_int} {an_float}");25Ok(())26}27async fn double_int_return_float(28&mut self,29_: &mut GuestMemory<'_>,30an_int: u32,31) -> Result<types::AliasToFloat, types::Errno> {32// Do something inside this test that is Pending for a trivial amount of time,33// to make sure we are hooked up to the tokio executor properly.34tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;35Ok((an_int as f32) * 2.0)36}37}3839#[tokio::test]40async fn test_sync_host_func() {41let mut store = async_store();42let mut linker = Linker::<Ctx>::new(store.engine());43atoms::add_to_linker(&mut linker, |cx| cx).unwrap();44let shim_mod = shim_module(linker.engine());45let shim_inst = linker46.instantiate_async(&mut store, &shim_mod)47.await48.unwrap();4950let mut results = [Val::I32(0)];51shim_inst52.get_func(&mut store, "int_float_args_shim")53.unwrap()54.call_async(&mut store, &[0i32.into(), 123.45f32.into()], &mut results)55.await56.unwrap();5758assert_eq!(59results[0].unwrap_i32(),60types::Errno::Ok as i32,61"int_float_args errno"62);63}6465#[tokio::test]66async fn test_async_host_func() {67let mut store = async_store();68let mut linker = Linker::<Ctx>::new(store.engine());69atoms::add_to_linker(&mut linker, |cx| cx).unwrap();7071let shim_mod = shim_module(linker.engine());72let shim_inst = linker73.instantiate_async(&mut store, &shim_mod)74.await75.unwrap();7677let input: i32 = 123;78let result_location: i32 = 0;7980let mut results = [Val::I32(0)];81shim_inst82.get_func(&mut store, "double_int_return_float_shim")83.unwrap()84.call_async(85&mut store,86&[input.into(), result_location.into()],87&mut results,88)89.await90.unwrap();9192assert_eq!(93results[0].unwrap_i32(),94types::Errno::Ok as i32,95"double_int_return_float errno"96);9798// The actual result is in memory:99let mem = shim_inst.get_memory(&mut store, "memory").unwrap();100let mut result_bytes: [u8; 4] = [0, 0, 0, 0];101mem.read(&store, result_location as usize, &mut result_bytes)102.unwrap();103let result = f32::from_le_bytes(result_bytes);104assert_eq!((input * 2) as f32, result);105}106107fn async_store() -> Store<Ctx> {108Store::new(&Engine::default(), Ctx)109}110111// Wiggle expects the caller to have an exported memory. Wasmtime can only112// provide this if the caller is a WebAssembly module, so we need to write113// a shim module:114fn shim_module(engine: &Engine) -> Module {115Module::new(116engine,117r#"118(module119(import "atoms" "int_float_args" (func $int_float_args (param i32 f32) (result i32)))120(import "atoms" "double_int_return_float" (func $double_int_return_float (param i32 i32) (result i32)))121122(memory 1)123(export "memory" (memory 0))124125(func $int_float_args_shim (param i32 f32) (result i32)126local.get 0127local.get 1128call $int_float_args129)130(func $double_int_return_float_shim (param i32 i32) (result i32)131local.get 0132local.get 1133call $double_int_return_float134)135(export "int_float_args_shim" (func $int_float_args_shim))136(export "double_int_return_float_shim" (func $double_int_return_float_shim))137)138"#,139)140.unwrap()141}142143144