Skip to content

Commit 3a451e0

Browse files
authored
threads: check mutability of GC instructions (#1729)
* threads: check mutability for `struct.atomic.rmw.*` instructions Previously this was not being checked; this adds tests which force new validation logic. * threads: check mutability for `array.atomic.rmw.*` instructions * review: add `mutable_struct_field_at` * review: add `mutable_array_field_at` * fix: formatting
1 parent 8a6eb57 commit 3a451e0

70 files changed

Lines changed: 739 additions & 480 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

crates/wasmparser/src/validator/operators.rs

Lines changed: 72 additions & 73 deletions
Large diffs are not rendered by default.

tests/local/shared-everything-threads/arrays.wast

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,80 @@
138138
(func (array.init_elem $funcs 0 (ref.null (shared none)) (i32.const 0) (i32.const 0) (i32.const 0)))
139139
)
140140

141+
;; Check that field-modifying instructions only work on mutable fields.
142+
(assert_invalid
143+
(module
144+
(type $a (shared (array (ref (shared any)))))
145+
(func (param $a (ref $a)) (param $ar (ref (shared any))) (result (ref (shared any)))
146+
(array.atomic.set seq_cst $a (local.get $a) (i32.const 0) (local.get $ar))
147+
)
148+
)
149+
"array is immutable"
150+
)
151+
(assert_invalid
152+
(module
153+
(type $a (shared (array i32)))
154+
(func (param $a (ref $a)) (result i32)
155+
(array.atomic.rmw.add seq_cst $a (local.get $a) (i32.const 0) (i32.const 1))
156+
)
157+
)
158+
"array is immutable"
159+
)
160+
(assert_invalid
161+
(module
162+
(type $a (shared (array i64)))
163+
(func (param $a (ref $a)) (result i64)
164+
(array.atomic.rmw.sub seq_cst $a (local.get $a) (i32.const 0) (i64.const 1))
165+
)
166+
)
167+
"array is immutable"
168+
)
169+
(assert_invalid
170+
(module
171+
(type $a (shared (array i32)))
172+
(func (param $a (ref $a)) (result i32)
173+
(array.atomic.rmw.and acq_rel $a (local.get $a) (i32.const 0) (i32.const 1))
174+
)
175+
)
176+
"array is immutable"
177+
)
178+
(assert_invalid
179+
(module
180+
(type $a (shared (array i64)))
181+
(func (param $a (ref $a)) (result i64)
182+
(array.atomic.rmw.or acq_rel $a (local.get $a) (i32.const 0) (i64.const 1))
183+
)
184+
)
185+
"array is immutable"
186+
)
187+
(assert_invalid
188+
(module
189+
(type $a (shared (array i32)))
190+
(func (param $a (ref $a)) (result i32)
191+
(array.atomic.rmw.xor seq_cst $a (local.get $a) (i32.const 0) (i32.const 1))
192+
)
193+
)
194+
"array is immutable"
195+
)
196+
(assert_invalid
197+
(module
198+
(type $a (shared (array (ref (shared any)))))
199+
(func (param $a (ref $a)) (param $ar (ref (shared any))) (result (ref (shared any)))
200+
(array.atomic.rmw.xchg seq_cst $a (local.get $a) (i32.const 0) (local.get $ar))
201+
)
202+
)
203+
"array is immutable"
204+
)
205+
(assert_invalid
206+
(module
207+
(type $a (shared (array (ref (shared eq)))))
208+
(func (param $a (ref $a)) (param $e1 (ref (shared eq))) (param $e2 (ref (shared eq))) (result)
209+
(array.atomic.rmw.cmpxchg acq_rel $a (local.get $a) (i32.const 0) (local.get $e1) (local.get $e2))
210+
)
211+
)
212+
"array is immutable"
213+
)
214+
141215
;; Exhaustively check `array.atomic.rmw.*` instructions.
142216
(module (; get, i32, seq_cst ;)
143217
(type $a (shared (array (mut i32))))

tests/local/shared-everything-threads/structs.wast

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,80 @@
9999
(func (struct.set $i8 0 (ref.null (shared none)) (i32.const 0)))
100100
)
101101

102+
;; Check that field-modifying instructions only work on mutable fields.
103+
(assert_invalid
104+
(module
105+
(type $s (shared (struct (field (ref (shared any))))))
106+
(func (param $s (ref $s)) (param $a (ref (shared any))) (result (ref (shared any)))
107+
(struct.atomic.set seq_cst $s 0 (local.get $s) (local.get $a))
108+
)
109+
)
110+
"field is immutable"
111+
)
112+
(assert_invalid
113+
(module
114+
(type $s (shared (struct (field i32))))
115+
(func (param $s (ref $s)) (result i32)
116+
(struct.atomic.rmw.add seq_cst $s 0 (local.get $s) (i32.const 1))
117+
)
118+
)
119+
"field is immutable"
120+
)
121+
(assert_invalid
122+
(module
123+
(type $s (shared (struct (field i64))))
124+
(func (param $s (ref $s)) (result i64)
125+
(struct.atomic.rmw.sub seq_cst $s 0 (local.get $s) (i64.const 1))
126+
)
127+
)
128+
"field is immutable"
129+
)
130+
(assert_invalid
131+
(module
132+
(type $s (shared (struct (field i32))))
133+
(func (param $s (ref $s)) (result i32)
134+
(struct.atomic.rmw.and acq_rel $s 0 (local.get $s) (i32.const 1))
135+
)
136+
)
137+
"field is immutable"
138+
)
139+
(assert_invalid
140+
(module
141+
(type $s (shared (struct (field i64))))
142+
(func (param $s (ref $s)) (result i64)
143+
(struct.atomic.rmw.or acq_rel $s 0 (local.get $s) (i64.const 1))
144+
)
145+
)
146+
"field is immutable"
147+
)
148+
(assert_invalid
149+
(module
150+
(type $s (shared (struct (field i32))))
151+
(func (param $s (ref $s)) (result i32)
152+
(struct.atomic.rmw.xor seq_cst $s 0 (local.get $s) (i32.const 1))
153+
)
154+
)
155+
"field is immutable"
156+
)
157+
(assert_invalid
158+
(module
159+
(type $s (shared (struct (field (ref (shared any))))))
160+
(func (param $s (ref $s)) (param $a (ref (shared any))) (result (ref (shared any)))
161+
(struct.atomic.rmw.xchg seq_cst $s 0 (local.get $s) (local.get $a))
162+
)
163+
)
164+
"field is immutable"
165+
)
166+
(assert_invalid
167+
(module
168+
(type $s (shared (struct (field (ref (shared eq))))))
169+
(func (param $s (ref $s)) (param $e1 (ref (shared eq))) (param $e2 (ref (shared eq))) (result (ref (shared eq)))
170+
(struct.atomic.rmw.cmpxchg acq_rel $s 0 (local.get $s) (local.get $e1) (local.get $e2))
171+
)
172+
)
173+
"field is immutable"
174+
)
175+
102176
;; Exhaustively check `struct.atomic.rmw.*` instructions.
103177
(module
104178
(type $s (shared (struct

0 commit comments

Comments
 (0)