Path: blob/main/crates/wiggle/tests/wasmtime_sync.rs
1692 views
use wasmtime::{Engine, Linker, Module, Store, Val};1use wiggle::GuestMemory;23wiggle::from_witx!({4witx: ["tests/atoms.witx"],5block_on: {6atoms::double_int_return_float7}8});910pub struct Ctx;11impl wiggle::GuestErrorType for types::Errno {12fn success() -> Self {13types::Errno::Ok14}15}1617const TRIGGER_PENDING: u32 = 0;1819#[wiggle::async_trait]20impl atoms::Atoms for Ctx {21fn int_float_args(22&mut self,23_: &mut GuestMemory<'_>,24an_int: u32,25an_float: f32,26) -> Result<(), types::Errno> {27println!("INT FLOAT ARGS: {an_int} {an_float}");28Ok(())29}30async fn double_int_return_float(31&mut self,32_: &mut GuestMemory<'_>,33an_int: u32,34) -> Result<types::AliasToFloat, types::Errno> {35if an_int == TRIGGER_PENDING {36// Define a Future that is pending forever. This is `futures::future::pending()`37// without incurring the dep.38use std::future::Future;39use std::pin::Pin;40use std::task::{Context, Poll};41struct Pending;42impl Future for Pending {43type Output = ();44fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {45Poll::Pending46}47}48// This await will pend, which should cause the dummy executor to Trap.49Pending.await;50}51Ok((an_int as f32) * 2.0)52}53}5455#[test]56fn test_sync_host_func() {57let engine = Engine::default();58let mut linker = Linker::new(&engine);59atoms::add_to_linker(&mut linker, |cx| cx).unwrap();60let mut store = store(&engine);61let shim_mod = shim_module(&engine);62let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();6364let mut results = [Val::I32(0)];65shim_inst66.get_func(&mut store, "int_float_args_shim")67.unwrap()68.call(&mut store, &[0i32.into(), 123.45f32.into()], &mut results)69.unwrap();7071assert_eq!(72results[0].unwrap_i32(),73types::Errno::Ok as i32,74"int_float_args errno"75);76}7778#[test]79fn test_async_host_func() {80let engine = Engine::default();81let mut linker = Linker::new(&engine);82atoms::add_to_linker(&mut linker, |cx| cx).unwrap();83let mut store = store(&engine);8485let shim_mod = shim_module(&engine);86let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();8788let input: i32 = 123;89let result_location: i32 = 0;9091let mut results = [Val::I32(0)];92shim_inst93.get_func(&mut store, "double_int_return_float_shim")94.unwrap()95.call(96&mut store,97&[input.into(), result_location.into()],98&mut results,99)100.unwrap();101102assert_eq!(103results[0].unwrap_i32(),104types::Errno::Ok as i32,105"double_int_return_float errno"106);107108// The actual result is in memory:109let mem = shim_inst.get_memory(&mut store, "memory").unwrap();110let mut result_bytes: [u8; 4] = [0, 0, 0, 0];111mem.read(&store, result_location as usize, &mut result_bytes)112.unwrap();113let result = f32::from_le_bytes(result_bytes);114assert_eq!((input * 2) as f32, result);115}116117#[test]118fn test_async_host_func_pending() {119let engine = Engine::default();120let mut linker = Linker::new(&engine);121atoms::add_to_linker(&mut linker, |cx| cx).unwrap();122let mut store = store(&engine);123124let shim_mod = shim_module(&engine);125let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();126127let result_location: i32 = 0;128129// This input triggers the host func pending forever130let input: i32 = TRIGGER_PENDING as i32;131let trap = shim_inst132.get_func(&mut store, "double_int_return_float_shim")133.unwrap()134.call(135&mut store,136&[input.into(), result_location.into()],137&mut [Val::I32(0)],138)139.unwrap_err();140assert!(141format!("{trap:?}").contains("Cannot wait on pending future"),142"expected get a pending future Trap from dummy executor, got: {trap}"143);144}145146fn store(engine: &Engine) -> Store<Ctx> {147Store::new(engine, Ctx)148}149150// Wiggle expects the caller to have an exported memory. Wasmtime can only151// provide this if the caller is a WebAssembly module, so we need to write152// a shim module:153fn shim_module(engine: &Engine) -> Module {154Module::new(155engine,156r#"157(module158(import "atoms" "int_float_args" (func $int_float_args (param i32 f32) (result i32)))159(import "atoms" "double_int_return_float" (func $double_int_return_float (param i32 i32) (result i32)))160161(memory 1)162(export "memory" (memory 0))163164(func $int_float_args_shim (param i32 f32) (result i32)165local.get 0166local.get 1167call $int_float_args168)169(func $double_int_return_float_shim (param i32 i32) (result i32)170local.get 0171local.get 1172call $double_int_return_float173)174(export "int_float_args_shim" (func $int_float_args_shim))175(export "double_int_return_float_shim" (func $double_int_return_float_shim))176)177"#,178)179.unwrap()180}181182183