Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/tests/all/component_model/bindgen/ownership.rs
1692 views
1
use super::{super::REALLOC_AND_FREE, engine};
2
use anyhow::Result;
3
use wasmtime::{
4
Store,
5
component::{Component, Linker},
6
};
7
8
fn component() -> String {
9
format!(
10
r#"
11
(component
12
(core module $libc
13
(memory (export "memory") 1)
14
{REALLOC_AND_FREE}
15
)
16
(core instance $libc (instantiate $libc))
17
(core module $m
18
(import "libc" "memory" (memory 0))
19
(import "libc" "realloc" (func $realloc (param i32 i32 i32 i32) (result i32)))
20
(func (export "core_foo_export") (param i32 i32) (result i32)
21
(local $retptr i32)
22
(local.set $retptr
23
(call $realloc
24
(i32.const 0)
25
(i32.const 0)
26
(i32.const 4)
27
(i32.const 8)))
28
(i32.store offset=0 (local.get $retptr) (local.get 0))
29
(i32.store offset=4 (local.get $retptr) (local.get 1))
30
(local.get $retptr)
31
)
32
(func (export "core_bar_export") (param i32 i32 i32 i32))
33
(func (export "core_baz_export") (param i32 i32 i32 i32) (result i32)
34
(local $retptr i32)
35
(local.set $retptr
36
(call $realloc
37
(i32.const 0)
38
(i32.const 0)
39
(i32.const 4)
40
(i32.const 16)))
41
(i32.store offset=0 (local.get $retptr) (local.get 0))
42
(i32.store offset=4 (local.get $retptr) (local.get 1))
43
(i32.store offset=8 (local.get $retptr) (local.get 2))
44
(i32.store offset=12 (local.get $retptr) (local.get 3))
45
(local.get $retptr)
46
)
47
)
48
(core instance $i (instantiate $m
49
(with "libc" (instance $libc))
50
))
51
52
(func $f_foo
53
(param "a" (list (list string)))
54
(result (list (list string)))
55
(canon lift (core func $i "core_foo_export") (memory $libc "memory")
56
(realloc (func $libc "realloc"))
57
)
58
)
59
60
(type $thing (record (field "name" string) (field "value" (list string))))
61
62
(func $f_bar
63
(param "a" $thing)
64
(canon lift (core func $i "core_bar_export") (memory $libc "memory")
65
(realloc (func $libc "realloc"))
66
)
67
)
68
69
(func $f_baz
70
(param "a" $thing)
71
(result $thing)
72
(canon lift (core func $i "core_baz_export") (memory $libc "memory")
73
(realloc (func $libc "realloc"))
74
)
75
)
76
77
(component $c_lists
78
(import "import-foo" (func $f
79
(param "a" (list (list string)))
80
(result (list (list string)))
81
))
82
(export "foo" (func $f))
83
)
84
(instance $i_lists (instantiate $c_lists
85
(with "import-foo" (func $f_foo))
86
))
87
(export "lists" (instance $i_lists))
88
89
(component $c_thing_in
90
(import "import-thing" (type $import-thing (eq $thing)))
91
(import "import-bar" (func $f (param "a" $import-thing)))
92
(export $export-thing "thing" (type $thing))
93
(export "bar" (func $f) (func (param "a" $export-thing)))
94
)
95
(instance $i_thing_in (instantiate $c_thing_in
96
(with "import-thing" (type $thing))
97
(with "import-bar" (func $f_bar))
98
))
99
(export "thing-in" (instance $i_thing_in))
100
101
(component $c_thing_in_and_out
102
(import "import-thing" (type $import-thing (eq $thing)))
103
(import "import-baz" (func $f (param "a" $import-thing) (result $import-thing)))
104
(export $export-thing "thing" (type $thing))
105
(export "baz" (func $f) (func (param "a" $export-thing) (result $export-thing)))
106
)
107
(instance $i_thing_in_and_out (instantiate $c_thing_in_and_out
108
(with "import-thing" (type $thing))
109
(with "import-baz" (func $f_baz))
110
))
111
(export "thing-in-and-out" (instance $i_thing_in_and_out))
112
)
113
"#
114
)
115
}
116
117
mod owning {
118
use super::*;
119
120
wasmtime::component::bindgen!({
121
inline: "
122
package inline:inline;
123
world test {
124
export lists: interface {
125
foo: func(a: list<list<string>>) -> list<list<string>>;
126
}
127
128
export thing-in: interface {
129
record thing {
130
name: string,
131
value: list<string>
132
}
133
134
bar: func(a: thing);
135
}
136
137
export thing-in-and-out: interface {
138
record thing {
139
name: string,
140
value: list<string>
141
}
142
143
baz: func(a: thing) -> thing;
144
}
145
}",
146
ownership: Owning
147
});
148
149
impl PartialEq for exports::thing_in::Thing {
150
fn eq(&self, other: &Self) -> bool {
151
self.name == other.name && self.value == other.value
152
}
153
}
154
155
impl PartialEq for exports::thing_in_and_out::Thing {
156
fn eq(&self, other: &Self) -> bool {
157
self.name == other.name && self.value == other.value
158
}
159
}
160
161
#[test]
162
fn owning() -> Result<()> {
163
let engine = engine();
164
let component = Component::new(&engine, component())?;
165
166
let linker = Linker::new(&engine);
167
let mut store = Store::new(&engine, ());
168
let test = Test::instantiate(&mut store, &component, &linker)?;
169
170
let value = vec![vec!["a".to_owned(), "b".to_owned()]];
171
assert_eq!(value, test.lists().call_foo(&mut store, &value)?);
172
173
let value = exports::thing_in::Thing {
174
name: "thing 1".to_owned(),
175
value: vec!["some value".to_owned(), "another value".to_owned()],
176
};
177
test.thing_in().call_bar(&mut store, &value)?;
178
179
let value = exports::thing_in_and_out::Thing {
180
name: "thing 1".to_owned(),
181
value: vec!["some value".to_owned(), "another value".to_owned()],
182
};
183
assert_eq!(value, test.thing_in_and_out().call_baz(&mut store, &value)?);
184
185
Ok(())
186
}
187
}
188
189
mod borrowing_no_duplication {
190
use super::*;
191
wasmtime::component::bindgen!({
192
inline: "
193
package inline:inline;
194
world test {
195
export lists: interface {
196
foo: func(a: list<list<string>>) -> list<list<string>>;
197
}
198
199
export thing-in: interface {
200
record thing {
201
name: string,
202
value: list<string>
203
}
204
205
bar: func(a: thing);
206
}
207
208
export thing-in-and-out: interface {
209
record thing {
210
name: string,
211
value: list<string>
212
}
213
214
baz: func(a: thing) -> thing;
215
}
216
}",
217
ownership: Borrowing {
218
duplicate_if_necessary: false
219
}
220
});
221
222
impl PartialEq for exports::thing_in::Thing<'_> {
223
fn eq(&self, other: &Self) -> bool {
224
self.name == other.name && self.value == other.value
225
}
226
}
227
228
impl PartialEq for exports::thing_in_and_out::Thing {
229
fn eq(&self, other: &Self) -> bool {
230
self.name == other.name && self.value == other.value
231
}
232
}
233
234
#[test]
235
fn borrowing_no_duplication() -> Result<()> {
236
let engine = engine();
237
let component = Component::new(&engine, component())?;
238
239
let linker = Linker::new(&engine);
240
let mut store = Store::new(&engine, ());
241
let test = Test::instantiate(&mut store, &component, &linker)?;
242
243
let value = &[&["a", "b"] as &[_]] as &[_];
244
assert_eq!(value, test.lists().call_foo(&mut store, value)?);
245
246
let value = exports::thing_in::Thing {
247
name: "thing 1",
248
value: &["some value", "another value"],
249
};
250
test.thing_in().call_bar(&mut store, value)?;
251
252
let value = exports::thing_in_and_out::Thing {
253
name: "thing 1".to_owned(),
254
value: vec!["some value".to_owned(), "another value".to_owned()],
255
};
256
assert_eq!(value, test.thing_in_and_out().call_baz(&mut store, &value)?);
257
258
Ok(())
259
}
260
}
261
262
mod borrowing_with_duplication {
263
use super::*;
264
265
wasmtime::component::bindgen!({
266
inline: "
267
package inline:inline;
268
world test {
269
export lists: interface {
270
foo: func(a: list<list<string>>) -> list<list<string>>;
271
}
272
273
export thing-in: interface {
274
record thing {
275
name: string,
276
value: list<string>
277
}
278
279
bar: func(a: thing);
280
}
281
282
export thing-in-and-out: interface {
283
record thing {
284
name: string,
285
value: list<string>
286
}
287
288
baz: func(a: thing) -> thing;
289
}
290
}",
291
ownership: Borrowing {
292
duplicate_if_necessary: true
293
}
294
});
295
296
impl PartialEq for exports::thing_in::Thing<'_> {
297
fn eq(&self, other: &Self) -> bool {
298
self.name == other.name && self.value == other.value
299
}
300
}
301
302
impl PartialEq for exports::thing_in_and_out::ThingResult {
303
fn eq(&self, other: &Self) -> bool {
304
self.name == other.name && self.value == other.value
305
}
306
}
307
308
#[test]
309
fn borrowing_with_duplication() -> Result<()> {
310
let engine = engine();
311
let component = Component::new(&engine, component())?;
312
313
let linker = Linker::new(&engine);
314
let mut store = Store::new(&engine, ());
315
let test = Test::instantiate(&mut store, &component, &linker)?;
316
317
let value = &[&["a", "b"] as &[_]] as &[_];
318
assert_eq!(value, test.lists().call_foo(&mut store, value)?);
319
320
let value = exports::thing_in::Thing {
321
name: "thing 1",
322
value: &["some value", "another value"],
323
};
324
test.thing_in().call_bar(&mut store, value)?;
325
326
let value = exports::thing_in_and_out::ThingParam {
327
name: "thing 1",
328
value: &["some value", "another value"],
329
};
330
assert_eq!(
331
exports::thing_in_and_out::ThingResult {
332
name: "thing 1".to_owned(),
333
value: vec!["some value".to_owned(), "another value".to_owned()],
334
},
335
test.thing_in_and_out().call_baz(&mut store, value)?
336
);
337
338
Ok(())
339
}
340
}
341
342