1 use wasmtime::Result;
2 use wasmtime::component::types::ComponentItem;
3 use wasmtime::component::{Component, Linker, ResourceType};
4 use wasmtime::{Engine, Store};
5 
6 #[test]
old_import_importing_new_item() -> Result<()>7 fn old_import_importing_new_item() -> Result<()> {
8     let engine = Engine::default();
9     let mut linker = Linker::<()>::new(&engine);
10 
11     let ty = ResourceType::host::<u32>();
12     linker.root().resource("a:b/[email protected]", ty, |_, _| Ok(()))?;
13 
14     let component = Component::new(
15         &engine,
16         r#"(component
17             (import "a:b/[email protected]" (type $t (sub resource)))
18             (export "a" (type $t))
19         )"#,
20     )?;
21     let mut store = Store::new(&engine, ());
22     let i = linker.instantiate(&mut store, &component)?;
23 
24     assert_eq!(i.get_resource(&mut store, "a"), Some(ty));
25 
26     Ok(())
27 }
28 
29 #[test]
new_import_importing_old_item() -> Result<()>30 fn new_import_importing_old_item() -> Result<()> {
31     let engine = Engine::default();
32     let mut linker = Linker::<()>::new(&engine);
33 
34     let ty = ResourceType::host::<u32>();
35     linker.root().resource("a:b/[email protected]", ty, |_, _| Ok(()))?;
36 
37     let component = Component::new(
38         &engine,
39         r#"(component
40             (import "a:b/[email protected]" (type $t (sub resource)))
41             (export "a" (type $t))
42         )"#,
43     )?;
44     let mut store = Store::new(&engine, ());
45     let i = linker.instantiate(&mut store, &component)?;
46 
47     assert_eq!(i.get_resource(&mut store, "a"), Some(ty));
48 
49     Ok(())
50 }
51 
52 #[test]
import_both_old_and_new() -> Result<()>53 fn import_both_old_and_new() -> Result<()> {
54     let engine = Engine::default();
55     let mut linker = Linker::<()>::new(&engine);
56 
57     let t1 = ResourceType::host::<u32>();
58     let t2 = ResourceType::host::<i32>();
59     linker.root().resource("a:b/[email protected]", t1, |_, _| Ok(()))?;
60     linker.root().resource("a:b/[email protected]", t2, |_, _| Ok(()))?;
61 
62     let component = Component::new(
63         &engine,
64         r#"(component
65             (import "a:b/[email protected]" (type $t1 (sub resource)))
66             (import "a:b/[email protected]" (type $t2 (sub resource)))
67             (export "t1" (type $t1))
68             (export "t2" (type $t2))
69         )"#,
70     )?;
71     let mut store = Store::new(&engine, ());
72     let i = linker.instantiate(&mut store, &component)?;
73 
74     assert_eq!(i.get_resource(&mut store, "t1"), Some(t1));
75     assert_eq!(i.get_resource(&mut store, "t2"), Some(t2));
76 
77     Ok(())
78 }
79 
80 #[test]
missing_import_selects_max() -> Result<()>81 fn missing_import_selects_max() -> Result<()> {
82     let engine = Engine::default();
83     let mut linker = Linker::<()>::new(&engine);
84 
85     let t1 = ResourceType::host::<u32>();
86     let t2 = ResourceType::host::<i32>();
87     linker.root().resource("a:b/[email protected]", t1, |_, _| Ok(()))?;
88     linker.root().resource("a:b/[email protected]", t2, |_, _| Ok(()))?;
89 
90     let component = Component::new(
91         &engine,
92         r#"(component
93             (import "a:b/[email protected]" (type $t1 (sub resource)))
94             (import "a:b/[email protected]" (type $t2 (sub resource)))
95             (export "t1" (type $t1))
96             (export "t2" (type $t2))
97         )"#,
98     )?;
99     let mut store = Store::new(&engine, ());
100     let i = linker.instantiate(&mut store, &component)?;
101 
102     assert_eq!(i.get_resource(&mut store, "t1"), Some(t2));
103     assert_eq!(i.get_resource(&mut store, "t2"), Some(t2));
104 
105     Ok(())
106 }
107 
108 #[test]
109 #[cfg_attr(miri, ignore)]
linker_substituting_types_issue_8003() -> Result<()>110 fn linker_substituting_types_issue_8003() -> Result<()> {
111     let engine = Engine::default();
112     let linker = Linker::<()>::new(&engine);
113     let component = Component::new(
114         &engine,
115         r#"
116             (component
117               (component $foo
118                 (type $_myres (resource (rep i32)))
119                 (export $myres "myres" (type $_myres))
120 
121                 (core module $m
122                   (func (export "make") (result i32) unreachable)
123                 )
124                 (core instance $m (instantiate $m))
125 
126                 (func (export "make") (result (own $myres))
127                   (canon lift (core func $m "make")))
128               )
129               (instance $foo (instantiate $foo))
130               (export "foo" (instance $foo))
131             )
132         "#,
133     )?;
134 
135     let component_ty = linker.substituted_component_type(&component)?;
136     let exports = component_ty.exports(&engine);
137     for (_name, item) in exports {
138         match item {
139             ComponentItem::ComponentInstance(instance) => {
140                 for _ in instance.exports(&engine) {
141                     // ..
142                 }
143             }
144             _ => {}
145         }
146     }
147     Ok(())
148 }
149 
150 #[test]
linker_defines_unknown_imports_as_traps() -> Result<()>151 fn linker_defines_unknown_imports_as_traps() -> Result<()> {
152     let engine = Engine::default();
153     let mut linker = Linker::<()>::new(&engine);
154 
155     let component = Component::new(
156         &engine,
157         r#"(component
158             (import "foo" (func))
159             (import "bar" (instance (export "baz" (func))))
160             (import "qux" (type (sub resource)))
161         )"#,
162     )?;
163     linker.define_unknown_imports_as_traps(&component)?;
164     let mut store = Store::new(&engine, ());
165     let _ = linker.instantiate(&mut store, &component)?;
166 
167     Ok(())
168 }
169 
170 #[test]
linker_fails_to_define_unknown_core_module_imports_as_traps() -> Result<()>171 fn linker_fails_to_define_unknown_core_module_imports_as_traps() -> Result<()> {
172     let engine = Engine::default();
173     let mut linker = Linker::<()>::new(&engine);
174 
175     let component = Component::new(
176         &engine,
177         r#"(component
178             (import "foo" (core module))
179         )"#,
180     )?;
181     assert!(linker.define_unknown_imports_as_traps(&component).is_err());
182 
183     Ok(())
184 }
185