1;;! gc = true
2;;! bulk_memory = true
3
4(module
5  (table $t 0 externref)
6
7  (func (export "get") (param $i i32) (result externref) (table.get $t (local.get $i)))
8  (func (export "set") (param $i i32) (param $r externref) (table.set $t (local.get $i) (local.get $r)))
9
10  (func (export "grow") (param $sz i32) (param $init externref) (result i32)
11    (table.grow $t (local.get $init) (local.get $sz))
12  )
13  (func (export "size") (result i32) (table.size $t))
14)
15
16(assert_return (invoke "size") (i32.const 0))
17(assert_trap (invoke "set" (i32.const 0) (ref.extern 2)) "out of bounds table access")
18(assert_trap (invoke "get" (i32.const 0)) "out of bounds table access")
19
20(assert_return (invoke "grow" (i32.const 1) (ref.null extern)) (i32.const 0))
21(assert_return (invoke "size") (i32.const 1))
22(assert_return (invoke "get" (i32.const 0)) (ref.null extern))
23(assert_return (invoke "set" (i32.const 0) (ref.extern 2)))
24(assert_return (invoke "get" (i32.const 0)) (ref.extern 2))
25(assert_trap (invoke "set" (i32.const 1) (ref.extern 2)) "out of bounds table access")
26(assert_trap (invoke "get" (i32.const 1)) "out of bounds table access")
27
28(assert_return (invoke "grow" (i32.const 4) (ref.extern 3)) (i32.const 1))
29(assert_return (invoke "size") (i32.const 5))
30(assert_return (invoke "get" (i32.const 0)) (ref.extern 2))
31(assert_return (invoke "set" (i32.const 0) (ref.extern 2)))
32(assert_return (invoke "get" (i32.const 0)) (ref.extern 2))
33(assert_return (invoke "get" (i32.const 1)) (ref.extern 3))
34(assert_return (invoke "get" (i32.const 4)) (ref.extern 3))
35(assert_return (invoke "set" (i32.const 4) (ref.extern 4)))
36(assert_return (invoke "get" (i32.const 4)) (ref.extern 4))
37(assert_trap (invoke "set" (i32.const 5) (ref.extern 2)) "out of bounds table access")
38(assert_trap (invoke "get" (i32.const 5)) "out of bounds table access")
39
40
41;; Reject growing to size outside i32 value range
42(module
43  (table $t 0x10 funcref)
44  (elem declare func $f)
45  (func $f (export "grow") (result i32)
46    (table.grow $t (ref.func $f) (i32.const 0xffff_fff0))
47  )
48)
49
50(assert_return (invoke "grow") (i32.const -1))
51
52
53(module
54  (table $t 0 externref)
55  (func (export "grow") (param i32) (result i32)
56    (table.grow $t (ref.null extern) (local.get 0))
57  )
58)
59
60(assert_return (invoke "grow" (i32.const 0)) (i32.const 0))
61(assert_return (invoke "grow" (i32.const 1)) (i32.const 0))
62(assert_return (invoke "grow" (i32.const 0)) (i32.const 1))
63(assert_return (invoke "grow" (i32.const 2)) (i32.const 1))
64(assert_return (invoke "grow" (i32.const 800)) (i32.const 3))
65
66(module
67  (type $afunc (func))
68  (table $t 0 (ref null $afunc))
69  (func (export "grow") (param i32) (result i32)
70    (table.grow $t (ref.null $afunc) (local.get 0))
71  )
72)
73
74(assert_return (invoke "grow" (i32.const 0)) (i32.const 0))
75(assert_return (invoke "grow" (i32.const 1)) (i32.const 0))
76(assert_return (invoke "grow" (i32.const 0)) (i32.const 1))
77(assert_return (invoke "grow" (i32.const 2)) (i32.const 1))
78(assert_return (invoke "grow" (i32.const 800)) (i32.const 3))
79
80(module
81  (table $t 0 10 externref)
82  (func (export "grow") (param i32) (result i32)
83    (table.grow $t (ref.null extern) (local.get 0))
84  )
85)
86
87(assert_return (invoke "grow" (i32.const 0)) (i32.const 0))
88(assert_return (invoke "grow" (i32.const 1)) (i32.const 0))
89(assert_return (invoke "grow" (i32.const 1)) (i32.const 1))
90(assert_return (invoke "grow" (i32.const 2)) (i32.const 2))
91(assert_return (invoke "grow" (i32.const 6)) (i32.const 4))
92(assert_return (invoke "grow" (i32.const 0)) (i32.const 10))
93(assert_return (invoke "grow" (i32.const 1)) (i32.const -1))
94(assert_return (invoke "grow" (i32.const 0x10000)) (i32.const -1))
95
96
97(module
98  (table $t 10 funcref)
99  (func (export "grow") (param i32) (result i32)
100    (table.grow $t (ref.null func) (local.get 0))
101  )
102  (elem declare func 1)
103  (func (export "check-table-null") (param i32 i32) (result funcref)
104    (local funcref)
105    (local.set 2 (ref.func 1))
106    (block
107      (loop
108        (local.set 2 (table.get $t (local.get 0)))
109        (br_if 1 (i32.eqz (ref.is_null (local.get 2))))
110        (br_if 1 (i32.ge_u (local.get 0) (local.get 1)))
111        (local.set 0 (i32.add (local.get 0) (i32.const 1)))
112        (br_if 0 (i32.le_u (local.get 0) (local.get 1)))
113      )
114    )
115    (local.get 2)
116  )
117)
118
119(assert_return (invoke "check-table-null" (i32.const 0) (i32.const 9)) (ref.null func))
120(assert_return (invoke "grow" (i32.const 10)) (i32.const 10))
121(assert_return (invoke "check-table-null" (i32.const 0) (i32.const 19)) (ref.null func))
122
123
124;; Type errors
125
126(assert_invalid
127  (module
128    (table $t 0 externref)
129    (func $type-init-size-empty-vs-i32-externref (result i32)
130      (table.grow $t)
131    )
132  )
133  "type mismatch"
134)
135(assert_invalid
136  (module
137    (table $t 0 externref)
138    (func $type-size-empty-vs-i32 (result i32)
139      (table.grow $t (ref.null extern))
140    )
141  )
142  "type mismatch"
143)
144(assert_invalid
145  (module
146    (table $t 0 externref)
147    (func $type-init-empty-vs-externref (result i32)
148      (table.grow $t (i32.const 1))
149    )
150  )
151  "type mismatch"
152)
153(assert_invalid
154  (module
155    (table $t 0 externref)
156    (func $type-size-f32-vs-i32 (result i32)
157      (table.grow $t (ref.null extern) (f32.const 1))
158    )
159  )
160  "type mismatch"
161)
162(assert_invalid
163  (module
164    (table $t 0 funcref)
165    (func $type-init-externref-vs-funcref (param $r externref) (result i32)
166      (table.grow $t (local.get $r) (i32.const 1))
167    )
168  )
169  "type mismatch"
170)
171(assert_invalid
172  (module
173    (type $afunc (func))
174    (table $t 0 (ref null $afunc))
175    (func $type-init-funcref-vs-typed-func (param $r funcref) (result i32)
176      (table.grow $t (local.get $r) (i32.const 1))
177    )
178  )
179  "type mismatch"
180)
181
182(assert_invalid
183  (module
184    (table $t 1 externref)
185    (func $type-result-i32-vs-empty
186      (table.grow $t (ref.null extern) (i32.const 0))
187    )
188  )
189  "type mismatch"
190)
191(assert_invalid
192  (module
193    (table $t 1 externref)
194    (func $type-result-i32-vs-f32 (result f32)
195      (table.grow $t (ref.null extern) (i32.const 0))
196    )
197  )
198  "type mismatch"
199)
200