1;;! gc = true
2
3(module
4  (type $res-i32 (func (result i32)))
5  (table $t2 1 externref)
6  (table $t3 2 funcref)
7  (table $t4 1 (ref null $res-i32))
8  (elem (table $t3) (i32.const 1) func $returns-five)
9  (func $returns-five (result i32) (i32.const 5))
10
11  (func (export "get-externref") (param $i i32) (result externref)
12    (table.get $t2 (local.get $i))
13  )
14  (func $f3 (export "get-funcref") (param $i i32) (result funcref)
15    (table.get $t3 (local.get $i))
16  )
17  (func $f4 (export "get-typed-func") (param $i i32) (result (ref null $res-i32))
18    (table.get $t4 (local.get $i))
19  )
20
21  (func (export "set-externref") (param $i i32) (param $r externref)
22    (table.set $t2 (local.get $i) (local.get $r))
23  )
24  (func (export "set-funcref") (param $i i32) (param $r funcref)
25    (table.set $t3 (local.get $i) (local.get $r))
26  )
27  (func (export "set-funcref-from") (param $i i32) (param $j i32)
28    (table.set $t3 (local.get $i) (table.get $t3 (local.get $j)))
29  )
30  (func $f5 (export "set-typed-func") (param $i i32) (param $r (ref $res-i32))
31    (table.set $t4 (local.get $i) (local.get $r))
32  )
33
34  (func (export "is_null-funcref") (param $i i32) (result i32)
35    (ref.is_null (call $f3 (local.get $i)))
36  )
37  (func (export "is_null-typed-func") (param $i i32) (result i32)
38    (ref.is_null (call $f4 (local.get $i)))
39  )
40  (func (export "set-returns-five") (param $i i32)
41    (call $f5 (local.get $i) (ref.func $returns-five))
42  )
43  (func (export "get-typed-and-call") (param $i i32) (result i32) (call_ref $res-i32 (call $f4 (local.get $i))))
44)
45
46(assert_return (invoke "get-externref" (i32.const 0)) (ref.null extern))
47(assert_return (invoke "set-externref" (i32.const 0) (ref.extern 1)))
48(assert_return (invoke "get-externref" (i32.const 0)) (ref.extern 1))
49(assert_return (invoke "set-externref" (i32.const 0) (ref.null extern)))
50(assert_return (invoke "get-externref" (i32.const 0)) (ref.null extern))
51
52(assert_return (invoke "get-funcref" (i32.const 0)) (ref.null func))
53(assert_return (invoke "set-funcref-from" (i32.const 0) (i32.const 1)))
54(assert_return (invoke "is_null-funcref" (i32.const 0)) (i32.const 0))
55(assert_return (invoke "set-funcref" (i32.const 0) (ref.null func)))
56(assert_return (invoke "get-funcref" (i32.const 0)) (ref.null func))
57
58(assert_return (invoke "is_null-typed-func" (i32.const 0)) (i32.const 1))
59(invoke "set-returns-five" (i32.const 0))
60(assert_return (invoke "get-typed-and-call" (i32.const 0)) (i32.const 5))
61
62(assert_trap (invoke "set-externref" (i32.const 2) (ref.null extern)) "out of bounds table access")
63(assert_trap (invoke "set-funcref" (i32.const 3) (ref.null func)) "out of bounds table access")
64(assert_trap (invoke "set-returns-five" (i32.const 2)) "out of bounds table access")
65(assert_trap (invoke "set-externref" (i32.const -1) (ref.null extern)) "out of bounds table access")
66(assert_trap (invoke "set-funcref" (i32.const -1) (ref.null func)) "out of bounds table access")
67(assert_trap (invoke "set-returns-five" (i32.const -1)) "out of bounds table access")
68
69(assert_trap (invoke "set-externref" (i32.const 2) (ref.extern 0)) "out of bounds table access")
70(assert_trap (invoke "set-funcref-from" (i32.const 3) (i32.const 1)) "out of bounds table access")
71(assert_trap (invoke "set-externref" (i32.const -1) (ref.extern 0)) "out of bounds table access")
72(assert_trap (invoke "set-funcref-from" (i32.const -1) (i32.const 1)) "out of bounds table access")
73
74
75;; Type errors
76
77(assert_invalid
78  (module
79    (table $t 10 externref)
80    (func $type-index-value-empty-vs-i32-externref
81      (table.set $t)
82    )
83  )
84  "type mismatch"
85)
86(assert_invalid
87  (module
88    (table $t 10 externref)
89    (func $type-index-empty-vs-i32
90      (table.set $t (ref.null extern))
91    )
92  )
93  "type mismatch"
94)
95(assert_invalid
96  (module
97    (table $t 10 externref)
98    (func $type-value-empty-vs-externref
99      (table.set $t (i32.const 1))
100    )
101  )
102  "type mismatch"
103)
104(assert_invalid
105  (module
106    (table $t 10 externref)
107    (func $type-size-f32-vs-i32
108      (table.set $t (f32.const 1) (ref.null extern))
109    )
110  )
111  "type mismatch"
112)
113(assert_invalid
114  (module
115    (table $t 10 funcref)
116    (func $type-value-externref-vs-funcref (param $r externref)
117      (table.set $t (i32.const 1) (local.get $r))
118    )
119  )
120  "type mismatch"
121)
122
123(assert_invalid
124  (module
125    (table $t1 1 externref)
126    (table $t2 1 funcref)
127    (func $type-value-externref-vs-funcref-multi (param $r externref)
128      (table.set $t2 (i32.const 0) (local.get $r))
129    )
130  )
131  "type mismatch"
132)
133
134(assert_invalid
135  (module
136    (table $t 10 externref)
137    (func $type-result-empty-vs-num (result i32)
138      (table.set $t (i32.const 0) (ref.null extern))
139    )
140  )
141  "type mismatch"
142)
143