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