1use wasmtime::{Engine, Instance, Memory, Module, Store};
2
3pub struct PureModule {
4 instance: Instance,
5 store: Store<()>,
6 memory: Memory,
7}
8
9impl PureModule {
10 pub fn from_binary(binary: &[u8]) -> Self {
11 let engine = Engine::default();
12 let module = Module::from_binary(&engine, binary).unwrap();
13 Self::new(module, engine)
14 }
15 pub fn from_file(file: &str) -> Self {
16 let engine = Engine::default();
17 let module = Module::from_file(&engine, file).unwrap();
18 Self::new(module, engine)
19 }
20
21 pub fn new(module: Module, engine: Engine) -> Self {
22 let mut store = Store::new(&engine, ());
23 let instance = Instance::new(&mut store, &module, &[]).unwrap();
24 let memory = instance.get_memory(&mut store, "memory").unwrap();
25
26 Self {
27 instance,
28 store,
29 memory,
30 }
31 }
32
33 pub fn call_fn(&mut self, fn_name: &str, input_bytes: &[u8]) -> Vec<u8> {
34 let input_bytes_len = input_bytes.len() as i32;
35 let alloc_func = self
36 .instance
37 .get_typed_func::<i32, i32>(&mut self.store, "alloc")
38 .unwrap();
39 let input_bytes_ptr = alloc_func.call(&mut self.store, input_bytes_len).unwrap();
40 self.memory
41 .write(&mut self.store, input_bytes_ptr as usize, &input_bytes)
42 .unwrap();
43
44 let func = self
45 .instance
46 .get_typed_func::<(i32, i32), (i32, i32)>(&mut self.store, fn_name)
47 .unwrap();
48 let (result_ptr, result_len) = func
49 .call(&mut self.store, (input_bytes_ptr, input_bytes_len))
50 .unwrap();
51 unsafe {
52 let mem_slice = std::slice::from_raw_parts(
53 self.memory
54 .data_ptr(&self.store)
55 .offset(result_ptr as isize),
56 result_len as usize,
57 );
58 mem_slice.to_vec()
59 }
60 }
61}