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