1;;! reference_types = true
2
3(module
4  (type $t0 (func))
5  (func $f1 (type $t0))
6  (func $f2 (type $t0))
7  (func $f3 (type $t0))
8
9  ;; Define two tables of funcref
10  (table $t1 3 funcref)
11  (table $t2 10 funcref)
12
13  ;; Initialize table $t1 with functions $f1, $f2, $f3
14  (elem (i32.const 0) $f1 $f2 $f3)
15
16  ;; Function to fill table $t1 using a function reference from table $t2
17  (func (export "fill") (param $i i32) (param $r i32) (param $n i32)
18    (local $ref funcref)
19    (local.set $ref (table.get $t1 (local.get $r)))
20    (table.fill $t2 (local.get $i) (local.get $ref) (local.get $n))
21  )
22
23  (func (export "get") (param $i i32) (result funcref)
24    (table.get $t2 (local.get $i))
25  )
26)
27
28(assert_return (invoke "get" (i32.const 1)) (ref.null func))
29(assert_return (invoke "get" (i32.const 2)) (ref.null func))
30(assert_return (invoke "get" (i32.const 3)) (ref.null func))
31(assert_return (invoke "get" (i32.const 4)) (ref.null func))
32(assert_return (invoke "get" (i32.const 5)) (ref.null func))
33
34(assert_return (invoke "fill" (i32.const 2) (i32.const 0) (i32.const 3)))
35(assert_return (invoke "get" (i32.const 1)) (ref.null func))
36(assert_return (invoke "get" (i32.const 2)) (ref.func 0))
37(assert_return (invoke "get" (i32.const 3)) (ref.func 0))
38(assert_return (invoke "get" (i32.const 4)) (ref.func 0))
39(assert_return (invoke "get" (i32.const 5)) (ref.null func))
40
41(assert_return (invoke "fill" (i32.const 4) (i32.const 1) (i32.const 2)))
42(assert_return (invoke "get" (i32.const 3)) (ref.func 0))
43(assert_return (invoke "get" (i32.const 4)) (ref.func 1))
44(assert_return (invoke "get" (i32.const 5)) (ref.func 1))
45(assert_return (invoke "get" (i32.const 6)) (ref.null func))
46
47(assert_return (invoke "fill" (i32.const 4) (i32.const 2) (i32.const 0)))
48(assert_return (invoke "get" (i32.const 3)) (ref.func 0))
49(assert_return (invoke "get" (i32.const 4)) (ref.func 1))
50(assert_return (invoke "get" (i32.const 5)) (ref.func 1))
51
52(assert_return (invoke "fill" (i32.const 8) (i32.const 0) (i32.const 2)))
53(assert_return (invoke "get" (i32.const 7)) (ref.null func))
54(assert_return (invoke "get" (i32.const 8)) (ref.func 0))
55(assert_return (invoke "get" (i32.const 9)) (ref.func 0))
56
57(assert_return (invoke "fill" (i32.const 9) (i32.const 2) (i32.const 1)))
58(assert_return (invoke "get" (i32.const 8)) (ref.func 0))
59(assert_return (invoke "get" (i32.const 9)) (ref.func 2))
60
61(assert_return (invoke "fill" (i32.const 10) (i32.const 1) (i32.const 0)))
62(assert_return (invoke "get" (i32.const 9)) (ref.func 2))
63
64(assert_trap
65  (invoke "fill" (i32.const 8) (i32.const 0) (i32.const 3))
66  "out of bounds table access"
67)
68
69(module $t
70  (table (export "t") 1 funcref)
71)
72
73(module
74  (import "t" "t" (table $t1 1 funcref))
75  (table $t2 2 funcref)
76
77  (func (export "fill1") (param i32 funcref i32)
78    local.get 0
79    local.get 1
80    local.get 2
81    table.fill $t1)
82
83  (func (export "fill2") (param i32 funcref i32)
84    local.get 0
85    local.get 1
86    local.get 2
87    table.fill $t2)
88)
89
90(assert_return (invoke "fill1" (i32.const 0) (ref.null func) (i32.const 0)))
91(assert_return (invoke "fill1" (i32.const 0) (ref.null func) (i32.const 1)))
92(assert_return (invoke "fill1" (i32.const 1) (ref.null func) (i32.const 0)))
93(assert_trap (invoke "fill1" (i32.const 2) (ref.null func) (i32.const 0))
94  "out of bounds table access")
95
96(assert_return (invoke "fill2" (i32.const 0) (ref.null func) (i32.const 0)))
97(assert_return (invoke "fill2" (i32.const 0) (ref.null func) (i32.const 1)))
98(assert_return (invoke "fill2" (i32.const 0) (ref.null func) (i32.const 2)))
99(assert_return (invoke "fill2" (i32.const 1) (ref.null func) (i32.const 0)))
100(assert_return (invoke "fill2" (i32.const 1) (ref.null func) (i32.const 1)))
101(assert_return (invoke "fill2" (i32.const 2) (ref.null func) (i32.const 0)))
102(assert_trap (invoke "fill2" (i32.const 3) (ref.null func) (i32.const 0))
103  "out of bounds table access")
104