vxx2 / vlib / wasm / tests / table_test.v
97 lines · 78 sloc · 2.27 KB · 863a2090f8eda7dc75e061b26e0bca252f167e24
Raw
1module main
2
3import wasm
4
5// A funcref table populated by an active element segment, dispatched through
6// `call_indirect`.
7fn test_call_indirect() {
8 mut m := wasm.Module{}
9
10 mut f0 := m.new_function('f0', [], [.i32_t])
11 {
12 f0.i32_const(10)
13 }
14 m.commit(f0, false)
15
16 mut f1 := m.new_function('f1', [], [.i32_t])
17 {
18 f1.i32_const(20)
19 }
20 m.commit(f1, false)
21
22 tidx := m.assign_table('__indirect_function_table', true, .funcref_t, 2, none)
23 m.new_active_element(tidx, 0, ['f0', 'f1'])
24
25 sig := m.new_functype(wasm.FuncType{
26 parameters: []wasm.ValType{}
27 results: [.i32_t]
28 })
29
30 mut dispatch := m.new_function('dispatch', [.i32_t], [.i32_t])
31 {
32 dispatch.local_get(0) // table index argument
33 dispatch.call_indirect(sig, tidx)
34 }
35 m.commit(dispatch, true)
36
37 validate(m.compile()) or { panic(err) }
38}
39
40// A growable externref table exercised with table.size/grow/set/get.
41fn test_externref_table() {
42 mut m := wasm.Module{}
43
44 tidx := m.assign_table('refs', true, .externref_t, 1, none)
45
46 // grow by 3 (filling with null); leaves the previous size on the stack
47 mut grow := m.new_function('grow_refs', [], [.i32_t])
48 {
49 grow.ref_null(.externref_t) // init value
50 grow.i32_const(3) // n
51 grow.table_grow(tidx)
52 }
53 m.commit(grow, true)
54
55 mut size := m.new_function('refs_size', [], [.i32_t])
56 {
57 size.table_size(tidx)
58 }
59 m.commit(size, true)
60
61 // refs[0] = null, then read it back and report whether it is null
62 mut roundtrip := m.new_function('roundtrip', [], [.i32_t])
63 {
64 roundtrip.i32_const(0) // index
65 roundtrip.ref_null(.externref_t) // value
66 roundtrip.table_set(tidx)
67 roundtrip.i32_const(0) // index
68 roundtrip.table_get(tidx)
69 roundtrip.ref_is_null(.externref_t)
70 }
71 m.commit(roundtrip, true)
72
73 validate(m.compile()) or { panic(err) }
74}
75
76// A declarative element segment makes `ref.func` to a non-exported, non-tabled
77// function validate. Without the segment, validation would fail.
78fn test_declarative_element() {
79 mut m := wasm.Module{}
80
81 mut hidden := m.new_function('f_hidden', [], [.i32_t])
82 {
83 hidden.i32_const(42)
84 }
85 m.commit(hidden, false) // NOT exported
86
87 m.new_declarative_element(['f_hidden'])
88
89 mut probe := m.new_function('probe', [], [.i32_t])
90 {
91 probe.ref_func('f_hidden')
92 probe.ref_is_null(.funcref_t)
93 }
94 m.commit(probe, true)
95
96 validate(m.compile()) or { panic(err) }
97}
98