Skip to content

Commit e71ba20

Browse files
authored
Update call_ref format: add type annotation. (bytecodealliance#752)
1 parent df39411 commit e71ba20

8 files changed

Lines changed: 781 additions & 3 deletions

File tree

crates/wast/src/core/expr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,8 +522,8 @@ instructions! {
522522
ReturnCallIndirect(CallIndirect<'a>) : [0x13] : "return_call_indirect",
523523

524524
// function-references proposal
525-
CallRef : [0x14] : "call_ref",
526-
ReturnCallRef : [0x15] : "return_call_ref",
525+
CallRef(HeapType<'a>) : [0x14] : "call_ref",
526+
ReturnCallRef(HeapType<'a>) : [0x15] : "return_call_ref",
527527
FuncBind(FuncBindType<'a>) : [0x16] : "func.bind",
528528
Let(LetType<'a>) : [0x17] : "let",
529529

crates/wast/src/core/resolve/names.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,9 @@ impl<'a, 'b> ExprResolver<'a, 'b> {
646646
self.resolver.resolve(&mut a.src_array, Ns::Type)?;
647647
}
648648

649-
RefNull(ty) => self.resolver.resolve_heaptype(ty)?,
649+
RefNull(ty) | CallRef(ty) | ReturnCallRef(ty) => {
650+
self.resolver.resolve_heaptype(ty)?
651+
}
650652

651653
_ => {}
652654
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
(module
2+
(type $t (func (result i32)))
3+
4+
(func $nn (param $r (ref $t)) (result i32)
5+
(call_ref $t
6+
(block $l (result (ref $t))
7+
(br_on_non_null $l (local.get $r))
8+
(return (i32.const -1))
9+
)
10+
)
11+
)
12+
(func $n (param $r (ref null $t)) (result i32)
13+
(call_ref $t
14+
(block $l (result (ref $t))
15+
(br_on_non_null $l (local.get $r))
16+
(return (i32.const -1))
17+
)
18+
)
19+
)
20+
21+
(elem func $f)
22+
(func $f (result i32) (i32.const 7))
23+
24+
(func (export "nullable-null") (result i32) (call $n (ref.null $t)))
25+
(func (export "nonnullable-f") (result i32) (call $nn (ref.func $f)))
26+
(func (export "nullable-f") (result i32) (call $n (ref.func $f)))
27+
28+
(func (export "unreachable") (result i32)
29+
(block $l
30+
(return (call_ref $t (br_on_null $l (unreachable))))
31+
)
32+
(i32.const -1)
33+
)
34+
)
35+
36+
(assert_trap (invoke "unreachable") "unreachable")
37+
38+
(assert_return (invoke "nullable-null") (i32.const -1))
39+
(assert_return (invoke "nonnullable-f") (i32.const 7))
40+
(assert_return (invoke "nullable-f") (i32.const 7))
41+
42+
(module
43+
(type $t (func))
44+
(func (param $r (ref null $t)) (drop (block (result (ref $t)) (br_on_non_null 0 (local.get $r)) (unreachable))))
45+
(func (param $r (ref null func)) (drop (block (result (ref func)) (br_on_non_null 0 (local.get $r)) (unreachable))))
46+
(func (param $r (ref null extern)) (drop (block (result (ref extern)) (br_on_non_null 0 (local.get $r)) (unreachable))))
47+
)
48+
49+
50+
(module
51+
(type $t (func (param i32) (result i32)))
52+
(elem func $f)
53+
(func $f (param i32) (result i32) (i32.mul (local.get 0) (local.get 0)))
54+
55+
(func $a (param $n i32) (param $r (ref null $t)) (result i32)
56+
(call_ref $t
57+
(block $l (result i32 (ref $t))
58+
(return (br_on_non_null $l (local.get $n) (local.get $r)))
59+
)
60+
)
61+
)
62+
63+
(func (export "args-null") (param $n i32) (result i32)
64+
(call $a (local.get $n) (ref.null $t))
65+
)
66+
(func (export "args-f") (param $n i32) (result i32)
67+
(call $a (local.get $n) (ref.func $f))
68+
)
69+
)
70+
71+
(assert_return (invoke "args-null" (i32.const 3)) (i32.const 3))
72+
(assert_return (invoke "args-f" (i32.const 3)) (i32.const 9))
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
(module
2+
(type $t (func (result i32)))
3+
4+
(func $nn (param $r (ref $t)) (result i32)
5+
(block $l
6+
(return (call_ref $t (br_on_null $l (local.get $r))))
7+
)
8+
(i32.const -1)
9+
)
10+
(func $n (param $r (ref null $t)) (result i32)
11+
(block $l
12+
(return (call_ref $t (br_on_null $l (local.get $r))))
13+
)
14+
(i32.const -1)
15+
)
16+
17+
(elem func $f)
18+
(func $f (result i32) (i32.const 7))
19+
20+
(func (export "nullable-null") (result i32) (call $n (ref.null $t)))
21+
(func (export "nonnullable-f") (result i32) (call $nn (ref.func $f)))
22+
(func (export "nullable-f") (result i32) (call $n (ref.func $f)))
23+
24+
(func (export "unreachable") (result i32)
25+
(block $l
26+
(return (call_ref $t (br_on_null $l (unreachable))))
27+
)
28+
(i32.const -1)
29+
)
30+
)
31+
32+
(assert_trap (invoke "unreachable") "unreachable")
33+
34+
(assert_return (invoke "nullable-null") (i32.const -1))
35+
(assert_return (invoke "nonnullable-f") (i32.const 7))
36+
(assert_return (invoke "nullable-f") (i32.const 7))
37+
38+
(module
39+
(type $t (func))
40+
(func (param $r (ref null $t)) (drop (br_on_null 0 (local.get $r))))
41+
(func (param $r (ref null func)) (drop (br_on_null 0 (local.get $r))))
42+
(func (param $r (ref null extern)) (drop (br_on_null 0 (local.get $r))))
43+
)
44+
45+
46+
(module
47+
(type $t (func (param i32) (result i32)))
48+
(elem func $f)
49+
(func $f (param i32) (result i32) (i32.mul (local.get 0) (local.get 0)))
50+
51+
(func $a (param $n i32) (param $r (ref null $t)) (result i32)
52+
(block $l (result i32)
53+
(return (call_ref $t (br_on_null $l (local.get $n) (local.get $r))))
54+
)
55+
)
56+
57+
(func (export "args-null") (param $n i32) (result i32)
58+
(call $a (local.get $n) (ref.null $t))
59+
)
60+
(func (export "args-f") (param $n i32) (result i32)
61+
(call $a (local.get $n) (ref.func $f))
62+
)
63+
)
64+
65+
(assert_return (invoke "args-null" (i32.const 3)) (i32.const 3))
66+
(assert_return (invoke "args-f" (i32.const 3)) (i32.const 9))
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
(module
2+
(type $ii (func (param i32) (result i32)))
3+
4+
(func $apply (param $f (ref $ii)) (param $x i32) (result i32)
5+
(call_ref $ii (local.get $x) (local.get $f))
6+
)
7+
8+
(func $f (type $ii) (i32.mul (local.get 0) (local.get 0)))
9+
(func $g (type $ii) (i32.sub (i32.const 0) (local.get 0)))
10+
11+
(elem declare func $f $g)
12+
13+
(func (export "run") (param $x i32) (result i32)
14+
(local $rf (ref null $ii))
15+
(local $rg (ref null $ii))
16+
(local.set $rf (ref.func $f))
17+
(local.set $rg (ref.func $g))
18+
(call_ref $ii (call_ref $ii (local.get $x) (local.get $rf)) (local.get $rg))
19+
)
20+
21+
(func (export "null") (result i32)
22+
(call_ref $ii (i32.const 1) (ref.null $ii))
23+
)
24+
25+
;; Recursion
26+
27+
(type $ll (func (param i64) (result i64)))
28+
(type $lll (func (param i64 i64) (result i64)))
29+
30+
(elem declare func $fac)
31+
(global $fac (ref $ll) (ref.func $fac))
32+
33+
(func $fac (export "fac") (type $ll)
34+
(if (result i64) (i64.eqz (local.get 0))
35+
(then (i64.const 1))
36+
(else
37+
(i64.mul
38+
(local.get 0)
39+
(call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fac))
40+
)
41+
)
42+
)
43+
)
44+
45+
(elem declare func $fac-acc)
46+
(global $fac-acc (ref $lll) (ref.func $fac-acc))
47+
48+
(func $fac-acc (export "fac-acc") (type $lll)
49+
(if (result i64) (i64.eqz (local.get 0))
50+
(then (local.get 1))
51+
(else
52+
(call_ref $lll
53+
(i64.sub (local.get 0) (i64.const 1))
54+
(i64.mul (local.get 0) (local.get 1))
55+
(global.get $fac-acc)
56+
)
57+
)
58+
)
59+
)
60+
61+
(elem declare func $fib)
62+
(global $fib (ref $ll) (ref.func $fib))
63+
64+
(func $fib (export "fib") (type $ll)
65+
(if (result i64) (i64.le_u (local.get 0) (i64.const 1))
66+
(then (i64.const 1))
67+
(else
68+
(i64.add
69+
(call_ref $ll (i64.sub (local.get 0) (i64.const 2)) (global.get $fib))
70+
(call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fib))
71+
)
72+
)
73+
)
74+
)
75+
76+
(elem declare func $even $odd)
77+
(global $even (ref $ll) (ref.func $even))
78+
(global $odd (ref $ll) (ref.func $odd))
79+
80+
(func $even (export "even") (type $ll)
81+
(if (result i64) (i64.eqz (local.get 0))
82+
(then (i64.const 44))
83+
(else (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $odd)))
84+
)
85+
)
86+
(func $odd (export "odd") (type $ll)
87+
(if (result i64) (i64.eqz (local.get 0))
88+
(then (i64.const 99))
89+
(else (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $even)))
90+
)
91+
)
92+
)
93+
94+
(assert_return (invoke "run" (i32.const 0)) (i32.const 0))
95+
(assert_return (invoke "run" (i32.const 3)) (i32.const -9))
96+
97+
(assert_trap (invoke "null") "null function")
98+
99+
(assert_return (invoke "fac" (i64.const 0)) (i64.const 1))
100+
(assert_return (invoke "fac" (i64.const 1)) (i64.const 1))
101+
(assert_return (invoke "fac" (i64.const 5)) (i64.const 120))
102+
(assert_return (invoke "fac" (i64.const 25)) (i64.const 7034535277573963776))
103+
(assert_return (invoke "fac-acc" (i64.const 0) (i64.const 1)) (i64.const 1))
104+
(assert_return (invoke "fac-acc" (i64.const 1) (i64.const 1)) (i64.const 1))
105+
(assert_return (invoke "fac-acc" (i64.const 5) (i64.const 1)) (i64.const 120))
106+
(assert_return
107+
(invoke "fac-acc" (i64.const 25) (i64.const 1))
108+
(i64.const 7034535277573963776)
109+
)
110+
111+
(assert_return (invoke "fib" (i64.const 0)) (i64.const 1))
112+
(assert_return (invoke "fib" (i64.const 1)) (i64.const 1))
113+
(assert_return (invoke "fib" (i64.const 2)) (i64.const 2))
114+
(assert_return (invoke "fib" (i64.const 5)) (i64.const 8))
115+
(assert_return (invoke "fib" (i64.const 20)) (i64.const 10946))
116+
117+
(assert_return (invoke "even" (i64.const 0)) (i64.const 44))
118+
(assert_return (invoke "even" (i64.const 1)) (i64.const 99))
119+
(assert_return (invoke "even" (i64.const 100)) (i64.const 44))
120+
(assert_return (invoke "even" (i64.const 77)) (i64.const 99))
121+
(assert_return (invoke "odd" (i64.const 0)) (i64.const 99))
122+
(assert_return (invoke "odd" (i64.const 1)) (i64.const 44))
123+
(assert_return (invoke "odd" (i64.const 200)) (i64.const 99))
124+
(assert_return (invoke "odd" (i64.const 77)) (i64.const 44))
125+
126+
127+
;; Unreachable typing.
128+
129+
(module
130+
(type $t (func))
131+
(func (export "unreachable") (result i32)
132+
(unreachable)
133+
(call_ref $t)
134+
)
135+
)
136+
(assert_trap (invoke "unreachable") "unreachable")
137+
138+
(module
139+
(elem declare func $f)
140+
(type $t (func (param i32) (result i32)))
141+
(func $f (param i32) (result i32) (local.get 0))
142+
143+
(func (export "unreachable") (result i32)
144+
(unreachable)
145+
(ref.func $f)
146+
(call_ref $t)
147+
)
148+
)
149+
(assert_trap (invoke "unreachable") "unreachable")
150+
151+
(module
152+
(elem declare func $f)
153+
(type $t (func (param i32) (result i32)))
154+
(func $f (param i32) (result i32) (local.get 0))
155+
156+
(func (export "unreachable") (result i32)
157+
(unreachable)
158+
(i32.const 0)
159+
(ref.func $f)
160+
(call_ref $t)
161+
(drop)
162+
(i32.const 0)
163+
)
164+
)
165+
(assert_trap (invoke "unreachable") "unreachable")
166+
167+
(assert_invalid
168+
(module
169+
(elem declare func $f)
170+
(type $t (func (param i32) (result i32)))
171+
(func $f (param i32) (result i32) (local.get 0))
172+
173+
(func (export "unreachable") (result i32)
174+
(unreachable)
175+
(i64.const 0)
176+
(ref.func $f)
177+
(call_ref $t)
178+
)
179+
)
180+
"type mismatch"
181+
)
182+
183+
(assert_invalid
184+
(module
185+
(elem declare func $f)
186+
(type $t (func (param i32) (result i32)))
187+
(func $f (param i32) (result i32) (local.get 0))
188+
189+
(func (export "unreachable") (result i32)
190+
(unreachable)
191+
(ref.func $f)
192+
(call_ref $t)
193+
(drop)
194+
(i64.const 0)
195+
)
196+
)
197+
"type mismatch"
198+
)
199+
200+
(assert_invalid
201+
(module
202+
(type $t (func))
203+
(func $f (param $r externref)
204+
(call_ref $t (local.get $r))
205+
)
206+
)
207+
"type mismatch"
208+
)

0 commit comments

Comments
 (0)