1 use wasmtime::Result;
2 use wasmtime::component::*;
3 use wasmtime::{Module, Store};
4 
5 #[test]
6 #[cfg_attr(miri, ignore)]
instance_exports() -> Result<()>7 fn instance_exports() -> Result<()> {
8     let engine = super::engine();
9     let component = r#"
10         (component
11             (import "a" (instance $i))
12             (import "b" (instance $i2 (export "m" (core module))))
13 
14             (alias export $i2 "m" (core module $m))
15 
16             (component $c
17                 (component $c
18                     (export "m" (core module $m))
19                 )
20                 (instance $c (instantiate $c))
21                 (export "i" (instance $c))
22             )
23             (instance $c (instantiate $c))
24             (export "i" (instance $c))
25             (export "r" (instance $i))
26             (export "r2" (instance $i2))
27         )
28     "#;
29     let component = Component::new(&engine, component)?;
30     let mut store = Store::new(&engine, ());
31     let mut linker = Linker::new(&engine);
32     linker.instance("a")?;
33     linker
34         .instance("b")?
35         .module("m", &Module::new(&engine, "(module)")?)?;
36     let instance = linker.instantiate(&mut store, &component)?;
37 
38     assert!(
39         instance
40             .get_export(&mut store, None, "not an instance")
41             .is_none()
42     );
43     let i = instance.get_export_index(&mut store, None, "r").unwrap();
44     assert!(instance.get_export(&mut store, Some(&i), "x").is_none());
45     instance.get_export(&mut store, None, "i").unwrap();
46     let i2 = instance.get_export_index(&mut store, None, "r2").unwrap();
47     let m = instance
48         .get_export_index(&mut store, Some(&i2), "m")
49         .unwrap();
50     assert!(instance.get_func(&mut store, &m).is_none());
51     assert!(instance.get_module(&mut store, &m).is_some());
52 
53     let i = instance.get_export_index(&mut store, None, "i").unwrap();
54     let i = instance
55         .get_export_index(&mut store, Some(&i), "i")
56         .unwrap();
57     let m = instance
58         .get_export_index(&mut store, Some(&i), "m")
59         .unwrap();
60     instance.get_module(&mut store, &m).unwrap();
61 
62     Ok(())
63 }
64 
65 #[test]
export_old_get_new() -> Result<()>66 fn export_old_get_new() -> Result<()> {
67     let engine = super::engine();
68     let component = r#"
69         (component
70             (core module $m)
71             (export "a:b/[email protected]" (core module $m))
72 
73             (instance $i (export "m" (core module $m)))
74             (export "a:b/[email protected]" (instance $i))
75         )
76     "#;
77 
78     let component = Component::new(&engine, component)?;
79     component.get_export(None, "a:b/[email protected]").unwrap();
80     let i = component.get_export_index(None, "a:b/[email protected]").unwrap();
81     component.get_export(Some(&i), "m").unwrap();
82 
83     let mut store = Store::new(&engine, ());
84     let linker = Linker::new(&engine);
85     let instance = linker.instantiate(&mut store, &component)?;
86 
87     instance.get_module(&mut store, "a:b/[email protected]").unwrap();
88     instance
89         .get_export(&mut store, None, "a:b/[email protected]")
90         .unwrap();
91 
92     let i = instance
93         .get_export_index(&mut store, None, "a:b/[email protected]")
94         .unwrap();
95     instance.get_export(&mut store, Some(&i), "m").unwrap();
96 
97     Ok(())
98 }
99 
100 #[test]
export_new_get_old() -> Result<()>101 fn export_new_get_old() -> Result<()> {
102     let engine = super::engine();
103     let component = r#"
104         (component
105             (core module $m)
106             (export "a:b/[email protected]" (core module $m))
107 
108             (instance $i (export "m" (core module $m)))
109             (export "a:b/[email protected]" (instance $i))
110         )
111     "#;
112 
113     let component = Component::new(&engine, component)?;
114     component.get_export(None, "a:b/[email protected]").unwrap();
115     let i = component.get_export_index(None, "a:b/[email protected]").unwrap();
116     component.get_export(Some(&i), "m").unwrap();
117 
118     let mut store = Store::new(&engine, ());
119     let linker = Linker::new(&engine);
120     let instance = linker.instantiate(&mut store, &component)?;
121 
122     instance.get_module(&mut store, "a:b/[email protected]").unwrap();
123     instance
124         .get_export(&mut store, None, "a:b/[email protected]")
125         .unwrap();
126 
127     let i = instance
128         .get_export_index(&mut store, None, "a:b/[email protected]")
129         .unwrap();
130     instance.get_export(&mut store, Some(&i), "m").unwrap();
131 
132     Ok(())
133 }
134 
135 #[test]
136 #[cfg_attr(miri, ignore)]
export_missing_get_max() -> Result<()>137 fn export_missing_get_max() -> Result<()> {
138     let engine = super::engine();
139     let component = r#"
140         (component
141             (core module $m1)
142             (core module $m2 (import "" "" (func)))
143             (export "a:b/[email protected]" (core module $m1))
144             (export "a:b/[email protected]" (core module $m2))
145         )
146     "#;
147 
148     fn assert_m2(module: &Module) {
149         assert_eq!(module.imports().len(), 1);
150     }
151     fn assert_m1(module: &Module) {
152         assert_eq!(module.imports().len(), 0);
153     }
154 
155     let component = Component::new(&engine, component)?;
156     let mut store = Store::new(&engine, ());
157     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
158 
159     let tests = [
160         ("a:b/[email protected]", assert_m2 as fn(&_)), // no exact, should pick max available
161         ("a:b/[email protected]", assert_m1),           // exact hit
162         ("a:b/[email protected]", assert_m2),           // no exact, should pick max available
163         ("a:b/[email protected]", assert_m2),           // exact hit
164         ("a:b/[email protected]", assert_m2),           // no exact, should pick max available
165     ];
166 
167     for (name, test_fn) in tests {
168         println!("test {name}");
169         let m = component.get_export_index(None, name).unwrap();
170         let m = instance.get_module(&mut store, &m).unwrap();
171         test_fn(&m);
172 
173         let m = instance.get_module(&mut store, name).unwrap();
174         test_fn(&m);
175 
176         let m = instance.get_export_index(&mut store, None, name).unwrap();
177         let m = instance.get_module(&mut store, &m).unwrap();
178         test_fn(&m);
179     }
180 
181     Ok(())
182 }
183