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