1 use super::REALLOC_AND_FREE;
2 use anyhow::Result;
3 use wasmtime::component::*;
4 use wasmtime::{Module, Store, StoreContextMut};
5 
6 #[test]
7 fn top_level_instance_two_level() -> Result<()> {
8     let component = r#"
9 (component
10   (import "c" (instance $i
11     (export "c" (instance
12       (export "m" (core module
13         (export "g" (global i32))
14       ))
15     ))
16   ))
17   (component $c1
18     (import "c" (instance $i
19       (export "c" (instance
20         (export "m" (core module
21           (export "g" (global i32))
22         ))
23       ))
24     ))
25     (core module $verify
26       (import "" "g" (global i32))
27       (func $start
28         global.get 0
29         i32.const 101
30         i32.ne
31         if unreachable end
32       )
33 
34       (start $start)
35     )
36     (core instance $m (instantiate (module $i "c" "m")))
37     (core instance (instantiate $verify (with "" (instance $m))))
38   )
39   (instance (instantiate $c1 (with "c" (instance $i))))
40 )
41     "#;
42     let module = r#"
43 (module
44   (global (export "g") i32 i32.const 101)
45 )
46     "#;
47 
48     let engine = super::engine();
49     let module = Module::new(&engine, module)?;
50     let component = Component::new(&engine, component)?;
51     let mut store = Store::new(&engine, ());
52     let mut linker = Linker::new(&engine);
53     linker.instance("c")?.instance("c")?.module("m", &module)?;
54     linker.instantiate(&mut store, &component)?;
55     Ok(())
56 }
57 
58 #[test]
59 fn nested_many_instantiations() -> Result<()> {
60     let component = r#"
61 (component
62   (import "count" (func $count))
63   (component $c1
64     (import "count" (func $count))
65     (core func $count_lower (canon lower (func $count)))
66     (core module $m
67         (import "" "" (func $count))
68         (start $count)
69     )
70     (core instance (instantiate $m (with "" (instance (export "" (func $count_lower))))))
71     (core instance (instantiate $m (with "" (instance (export "" (func $count_lower))))))
72   )
73   (component $c2
74     (import "count" (func $count))
75     (instance (instantiate $c1 (with "count" (func $count))))
76     (instance (instantiate $c1 (with "count" (func $count))))
77   )
78   (component $c3
79     (import "count" (func $count))
80     (instance (instantiate $c2 (with "count" (func $count))))
81     (instance (instantiate $c2 (with "count" (func $count))))
82   )
83   (component $c4
84     (import "count" (func $count))
85     (instance (instantiate $c3 (with "count" (func $count))))
86     (instance (instantiate $c3 (with "count" (func $count))))
87   )
88 
89   (instance (instantiate $c4 (with "count" (func $count))))
90 )
91     "#;
92     let engine = super::engine();
93     let component = Component::new(&engine, component)?;
94     let mut store = Store::new(&engine, 0);
95     let mut linker = Linker::new(&engine);
96     linker
97         .root()
98         .func_wrap("count", |mut store: StoreContextMut<'_, u32>| {
99             *store.data_mut() += 1;
100             Ok(())
101         })?;
102     linker.instantiate(&mut store, &component)?;
103     assert_eq!(*store.data(), 16);
104     Ok(())
105 }
106 
107 #[test]
108 fn thread_options_through_inner() -> Result<()> {
109     let component = format!(
110         r#"
111 (component
112   (import "hostfn" (func $host (param u32) (result string)))
113 
114   (component $c
115     (import "hostfn" (func $host (param u32) (result string)))
116 
117     (core module $libc
118         (memory (export "memory") 1)
119         {REALLOC_AND_FREE}
120     )
121     (core instance $libc (instantiate $libc))
122 
123     (core func $host_lower
124         (canon lower
125             (func $host)
126             (memory $libc "memory")
127             (realloc (func $libc "realloc"))
128         )
129     )
130 
131     (core module $m
132         (import "" "host" (func $host (param i32 i32)))
133         (import "libc" "memory" (memory 1))
134         (func (export "run") (param i32) (result i32)
135             i32.const 42
136             i32.const 100
137             call $host
138             i32.const 100
139         )
140         (export "memory" (memory 0))
141     )
142     (core instance $m (instantiate $m
143         (with "" (instance (export "host" (func $host_lower))))
144         (with "libc" (instance $libc))
145     ))
146 
147     (func (export "run") (param u32) (result string)
148         (canon lift
149             (core func $m "run")
150             (memory $m "memory")
151         )
152     )
153   )
154   (instance $c (instantiate $c (with "hostfn" (func $host))))
155   (export "run" (func $c "run"))
156 )
157     "#
158     );
159     let engine = super::engine();
160     let component = Component::new(&engine, component)?;
161     let mut store = Store::new(&engine, 0);
162     let mut linker = Linker::new(&engine);
163     linker
164         .root()
165         .func_wrap("hostfn", |param: u32| Ok((param.to_string(),)))?;
166     let instance = linker.instantiate(&mut store, &component)?;
167     let result = instance
168         .get_typed_func::<(u32,), (WasmStr,), _>(&mut store, "run")?
169         .call(&mut store, (43,))?
170         .0;
171     assert_eq!(result.to_str(&store)?, "42");
172     Ok(())
173 }
174