Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/tests/all/component_model/linker.rs
1692 views
1
use anyhow::Result;
2
use wasmtime::component::types::ComponentItem;
3
use wasmtime::component::{Component, Linker, ResourceType};
4
use wasmtime::{Engine, Store};
5
6
#[test]
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]
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]
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]
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)]
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]
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]
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
186