Path: blob/main/crates/wiggle/tests/wasmtime_integration.rs
1692 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}2829#[wiggle::async_trait]30impl atoms::Atoms for Ctx {31fn int_float_args(32&mut self,33_: &mut GuestMemory<'_>,34an_int: u32,35an_float: f32,36) -> Result<(), types::Errno> {37println!("INT FLOAT ARGS: {an_int} {an_float}");38Ok(())39}40async fn double_int_return_float(41&mut self,42_: &mut GuestMemory<'_>,43an_int: u32,44) -> Result<types::AliasToFloat, types::Errno> {45Ok((an_int as f32) * 2.0)46}47}4849#[test]50fn test_sync_host_func() {51let engine = Engine::default();52let mut linker = Linker::new(&engine);53integration::add_atoms_to_linker(&mut linker, |cx| cx).unwrap();54let mut store = store(&engine);55let shim_mod = shim_module(&engine);56let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();5758let mut results = [Val::I32(0)];59shim_inst60.get_func(&mut store, "int_float_args_shim")61.unwrap()62.call(&mut store, &[0i32.into(), 123.45f32.into()], &mut results)63.unwrap();6465assert_eq!(66results[0].unwrap_i32(),67types::Errno::Ok as i32,68"int_float_args errno"69);70}7172#[test]73fn test_async_host_func() {74let engine = Engine::default();75let mut linker = Linker::new(&engine);76integration::add_atoms_to_linker(&mut linker, |cx| cx).unwrap();77let mut store = store(&engine);7879let shim_mod = shim_module(&engine);80let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();8182let input: i32 = 123;83let result_location: i32 = 0;8485let mut results = [Val::I32(0)];86shim_inst87.get_func(&mut store, "double_int_return_float_shim")88.unwrap()89.call(90&mut store,91&[input.into(), result_location.into()],92&mut results,93)94.unwrap();9596assert_eq!(97results[0].unwrap_i32(),98types::Errno::Ok as i32,99"double_int_return_float errno"100);101102// The actual result is in memory:103let mem = shim_inst.get_memory(&mut store, "memory").unwrap();104let mut result_bytes: [u8; 4] = [0, 0, 0, 0];105mem.read(&store, result_location as usize, &mut result_bytes)106.unwrap();107let result = f32::from_le_bytes(result_bytes);108assert_eq!((input * 2) as f32, result);109}110111fn store(engine: &Engine) -> Store<Ctx> {112Store::new(engine, Ctx)113}114115// Wiggle expects the caller to have an exported memory. Wasmtime can only116// provide this if the caller is a WebAssembly module, so we need to write117// a shim module:118fn shim_module(engine: &Engine) -> Module {119Module::new(120engine,121r#"122(module123(import "atoms" "int_float_args" (func $int_float_args (param i32 f32) (result i32)))124(import "atoms" "double_int_return_float" (func $double_int_return_float (param i32 i32) (result i32)))125126(memory 1)127(export "memory" (memory 0))128129(func $int_float_args_shim (param i32 f32) (result i32)130local.get 0131local.get 1132call $int_float_args133)134(func $double_int_return_float_shim (param i32 i32) (result i32)135local.get 0136local.get 1137call $double_int_return_float138)139(export "int_float_args_shim" (func $int_float_args_shim))140(export "double_int_return_float_shim" (func $double_int_return_float_shim))141)142"#,143)144.unwrap()145}146147148