Skip to content

Commit 689eae7

Browse files
authored
Add a .wast test for br_on_null and br_on_non_null instructions (#13284)
These were not previously covered/exercised very well.
1 parent aca4636 commit 689eae7

1 file changed

Lines changed: 142 additions & 0 deletions

File tree

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
;;! gc = true
2+
3+
;; Test `br_on_null` and `br_on_non_null` with GC reference types.
4+
;;
5+
;; Note: `assert_return` arguments must be `[type].const` expressions, so GC
6+
;; refs (`struct.new`, `array.new`, `ref.i31`) are created inside the test
7+
;; functions.
8+
9+
;; br_on_null: branch when null, fall through when non-null
10+
(module
11+
(type $s (struct (field i32)))
12+
(type $arr (array i32))
13+
14+
;; Null struct ref -> branch taken -> returns 0.
15+
(func (export "br-on-null-struct-null") (result i32)
16+
(local $r (ref null $s))
17+
(block $l
18+
(br_on_null $l (local.get $r))
19+
(return (i32.const -1))
20+
)
21+
(i32.const 0)
22+
)
23+
24+
;; Non-null struct ref -> falls through -> returns -1.
25+
(func (export "br-on-null-struct-non-null") (result i32)
26+
(local $r (ref null $s))
27+
(local.set $r (struct.new_default $s))
28+
(block $l
29+
(br_on_null $l (local.get $r))
30+
(return (i32.const -1))
31+
)
32+
(i32.const 0)
33+
)
34+
35+
;; Null array ref -> branch taken -> returns 0.
36+
(func (export "br-on-null-array-null") (result i32)
37+
(local $r (ref null $arr))
38+
(block $l
39+
(br_on_null $l (local.get $r))
40+
(return (i32.const -1))
41+
)
42+
(i32.const 0)
43+
)
44+
45+
;; Non-null array ref -> falls through -> returns -1.
46+
(func (export "br-on-null-array-non-null") (result i32)
47+
(local $r (ref null $arr))
48+
(local.set $r (array.new_default $arr (i32.const 2)))
49+
(block $l
50+
(br_on_null $l (local.get $r))
51+
(return (i32.const -1))
52+
)
53+
(i32.const 0)
54+
)
55+
56+
;; Null i31ref -> branch taken -> returns 0.
57+
(func (export "br-on-null-i31-null") (result i32)
58+
(block $l
59+
(br_on_null $l (ref.null i31))
60+
(return (i32.const -1))
61+
)
62+
(i32.const 0)
63+
)
64+
65+
;; Non-null i31ref -> falls through -> returns -1.
66+
(func (export "br-on-null-i31-non-null") (result i32)
67+
(block $l
68+
(br_on_null $l (ref.i31 (i32.const 5)))
69+
(return (i32.const -1))
70+
)
71+
(i32.const 0)
72+
)
73+
74+
;; When non-null, br_on_null leaves the non-null ref on the stack.
75+
(func (export "br-on-null-yields-value") (result i32)
76+
(local $r (ref null $s))
77+
(local.set $r (struct.new $s (i32.const 42)))
78+
(block $l
79+
;; br_on_null falls through, leaving (ref $s) on stack
80+
(struct.get $s 0 (br_on_null $l (local.get $r)))
81+
(return)
82+
)
83+
(i32.const -1)
84+
)
85+
)
86+
87+
(assert_return (invoke "br-on-null-struct-null") (i32.const 0))
88+
(assert_return (invoke "br-on-null-struct-non-null") (i32.const -1))
89+
(assert_return (invoke "br-on-null-array-null") (i32.const 0))
90+
(assert_return (invoke "br-on-null-array-non-null") (i32.const -1))
91+
(assert_return (invoke "br-on-null-i31-null") (i32.const 0))
92+
(assert_return (invoke "br-on-null-i31-non-null") (i32.const -1))
93+
(assert_return (invoke "br-on-null-yields-value") (i32.const 42))
94+
95+
;; br_on_non_null: branch when non-null, fall through when null
96+
(module
97+
(type $s (struct (field i32)))
98+
99+
;; Null struct -> falls through -> returns -1.
100+
(func (export "br-on-non-null-struct-null") (result i32)
101+
(local $r (ref null $s))
102+
(block $l (result (ref $s))
103+
(br_on_non_null $l (local.get $r))
104+
(return (i32.const -1))
105+
)
106+
(struct.get $s 0)
107+
)
108+
109+
;; Non-null struct -> branch taken -> returns field value.
110+
(func (export "br-on-non-null-struct-non-null") (result i32)
111+
(block $l (result (ref $s))
112+
(br_on_non_null $l (struct.new $s (i32.const 99)))
113+
(return (i32.const -1))
114+
)
115+
(struct.get $s 0)
116+
)
117+
118+
;; Null anyref -> falls through -> returns -1.
119+
(func (export "br-on-non-null-any-null") (result i32)
120+
(block $l (result (ref any))
121+
(br_on_non_null $l (ref.null any))
122+
(return (i32.const -1))
123+
)
124+
(drop)
125+
(i32.const 1)
126+
)
127+
128+
;; Non-null anyref (i31) -> branch taken -> returns 1.
129+
(func (export "br-on-non-null-any-non-null") (result i32)
130+
(block $l (result (ref any))
131+
(br_on_non_null $l (ref.i31 (i32.const 0)))
132+
(return (i32.const -1))
133+
)
134+
(drop)
135+
(i32.const 1)
136+
)
137+
)
138+
139+
(assert_return (invoke "br-on-non-null-struct-null") (i32.const -1))
140+
(assert_return (invoke "br-on-non-null-struct-non-null") (i32.const 99))
141+
(assert_return (invoke "br-on-non-null-any-null") (i32.const -1))
142+
(assert_return (invoke "br-on-non-null-any-non-null") (i32.const 1))

0 commit comments

Comments
 (0)