1 use wasmtime::Result;
2 use wasmtime::{Instance, Linker, Module};
3 use wasmtime_wizer::Wizer;
4 use wat::parse_str as wat_to_wasm;
5
6 const PRELOAD1: &'static str = r#"
7 (module
8 (func (export "f") (param i32) (result i32)
9 local.get 0
10 i32.const 1
11 i32.add))
12 "#;
13
14 const PRELOAD2: &'static str = r#"
15 (module
16 (func (export "f") (param i32) (result i32)
17 local.get 0
18 i32.const 2
19 i32.add))
20 "#;
21
run_with_preloads(args: &[wasmtime::Val], wat: &str) -> Result<wasmtime::Val>22 async fn run_with_preloads(args: &[wasmtime::Val], wat: &str) -> Result<wasmtime::Val> {
23 let wasm = wat_to_wasm(wat)?;
24 let engine = wasmtime::Engine::default();
25 let mut store = wasmtime::Store::new(&engine, ());
26 let mod1 = Module::new(store.engine(), PRELOAD1)?;
27 let mod2 = Module::new(store.engine(), PRELOAD2)?;
28
29 let processed = Wizer::new()
30 .run(&mut store, &wasm, async |store, module| {
31 let i1 = Instance::new_async(&mut *store, &mod1, &[]).await?;
32 let i2 = Instance::new_async(&mut *store, &mod2, &[]).await?;
33 let mut linker = Linker::new(store.engine());
34 linker.instance(&mut *store, "mod1", i1)?;
35 linker.instance(&mut *store, "mod2", i2)?;
36 linker.instantiate_async(store, module).await
37 })
38 .await?;
39
40 let testmod = wasmtime::Module::new(&engine, &processed[..])?;
41
42 let mod1_inst = wasmtime::Instance::new_async(&mut store, &mod1, &[]).await?;
43 let mod2_inst = wasmtime::Instance::new_async(&mut store, &mod2, &[]).await?;
44 let mut linker = wasmtime::Linker::new(&engine);
45 linker.instance(&mut store, "mod1", mod1_inst)?;
46 linker.instance(&mut store, "mod2", mod2_inst)?;
47
48 let inst = linker.instantiate_async(&mut store, &testmod).await?;
49 let run = inst
50 .get_func(&mut store, "run")
51 .ok_or_else(|| wasmtime::format_err!("no `run` function on test module"))?;
52 let mut returned = vec![wasmtime::Val::I32(0)];
53 run.call_async(&mut store, args, &mut returned).await?;
54 Ok(returned[0])
55 }
56
57 #[tokio::test]
test_preloads()58 async fn test_preloads() {
59 const WAT: &'static str = r#"
60 (module
61 (import "mod1" "f" (func $mod1f (param i32) (result i32)))
62 (import "mod2" "f" (func $mod2f (param i32) (result i32)))
63 (global $g1 (mut i32) (i32.const 0))
64 (global $g2 (mut i32) (i32.const 0))
65 (func (export "wizer-initialize")
66 i32.const 100
67 call $mod1f
68 global.set $g1
69 i32.const 100
70 call $mod2f
71 global.set $g2)
72 (func (export "run") (param i32 i32) (result i32)
73 local.get 0
74 call $mod1f
75 local.get 1
76 call $mod2f
77 i32.add
78 global.get $g1
79 global.get $g2
80 i32.add
81 i32.add))
82 "#;
83
84 let result = run_with_preloads(&[wasmtime::Val::I32(200), wasmtime::Val::I32(201)], WAT)
85 .await
86 .unwrap();
87 assert!(matches!(result, wasmtime::Val::I32(607)));
88 }
89