Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/tests/all/component_model.rs
1692 views
1
use anyhow::Result;
2
use std::fmt::Write;
3
use std::iter;
4
use wasmtime::component::Component;
5
use wasmtime_component_util::REALLOC_AND_FREE;
6
use wasmtime_test_util::component::{TypedFuncExt, async_engine, engine};
7
8
mod aot;
9
mod r#async;
10
mod bindgen;
11
mod call_hook;
12
mod dynamic;
13
mod func;
14
mod import;
15
mod instance;
16
mod linker;
17
mod macros;
18
mod nested;
19
mod post_return;
20
mod resources;
21
mod strings;
22
23
#[test]
24
#[cfg_attr(miri, ignore)]
25
fn components_importing_modules() -> Result<()> {
26
let engine = engine();
27
28
// FIXME: these components should actually get instantiated in `*.wast`
29
// tests once supplying imports has actually been implemented.
30
31
Component::new(
32
&engine,
33
r#"
34
(component
35
(import "a" (core module))
36
)
37
"#,
38
)?;
39
40
Component::new(
41
&engine,
42
r#"
43
(component
44
(import "a" (core module $m1
45
(import "" "" (func))
46
(import "" "x" (global i32))
47
48
(export "a" (table 1 funcref))
49
(export "b" (memory 1))
50
(export "c" (func (result f32)))
51
(export "d" (global i64))
52
))
53
54
(core module $m2
55
(func (export ""))
56
(global (export "x") i32 i32.const 0)
57
)
58
(core instance $i2 (instantiate (module $m2)))
59
(core instance $i1 (instantiate (module $m1) (with "" (instance $i2))))
60
61
(core module $m3
62
(import "mod" "1" (memory 1))
63
(import "mod" "2" (table 1 funcref))
64
(import "mod" "3" (global i64))
65
(import "mod" "4" (func (result f32)))
66
)
67
68
(core instance $i3 (instantiate (module $m3)
69
(with "mod" (instance
70
(export "1" (memory $i1 "b"))
71
(export "2" (table $i1 "a"))
72
(export "3" (global $i1 "d"))
73
(export "4" (func $i1 "c"))
74
))
75
))
76
)
77
"#,
78
)?;
79
80
Ok(())
81
}
82
83
#[derive(Copy, Clone, PartialEq, Eq)]
84
enum Type {
85
S8,
86
U8,
87
S16,
88
U16,
89
I32,
90
I64,
91
F32,
92
F64,
93
}
94
95
impl Type {
96
fn store(&self) -> &'static str {
97
match self {
98
Self::S8 | Self::U8 => "store8",
99
Self::S16 | Self::U16 => "store16",
100
Self::I32 | Self::F32 | Self::I64 | Self::F64 => "store",
101
}
102
}
103
104
fn primitive(&self) -> &'static str {
105
match self {
106
Self::S8 | Self::U8 | Self::S16 | Self::U16 | Self::I32 => "i32",
107
Self::I64 => "i64",
108
Self::F32 => "f32",
109
Self::F64 => "f64",
110
}
111
}
112
}
113
114
#[derive(Copy, Clone, PartialEq, Eq)]
115
struct Param(Type, Option<usize>);
116
117
fn make_echo_component(type_definition: &str, type_size: u32) -> String {
118
let mut offset = 0;
119
make_echo_component_with_params(
120
type_definition,
121
&iter::repeat(Type::I32)
122
.map(|ty| {
123
let param = Param(ty, Some(offset));
124
offset += 4;
125
param
126
})
127
.take(usize::try_from(type_size).unwrap() / 4)
128
.collect::<Vec<_>>(),
129
)
130
}
131
132
fn make_echo_component_with_params(type_definition: &str, params: &[Param]) -> String {
133
let func = if params.len() == 0 {
134
format!("(func (export \"echo\"))")
135
} else if params.len() == 1 || params.len() > 16 {
136
let primitive = if params.len() == 1 {
137
params[0].0.primitive()
138
} else {
139
"i32"
140
};
141
142
format!(
143
r#"
144
(func (export "echo") (param {primitive}) (result {primitive})
145
local.get 0
146
)"#,
147
)
148
} else {
149
let mut param_string = String::new();
150
let mut store = String::new();
151
let mut size = 8;
152
153
for (index, Param(ty, offset)) in params.iter().enumerate() {
154
let primitive = ty.primitive();
155
156
write!(&mut param_string, " {primitive}").unwrap();
157
if let Some(offset) = offset {
158
write!(
159
&mut store,
160
"({primitive}.{} offset={offset} (local.get $base) (local.get {index}))",
161
ty.store(),
162
)
163
.unwrap();
164
165
size = size.max(offset + 8);
166
}
167
}
168
169
format!(
170
r#"
171
(func (export "echo") (param{param_string}) (result i32)
172
(local $base i32)
173
(local.set $base
174
(call $realloc
175
(i32.const 0)
176
(i32.const 0)
177
(i32.const 4)
178
(i32.const {size})))
179
{store}
180
local.get $base
181
)"#
182
)
183
};
184
185
let type_section = if type_definition.contains("(type ") {
186
type_definition.to_string()
187
} else {
188
format!("(type $Foo' {type_definition})")
189
};
190
191
format!(
192
r#"
193
(component
194
(core module $m
195
{func}
196
197
(memory (export "memory") 1)
198
{REALLOC_AND_FREE}
199
)
200
201
(core instance $i (instantiate $m))
202
203
{type_section}
204
(export $Foo "foo" (type $Foo'))
205
206
(func (export "echo") (param "a" $Foo) (result $Foo)
207
(canon lift
208
(core func $i "echo")
209
(memory $i "memory")
210
(realloc (func $i "realloc"))
211
)
212
)
213
)"#
214
)
215
}
216
217