Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/tests/all/table.rs
1690 views
1
use wasmtime::*;
2
3
#[test]
4
fn get_none() {
5
let mut store = Store::<()>::default();
6
let ty = TableType::new(RefType::FUNCREF, 1, None);
7
let table = Table::new(&mut store, ty, Ref::Func(None)).unwrap();
8
match table.get(&mut store, 0) {
9
Some(Ref::Func(None)) => {}
10
_ => panic!(),
11
}
12
assert!(table.get(&mut store, 1).is_none());
13
}
14
15
#[test]
16
fn fill_wrong() {
17
let mut store = Store::<()>::default();
18
let ty = TableType::new(RefType::FUNCREF, 1, None);
19
let table = Table::new(&mut store, ty, Ref::Func(None)).unwrap();
20
assert_eq!(
21
table
22
.fill(&mut store, 0, Ref::Extern(None), 1)
23
.map_err(|e| e.to_string())
24
.unwrap_err(),
25
"type mismatch: value does not match table element type"
26
);
27
28
let ty = TableType::new(RefType::EXTERNREF, 1, None);
29
let table = Table::new(&mut store, ty, Ref::Extern(None)).unwrap();
30
assert_eq!(
31
table
32
.fill(&mut store, 0, Ref::Func(None), 1)
33
.map_err(|e| e.to_string())
34
.unwrap_err(),
35
"type mismatch: value does not match table element type"
36
);
37
}
38
39
#[test]
40
fn copy_wrong() {
41
let mut store = Store::<()>::default();
42
let ty = TableType::new(RefType::FUNCREF, 1, None);
43
let table1 = Table::new(&mut store, ty, Ref::Func(None)).unwrap();
44
let ty = TableType::new(RefType::EXTERNREF, 1, None);
45
let table2 = Table::new(&mut store, ty, Ref::Extern(None)).unwrap();
46
assert_eq!(
47
Table::copy(&mut store, &table1, 0, &table2, 0, 1)
48
.map_err(|e| e.to_string())
49
.unwrap_err(),
50
"type mismatch: source table's element type does not match destination table's element type"
51
);
52
}
53
54
#[test]
55
#[cfg_attr(miri, ignore)]
56
fn null_elem_segment_works_with_imported_table() -> Result<()> {
57
let mut store = Store::<()>::default();
58
let ty = TableType::new(RefType::FUNCREF, 1, None);
59
let table = Table::new(&mut store, ty, Ref::Func(None))?;
60
let module = Module::new(
61
store.engine(),
62
r#"
63
(module
64
(import "" "" (table (;0;) 1 funcref))
65
(func
66
i32.const 0
67
table.get 0
68
drop
69
)
70
(start 0)
71
(elem (;0;) (i32.const 0) funcref (ref.null func))
72
)
73
"#,
74
)?;
75
Instance::new(&mut store, &module, &[table.into()])?;
76
Ok(())
77
}
78
79
#[test]
80
fn i31ref_table_new() -> Result<()> {
81
let mut config = Config::new();
82
config.wasm_function_references(true);
83
config.wasm_gc(true);
84
85
let engine = Engine::new(&config)?;
86
let mut store = Store::new(&engine, ());
87
88
for (elem_ty, inits) in [
89
(
90
RefType::I31REF,
91
vec![
92
Ref::Any(None),
93
AnyRef::from_i31(&mut store, I31::default()).into(),
94
],
95
),
96
(
97
RefType::new(false, HeapType::I31),
98
vec![AnyRef::from_i31(&mut store, I31::default()).into()],
99
),
100
] {
101
let table_ty = TableType::new(elem_ty, 10, None);
102
for init in inits {
103
Table::new(&mut store, table_ty.clone(), init)?;
104
}
105
}
106
107
Ok(())
108
}
109
110
#[test]
111
fn i31ref_table_get() -> Result<()> {
112
let mut config = Config::new();
113
config.wasm_function_references(true);
114
config.wasm_gc(true);
115
116
let engine = Engine::new(&config)?;
117
let mut store = Store::new(&engine, ());
118
119
for (elem_ty, inits) in [
120
(
121
RefType::I31REF,
122
vec![
123
Ref::Any(None),
124
AnyRef::from_i31(&mut store, I31::default()).into(),
125
],
126
),
127
(
128
RefType::new(false, HeapType::I31),
129
vec![AnyRef::from_i31(&mut store, I31::default()).into()],
130
),
131
] {
132
let table_ty = TableType::new(elem_ty, 10, None);
133
for init in inits {
134
let table = Table::new(&mut store, table_ty.clone(), init.clone())?;
135
for i in 0..10 {
136
let val = table.get(&mut store, i).unwrap();
137
assert_eq!(init.is_null(), val.is_null());
138
assert_eq!(
139
init.as_any()
140
.expect("is anyref")
141
.map(|a| a.as_i31(&store).expect("is in scope")),
142
val.as_any()
143
.expect("is anyref")
144
.map(|a| a.as_i31(&store).expect("is in scope"))
145
)
146
}
147
}
148
}
149
150
Ok(())
151
}
152
153
#[test]
154
fn i31ref_table_set() -> Result<()> {
155
let mut config = Config::new();
156
config.wasm_function_references(true);
157
config.wasm_gc(true);
158
159
let engine = Engine::new(&config)?;
160
let mut store = Store::new(&engine, ());
161
162
for (elem_ty, inits, vals) in [
163
(
164
RefType::I31REF,
165
vec![
166
Ref::Any(None),
167
AnyRef::from_i31(&mut store, I31::default()).into(),
168
],
169
vec![
170
Ref::Any(None),
171
AnyRef::from_i31(&mut store, I31::wrapping_u32(42)).into(),
172
],
173
),
174
(
175
RefType::new(false, HeapType::I31),
176
vec![AnyRef::from_i31(&mut store, I31::default()).into()],
177
vec![AnyRef::from_i31(&mut store, I31::wrapping_u32(42)).into()],
178
),
179
] {
180
let table_ty = TableType::new(elem_ty, 10, None);
181
for init in inits {
182
for expected in vals.clone() {
183
let table = Table::new(&mut store, table_ty.clone(), init.clone())?;
184
for i in 0..10 {
185
table.set(&mut store, i, expected.clone())?;
186
let actual = table.get(&mut store, i).unwrap();
187
assert_eq!(expected.is_null(), actual.is_null());
188
assert_eq!(
189
expected
190
.as_any()
191
.expect("is anyref")
192
.map(|a| a.as_i31(&store).expect("is in scope")),
193
actual
194
.as_any()
195
.expect("is anyref")
196
.map(|a| a.as_i31(&store).expect("is in scope"))
197
)
198
}
199
}
200
}
201
}
202
203
Ok(())
204
}
205
206
#[test]
207
fn i31ref_table_grow() -> Result<()> {
208
let mut config = Config::new();
209
config.wasm_function_references(true);
210
config.wasm_gc(true);
211
212
let engine = Engine::new(&config)?;
213
let mut store = Store::new(&engine, ());
214
215
for (elem_ty, init) in [
216
(RefType::I31REF, Ref::Any(None)),
217
(
218
RefType::new(false, HeapType::I31),
219
AnyRef::from_i31(&mut store, I31::default()).into(),
220
),
221
] {
222
let table_ty = TableType::new(elem_ty, 10, None);
223
let table = Table::new(&mut store, table_ty, init)?;
224
assert_eq!(table.size(&store), 10);
225
for i in 10..20 {
226
assert!(table.get(&mut store, i).is_none());
227
}
228
let expected = I31::wrapping_u32(42);
229
let grow_val = AnyRef::from_i31(&mut store, expected);
230
table.grow(&mut store, 10, grow_val.into())?;
231
for i in 10..20 {
232
let actual = table.get(&mut store, i).unwrap();
233
assert_eq!(
234
actual
235
.as_any()
236
.expect("is anyref")
237
.expect("is non null")
238
.as_i31(&store)
239
.expect("is in scope")
240
.expect("is i31"),
241
expected,
242
);
243
}
244
assert!(table.get(&mut store, 20).is_none());
245
}
246
247
Ok(())
248
}
249
250
#[test]
251
fn i31ref_table_fill() -> Result<()> {
252
let mut config = Config::new();
253
config.wasm_function_references(true);
254
config.wasm_gc(true);
255
256
let engine = Engine::new(&config)?;
257
let mut store = Store::new(&engine, ());
258
259
let table_ty = TableType::new(RefType::I31REF, 10, None);
260
let table = Table::new(&mut store, table_ty, Ref::Any(None))?;
261
262
let expected = I31::wrapping_u32(42);
263
let fill_val = AnyRef::from_i31(&mut store, expected);
264
let dst = 3;
265
let len = 4;
266
table.fill(&mut store, dst, fill_val.into(), len)?;
267
268
for i in 0..dst {
269
let actual = table.get(&mut store, i).unwrap();
270
assert!(actual.as_any().expect("is anyref").is_none());
271
}
272
for i in dst..dst + len {
273
let actual = table.get(&mut store, i).unwrap();
274
assert_eq!(
275
actual
276
.as_any()
277
.expect("is anyref")
278
.expect("is non null")
279
.as_i31(&store)
280
.expect("is in scope")
281
.expect("is i31"),
282
expected,
283
);
284
}
285
for i in dst + len..10 {
286
let actual = table.get(&mut store, i).unwrap();
287
assert!(actual.as_any().expect("is anyref").is_none());
288
}
289
290
Ok(())
291
}
292
293
#[test]
294
fn i31ref_table_copy() -> Result<()> {
295
let mut config = Config::new();
296
config.wasm_function_references(true);
297
config.wasm_gc(true);
298
299
let engine = Engine::new(&config)?;
300
let mut store = Store::new(&engine, ());
301
302
let table_ty = TableType::new(RefType::I31REF, 10, None);
303
let dst_table = Table::new(&mut store, table_ty.clone(), Ref::Any(None))?;
304
305
let expected = I31::wrapping_u32(42);
306
let init_val = AnyRef::from_i31(&mut store, expected);
307
let src_table = Table::new(&mut store, table_ty, init_val.into())?;
308
309
let dst_index = 1;
310
let src_index = 2;
311
let len = 3;
312
Table::copy(
313
&mut store, &dst_table, dst_index, &src_table, src_index, len,
314
)?;
315
316
for i in 0..dst_index {
317
let actual = dst_table.get(&mut store, i).unwrap();
318
assert!(actual.as_any().expect("is anyref").is_none());
319
}
320
for i in dst_index..dst_index + len {
321
let actual = dst_table.get(&mut store, i).unwrap();
322
assert_eq!(
323
actual
324
.as_any()
325
.expect("is anyref")
326
.expect("is non null")
327
.as_i31(&store)
328
.expect("is in scope")
329
.expect("is i31"),
330
expected,
331
);
332
}
333
for i in dst_index + len..10 {
334
let actual = dst_table.get(&mut store, i).unwrap();
335
assert!(actual.as_any().expect("is anyref").is_none());
336
}
337
338
Ok(())
339
}
340
341
#[test]
342
fn host_table_keep_type_registration() -> Result<()> {
343
let engine = Engine::default();
344
let mut store = Store::new(&engine, ());
345
346
let ty = FuncType::new(&engine, [], []);
347
348
let t = Table::new(
349
&mut store,
350
TableType::new(RefType::new(true, HeapType::ConcreteFunc(ty)), 1, None),
351
Ref::Func(None),
352
)?;
353
354
{
355
let _ty2 = FuncType::new(&engine, [ValType::I32], [ValType::I32]);
356
let ty = t.ty(&store);
357
let fty = ty.element().heap_type().unwrap_concrete_func();
358
assert!(fty.params().len() == 0);
359
assert!(fty.results().len() == 0);
360
}
361
362
let ty = t.ty(&store);
363
let fty = ty.element().heap_type().unwrap_concrete_func();
364
assert!(fty.params().len() == 0);
365
assert!(fty.results().len() == 0);
366
367
Ok(())
368
}
369
370
#[test]
371
fn gc_store_with_table_initializers() -> Result<()> {
372
let mut config = Config::new();
373
config.wasm_gc(true);
374
config.wasm_function_references(true);
375
let engine = Engine::new(&config)?;
376
377
let test = |wat: &str| -> Result<()> {
378
let module = Module::new(&engine, wat)?;
379
Instance::new(&mut Store::new(&engine, ()), &module, &[])?;
380
Ok(())
381
};
382
383
test("(module (table 1 i31ref))")?;
384
test("(module (table 1 i31ref (ref.i31 (i32.const 1))))")?;
385
test("(module (table 1 i31ref (ref.null i31)))")?;
386
387
Ok(())
388
}
389
390