Path: blob/main/crates/wiggle/tests/wasmtime_sync.rs
3092 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;1819impl atoms::Atoms for Ctx {20fn int_float_args(21&mut self,22_: &mut GuestMemory<'_>,23an_int: u32,24an_float: f32,25) -> Result<(), types::Errno> {26println!("INT FLOAT ARGS: {an_int} {an_float}");27Ok(())28}29async fn double_int_return_float(30&mut self,31_: &mut GuestMemory<'_>,32an_int: u32,33) -> Result<types::AliasToFloat, types::Errno> {34if an_int == TRIGGER_PENDING {35// Define a Future that is pending forever. This is `futures::future::pending()`36// without incurring the dep.37use std::future::Future;38use std::pin::Pin;39use std::task::{Context, Poll};40struct Pending;41impl Future for Pending {42type Output = ();43fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {44Poll::Pending45}46}47// This await will pend, which should cause the dummy executor to Trap.48Pending.await;49}50Ok((an_int as f32) * 2.0)51}52}5354#[test]55fn test_sync_host_func() {56let engine = Engine::default();57let mut linker = Linker::new(&engine);58atoms::add_to_linker(&mut linker, |cx| cx).unwrap();59let mut store = store(&engine);60let shim_mod = shim_module(&engine);61let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();6263let mut results = [Val::I32(0)];64shim_inst65.get_func(&mut store, "int_float_args_shim")66.unwrap()67.call(&mut store, &[0i32.into(), 123.45f32.into()], &mut results)68.unwrap();6970assert_eq!(71results[0].unwrap_i32(),72types::Errno::Ok as i32,73"int_float_args errno"74);75}7677#[test]78fn test_async_host_func() {79let engine = Engine::default();80let mut linker = Linker::new(&engine);81atoms::add_to_linker(&mut linker, |cx| cx).unwrap();82let mut store = store(&engine);8384let shim_mod = shim_module(&engine);85let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();8687let input: i32 = 123;88let result_location: i32 = 0;8990let mut results = [Val::I32(0)];91shim_inst92.get_func(&mut store, "double_int_return_float_shim")93.unwrap()94.call(95&mut store,96&[input.into(), result_location.into()],97&mut results,98)99.unwrap();100101assert_eq!(102results[0].unwrap_i32(),103types::Errno::Ok as i32,104"double_int_return_float errno"105);106107// The actual result is in memory:108let mem = shim_inst.get_memory(&mut store, "memory").unwrap();109let mut result_bytes: [u8; 4] = [0, 0, 0, 0];110mem.read(&store, result_location as usize, &mut result_bytes)111.unwrap();112let result = f32::from_le_bytes(result_bytes);113assert_eq!((input * 2) as f32, result);114}115116#[test]117fn test_async_host_func_pending() {118let engine = Engine::default();119let mut linker = Linker::new(&engine);120atoms::add_to_linker(&mut linker, |cx| cx).unwrap();121let mut store = store(&engine);122123let shim_mod = shim_module(&engine);124let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();125126let result_location: i32 = 0;127128// This input triggers the host func pending forever129let input: i32 = TRIGGER_PENDING as i32;130let trap = shim_inst131.get_func(&mut store, "double_int_return_float_shim")132.unwrap()133.call(134&mut store,135&[input.into(), result_location.into()],136&mut [Val::I32(0)],137)138.unwrap_err();139assert!(140format!("{trap:?}").contains("Cannot wait on pending future"),141"expected get a pending future Trap from dummy executor, got: {trap}"142);143}144145fn store(engine: &Engine) -> Store<Ctx> {146Store::new(engine, Ctx)147}148149// Wiggle expects the caller to have an exported memory. Wasmtime can only150// provide this if the caller is a WebAssembly module, so we need to write151// a shim module:152fn shim_module(engine: &Engine) -> Module {153Module::new(154engine,155r#"156(module157(import "atoms" "int_float_args" (func $int_float_args (param i32 f32) (result i32)))158(import "atoms" "double_int_return_float" (func $double_int_return_float (param i32 i32) (result i32)))159160(memory 1)161(export "memory" (memory 0))162163(func $int_float_args_shim (param i32 f32) (result i32)164local.get 0165local.get 1166call $int_float_args167)168(func $double_int_return_float_shim (param i32 i32) (result i32)169local.get 0170local.get 1171call $double_int_return_float172)173(export "int_float_args_shim" (func $int_float_args_shim))174(export "double_int_return_float_shim" (func $double_int_return_float_shim))175)176"#,177)178.unwrap()179}180181182