1 #![no_std] 2 3 #[macro_use] 4 extern crate alloc; 5 6 use anyhow::Result; 7 use wasmtime::{Engine, Instance, Linker, Module, Store}; 8 9 mod allocator; 10 mod panic; 11 12 /// Entrypoint of this embedding. 13 /// 14 /// This takes a number of parameters which are the precompiled module AOT 15 /// images that are run for each of the various tests below. The first parameter 16 /// is also where to put an error string, if any, if anything fails. 17 #[no_mangle] 18 pub unsafe extern "C" fn run( 19 error_buf: *mut u8, 20 error_size: usize, 21 smoke_module: *const u8, 22 smoke_size: usize, 23 simple_add_module: *const u8, 24 simple_add_size: usize, 25 simple_host_fn_module: *const u8, 26 simple_host_fn_size: usize, 27 ) -> usize { 28 let buf = core::slice::from_raw_parts_mut(error_buf, error_size); 29 let smoke = core::slice::from_raw_parts(smoke_module, smoke_size); 30 let simple_add = core::slice::from_raw_parts(simple_add_module, simple_add_size); 31 let simple_host_fn = core::slice::from_raw_parts(simple_host_fn_module, simple_host_fn_size); 32 match run_result(smoke, simple_add, simple_host_fn) { 33 Ok(()) => 0, 34 Err(e) => { 35 let msg = format!("{e:?}"); 36 let len = buf.len().min(msg.len()); 37 buf[..len].copy_from_slice(&msg.as_bytes()[..len]); 38 len 39 } 40 } 41 } 42 43 fn run_result( 44 smoke_module: &[u8], 45 simple_add_module: &[u8], 46 simple_host_fn_module: &[u8], 47 ) -> Result<()> { 48 smoke(smoke_module)?; 49 simple_add(simple_add_module)?; 50 simple_host_fn(simple_host_fn_module)?; 51 Ok(()) 52 } 53 54 fn smoke(module: &[u8]) -> Result<()> { 55 let engine = Engine::default(); 56 let module = unsafe { Module::deserialize(&engine, module)? }; 57 Instance::new(&mut Store::new(&engine, ()), &module, &[])?; 58 Ok(()) 59 } 60 61 fn simple_add(module: &[u8]) -> Result<()> { 62 let engine = Engine::default(); 63 let module = unsafe { Module::deserialize(&engine, module)? }; 64 let mut store = Store::new(&engine, ()); 65 let instance = Linker::new(&engine).instantiate(&mut store, &module)?; 66 let func = instance.get_typed_func::<(u32, u32), u32>(&mut store, "add")?; 67 assert_eq!(func.call(&mut store, (2, 3))?, 5); 68 Ok(()) 69 } 70 71 fn simple_host_fn(module: &[u8]) -> Result<()> { 72 let engine = Engine::default(); 73 let module = unsafe { Module::deserialize(&engine, module)? }; 74 let mut linker = Linker::<()>::new(&engine); 75 linker.func_wrap("host", "multiply", |a: u32, b: u32| a.saturating_mul(b))?; 76 let mut store = Store::new(&engine, ()); 77 let instance = linker.instantiate(&mut store, &module)?; 78 let func = instance.get_typed_func::<(u32, u32, u32), u32>(&mut store, "add_and_mul")?; 79 assert_eq!(func.call(&mut store, (2, 3, 4))?, 10); 80 Ok(()) 81 } 82