1 #![no_std]
2 
3 #[macro_use]
4 extern crate alloc;
5 
6 use alloc::string::ToString;
7 use anyhow::Result;
8 use wasmtime::{Engine, Instance, Linker, Module, Store};
9 
10 mod allocator;
11 mod panic;
12 
13 /// Entrypoint of this embedding.
14 ///
15 /// This takes a number of parameters which are the precompiled module AOT
16 /// images that are run for each of the various tests below. The first parameter
17 /// is also where to put an error string, if any, if anything fails.
18 #[unsafe(no_mangle)]
19 pub unsafe extern "C" fn run(
20     error_buf: *mut u8,
21     error_size: usize,
22     smoke_module: *const u8,
23     smoke_size: usize,
24     simple_add_module: *const u8,
25     simple_add_size: usize,
26     simple_host_fn_module: *const u8,
27     simple_host_fn_size: usize,
28 ) -> usize {
29     let buf = core::slice::from_raw_parts_mut(error_buf, error_size);
30     let smoke = core::slice::from_raw_parts(smoke_module, smoke_size);
31     let simple_add = core::slice::from_raw_parts(simple_add_module, simple_add_size);
32     let simple_host_fn = core::slice::from_raw_parts(simple_host_fn_module, simple_host_fn_size);
33     match run_result(smoke, simple_add, simple_host_fn) {
34         Ok(()) => 0,
35         Err(e) => {
36             let msg = format!("{e:?}");
37             let len = buf.len().min(msg.len());
38             buf[..len].copy_from_slice(&msg.as_bytes()[..len]);
39             len
40         }
41     }
42 }
43 
44 fn run_result(
45     smoke_module: &[u8],
46     simple_add_module: &[u8],
47     simple_host_fn_module: &[u8],
48 ) -> Result<()> {
49     smoke(smoke_module)?;
50     simple_add(simple_add_module)?;
51     simple_host_fn(simple_host_fn_module)?;
52     Ok(())
53 }
54 
55 fn smoke(module: &[u8]) -> Result<()> {
56     let engine = Engine::default();
57     let module = match deserialize(&engine, module)? {
58         Some(module) => module,
59         None => return Ok(()),
60     };
61     Instance::new(&mut Store::new(&engine, ()), &module, &[])?;
62     Ok(())
63 }
64 
65 fn simple_add(module: &[u8]) -> Result<()> {
66     let engine = Engine::default();
67     let module = match deserialize(&engine, module)? {
68         Some(module) => module,
69         None => return Ok(()),
70     };
71     let mut store = Store::new(&engine, ());
72     let instance = Linker::new(&engine).instantiate(&mut store, &module)?;
73     let func = instance.get_typed_func::<(u32, u32), u32>(&mut store, "add")?;
74     assert_eq!(func.call(&mut store, (2, 3))?, 5);
75     Ok(())
76 }
77 
78 fn simple_host_fn(module: &[u8]) -> Result<()> {
79     let engine = Engine::default();
80     let module = match deserialize(&engine, module)? {
81         Some(module) => module,
82         None => return Ok(()),
83     };
84     let mut linker = Linker::<()>::new(&engine);
85     linker.func_wrap("host", "multiply", |a: u32, b: u32| a.saturating_mul(b))?;
86     let mut store = Store::new(&engine, ());
87     let instance = linker.instantiate(&mut store, &module)?;
88     let func = instance.get_typed_func::<(u32, u32, u32), u32>(&mut store, "add_and_mul")?;
89     assert_eq!(func.call(&mut store, (2, 3, 4))?, 10);
90     Ok(())
91 }
92 
93 fn deserialize(engine: &Engine, module: &[u8]) -> Result<Option<Module>> {
94     match unsafe { Module::deserialize(engine, module) } {
95         Ok(module) => Ok(Some(module)),
96         Err(e) => {
97             // Currently if custom signals/virtual memory are disabled then this
98             // example is expected to fail to load since loading native code
99             // requires virtual memory. In the future this will go away as when
100             // signals-based-traps is disabled then that means that the
101             // interpreter should be used which should work here.
102             if !cfg!(feature = "custom")
103                 && e.to_string()
104                     .contains("requires virtual memory to be enabled")
105             {
106                 Ok(None)
107             } else {
108                 Err(e)
109             }
110         }
111     }
112 }
113