Skip to content

Commit c93c28b

Browse files
authored
Add a .wast test to exercise GC operations in const expressions (#13286)
Was not well exercised/covered by existing tests.
1 parent 7ed8f19 commit c93c28b

1 file changed

Lines changed: 173 additions & 0 deletions

File tree

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
;;! gc = true
2+
3+
;; Test GC operations in constant expression contexts (global initializers and
4+
;; element segment expressions) and covers `struct.new_default` with every
5+
;; storage type to cover all our code paths.
6+
7+
;; `ConstOp::StructNew`
8+
(module
9+
(type $s (struct (field i32) (field f64)))
10+
11+
(global $g anyref (struct.new $s (i32.const 7) (f64.const 3.14)))
12+
13+
(func (export "struct-new-const") (result i32)
14+
(struct.get $s 0 (ref.cast (ref $s) (global.get $g)))
15+
)
16+
)
17+
(assert_return (invoke "struct-new-const") (i32.const 7))
18+
19+
;; `ConstOp::StructNewDefault` w/ one field per storage type
20+
(module
21+
(type $s (struct
22+
(field i8)
23+
(field i16)
24+
(field i32)
25+
(field i64)
26+
(field f32)
27+
(field f64)
28+
(field anyref)
29+
))
30+
31+
;; struct.new_default fills every field with its zero/null default
32+
(global $g anyref (struct.new_default $s))
33+
34+
(func (export "struct-new-default-i32") (result i32)
35+
(struct.get_s $s 0 (ref.cast (ref $s) (global.get $g)))
36+
)
37+
(func (export "struct-new-default-i64") (result i64)
38+
(struct.get $s 3 (ref.cast (ref $s) (global.get $g)))
39+
)
40+
(func (export "struct-new-default-f32") (result f32)
41+
(struct.get $s 4 (ref.cast (ref $s) (global.get $g)))
42+
)
43+
(func (export "struct-new-default-f64") (result f64)
44+
(struct.get $s 5 (ref.cast (ref $s) (global.get $g)))
45+
)
46+
(func (export "struct-new-default-ref-null") (result i32)
47+
(ref.is_null (struct.get $s 6 (ref.cast (ref $s) (global.get $g))))
48+
)
49+
)
50+
(assert_return (invoke "struct-new-default-i32") (i32.const 0))
51+
(assert_return (invoke "struct-new-default-i64") (i64.const 0))
52+
(assert_return (invoke "struct-new-default-f32") (f32.const 0.0))
53+
(assert_return (invoke "struct-new-default-f64") (f64.const 0.0))
54+
(assert_return (invoke "struct-new-default-ref-null") (i32.const 1))
55+
56+
;; `ConstOp::ArrayNew`
57+
(module
58+
(type $arr (array (mut i32)))
59+
60+
(global $g anyref (array.new $arr (i32.const 99) (i32.const 3)))
61+
62+
(func (export "array-new-const-len") (result i32)
63+
(array.len (ref.cast (ref $arr) (global.get $g)))
64+
)
65+
(func (export "array-new-const-elem") (result i32)
66+
(array.get $arr (ref.cast (ref $arr) (global.get $g)) (i32.const 1))
67+
)
68+
)
69+
(assert_return (invoke "array-new-const-len") (i32.const 3))
70+
(assert_return (invoke "array-new-const-elem") (i32.const 99))
71+
72+
;; `ConstOp::ArrayNewDefault`
73+
(module
74+
(type $arr (array (mut i32)))
75+
76+
(global $g anyref (array.new_default $arr (i32.const 4)))
77+
78+
(func (export "array-new-default-const-len") (result i32)
79+
(array.len (ref.cast (ref $arr) (global.get $g)))
80+
)
81+
(func (export "array-new-default-const-elem") (result i32)
82+
(array.get $arr (ref.cast (ref $arr) (global.get $g)) (i32.const 2))
83+
)
84+
)
85+
(assert_return (invoke "array-new-default-const-len") (i32.const 4))
86+
(assert_return (invoke "array-new-default-const-elem") (i32.const 0))
87+
88+
;; `ConstOp::ArrayNewFixed`
89+
(module
90+
(type $arr (array i32))
91+
92+
(global $g anyref (array.new_fixed $arr 3
93+
(i32.const 10)
94+
(i32.const 20)
95+
(i32.const 30)
96+
))
97+
98+
(func (export "array-new-fixed-const-len") (result i32)
99+
(array.len (ref.cast (ref $arr) (global.get $g)))
100+
)
101+
(func (export "array-new-fixed-const-elem0") (result i32)
102+
(array.get $arr (ref.cast (ref $arr) (global.get $g)) (i32.const 0))
103+
)
104+
(func (export "array-new-fixed-const-elem2") (result i32)
105+
(array.get $arr (ref.cast (ref $arr) (global.get $g)) (i32.const 2))
106+
)
107+
)
108+
(assert_return (invoke "array-new-fixed-const-len") (i32.const 3))
109+
(assert_return (invoke "array-new-fixed-const-elem0") (i32.const 10))
110+
(assert_return (invoke "array-new-fixed-const-elem2") (i32.const 30))
111+
112+
;; `ConstOp::ExternConvertAny`
113+
(module
114+
(type $s (struct (field i32)))
115+
116+
;; Convert a struct anyref to an externref in a const expression.
117+
(global $g externref
118+
(extern.convert_any (struct.new $s (i32.const 55)))
119+
)
120+
121+
(func (export "extern-convert-any-const") (result i32)
122+
(struct.get $s 0
123+
(ref.cast (ref $s)
124+
(any.convert_extern (global.get $g))
125+
)
126+
)
127+
)
128+
)
129+
(assert_return (invoke "extern-convert-any-const") (i32.const 55))
130+
131+
;; Null any -> null extern in a const expression.
132+
(module
133+
(global $g externref (extern.convert_any (ref.null any)))
134+
135+
(func (export "extern-convert-any-null") (result i32)
136+
(ref.is_null (global.get $g))
137+
)
138+
)
139+
(assert_return (invoke "extern-convert-any-null") (i32.const 1))
140+
141+
;; `ConstOp::AnyConvertExtern`
142+
(module
143+
(global $g anyref
144+
(any.convert_extern
145+
(extern.convert_any
146+
(ref.i31 (i32.const 7))
147+
)
148+
)
149+
)
150+
(func (export "any-convert-extern-non-null") (result i32)
151+
(i31.get_u (ref.cast (ref i31) (global.get $g)))
152+
)
153+
)
154+
(assert_return (invoke "any-convert-extern-non-null") (i32.const 7))
155+
156+
;; Null extern -> null any in a const expression.
157+
(module
158+
(func (export "any-convert-extern-null") (result i32)
159+
(ref.is_null (global.get $g))
160+
)
161+
(global $g anyref (any.convert_extern (ref.null extern)))
162+
)
163+
(assert_return (invoke "any-convert-extern-null") (i32.const 1))
164+
165+
;; `ConstOp::RefI31`
166+
(module
167+
(global $g i31ref (ref.i31 (i32.const 42)))
168+
169+
(func (export "ref-i31-const") (result i32)
170+
(i31.get_u (global.get $g))
171+
)
172+
)
173+
(assert_return (invoke "ref-i31-const") (i32.const 42))

0 commit comments

Comments
 (0)