Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/tests/all/component_model/aot.rs
1691 views
1
use anyhow::Result;
2
use wasmtime::component::types::ComponentItem;
3
use wasmtime::component::{Component, Linker, Type};
4
use wasmtime::{Engine, Module, Precompiled, Store};
5
6
#[test]
7
fn module_component_mismatch() -> Result<()> {
8
let engine = super::engine();
9
let module = Module::new(&engine, "(module)")?.serialize()?;
10
let component = Component::new(&engine, "(component)")?.serialize()?;
11
12
unsafe {
13
assert!(Module::deserialize(&engine, &component).is_err());
14
assert!(Component::deserialize(&engine, &module).is_err());
15
}
16
17
Ok(())
18
}
19
20
#[test]
21
fn bare_bones() -> Result<()> {
22
let engine = super::engine();
23
let component = Component::new(&engine, "(component)")?.serialize()?;
24
assert_eq!(component, engine.precompile_component(b"(component)")?);
25
26
let component = unsafe { Component::deserialize(&engine, &component)? };
27
let mut store = Store::new(&engine, ());
28
Linker::new(&engine).instantiate(&mut store, &component)?;
29
30
Ok(())
31
}
32
33
#[test]
34
#[cfg_attr(miri, ignore)]
35
fn mildly_more_interesting() -> Result<()> {
36
let engine = super::engine();
37
let component = Component::new(
38
&engine,
39
r#"
40
(component
41
(core module $a
42
(func (export "a") (result i32)
43
i32.const 100)
44
)
45
(core instance $a (instantiate $a))
46
47
(core module $b
48
(import "a" "a" (func $import (result i32)))
49
(func (export "a") (result i32)
50
call $import
51
i32.const 3
52
i32.add)
53
)
54
(core instance $b (instantiate $b (with "a" (instance $a))))
55
56
(func (export "a") (result u32)
57
(canon lift (core func $b "a"))
58
)
59
)
60
"#,
61
)?
62
.serialize()?;
63
64
let component = unsafe { Component::deserialize(&engine, &component)? };
65
let mut store = Store::new(&engine, ());
66
let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
67
let func = instance.get_typed_func::<(), (u32,)>(&mut store, "a")?;
68
assert_eq!(func.call(&mut store, ())?, (103,));
69
70
Ok(())
71
}
72
73
#[test]
74
fn deserialize_from_serialized() -> Result<()> {
75
let engine = super::engine();
76
let buffer1 = Component::new(&engine, "(component (core module))")?.serialize()?;
77
let buffer2 = unsafe { Component::deserialize(&engine, &buffer1)?.serialize()? };
78
assert!(buffer1 == buffer2);
79
Ok(())
80
}
81
82
// This specifically tests the current behavior that it's an error, but this can
83
// be made to work if necessary in the future. Currently the implementation of
84
// `serialize` is not conducive to easily implementing this feature and
85
// otherwise it's not seen as too important to implement.
86
#[test]
87
fn cannot_serialize_exported_module() -> Result<()> {
88
let engine = super::engine();
89
let component = Component::new(
90
&engine,
91
r#"(component
92
(core module $m)
93
(export "a" (core module $m))
94
)"#,
95
)?;
96
let mut store = Store::new(&engine, ());
97
let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
98
let module = instance.get_module(&mut store, "a").unwrap();
99
assert!(module.serialize().is_err());
100
Ok(())
101
}
102
103
#[test]
104
#[cfg_attr(miri, ignore)]
105
fn usable_exported_modules() -> Result<()> {
106
let engine = super::engine();
107
let component = Component::new(
108
&engine,
109
r#"(component
110
(core module $m)
111
(core module $m1 (export "a")
112
(import "" "" (func (param i32)))
113
)
114
)"#,
115
)?;
116
let mut store = Store::new(&engine, ());
117
let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
118
let module = instance.get_module(&mut store, "a").unwrap();
119
let mut core_linker = wasmtime::Linker::new(&engine);
120
core_linker.func_wrap("", "", |_: u32| {})?;
121
core_linker.instantiate(&mut store, &module)?;
122
Ok(())
123
}
124
125
#[test]
126
#[cfg_attr(miri, ignore)]
127
fn detect_precompiled() -> Result<()> {
128
let engine = super::engine();
129
let buffer = Component::new(&engine, "(component)")?.serialize()?;
130
assert_eq!(Engine::detect_precompiled(&[]), None);
131
assert_eq!(Engine::detect_precompiled(&buffer[..5]), None);
132
assert_eq!(
133
Engine::detect_precompiled(&buffer),
134
Some(Precompiled::Component)
135
);
136
Ok(())
137
}
138
139
#[test]
140
fn reflect_resource_import() -> Result<()> {
141
let engine = super::engine();
142
let c = Component::new(
143
&engine,
144
r#"
145
(component
146
(import "x" (type $x (sub resource)))
147
(import "y" (func (result (own $x))))
148
)
149
"#,
150
)?;
151
let ty = c.component_type();
152
let mut imports = ty.imports(&engine);
153
let (_, x) = imports.next().unwrap();
154
let (_, y) = imports.next().unwrap();
155
let x = match x {
156
ComponentItem::Resource(t) => t,
157
_ => unreachable!(),
158
};
159
let y = match y {
160
ComponentItem::ComponentFunc(t) => t,
161
_ => unreachable!(),
162
};
163
let result = y.results().next().unwrap();
164
assert_eq!(result, Type::Own(x));
165
166
Ok(())
167
}
168
169
#[test]
170
#[cfg_attr(miri, ignore)]
171
fn truncated_component_binaries_dont_panic() -> Result<()> {
172
let engine = super::engine();
173
174
let binary = wat::parse_str(
175
r#"
176
(component
177
(import "a" (core module $m0
178
(import "" "" (func))
179
))
180
181
(core module $m1
182
(func (export ""))
183
)
184
(core instance $i1 (instantiate (module $m1)))
185
(func $f (canon lift (core func $i1 "f")))
186
187
(component $c1
188
(import "f" (func))
189
(core module $m2
190
(func (export "g"))
191
)
192
(core instance $i2 (instantiate $m2))
193
(func (export "g")
194
(canon lift (core func $i2 "g"))
195
)
196
)
197
(instance $i3 (instantiate $c1 (with "f" (func $f))))
198
(func (export "g") (alias export $i3 "g"))
199
)
200
"#,
201
)?;
202
203
// Check that if we feed each truncation of the component binary into
204
// `Component::new` we don't get any panics.
205
for i in 1..binary.len() - 1 {
206
let _ = Component::from_binary(&engine, &binary[0..i]);
207
}
208
209
Ok(())
210
}
211
212