Skip to content

Commit 46cd6d0

Browse files
committed
add trap-if-block-and-sync.wast
We'll remove this again in favor of the upstream version once WebAssembly/component-model#578 has been merged. Signed-off-by: Joel Dice <joel.dice@fermyon.com>
1 parent 57dde5e commit 46cd6d0

File tree

1 file changed

+377
-0
lines changed

1 file changed

+377
-0
lines changed
Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
;;! component_model_async = true
2+
;;! component_model_threading = true
3+
;;! reference_types = true
4+
;;! gc_types = true
5+
;;! multi_memory = true
6+
7+
;; TODO: remove this in favor of the upstream version once
8+
;; https://github.com/WebAssembly/component-model/pull/578 has been merged.
9+
10+
;; The $Tester component has two nested components $C and $D, where $D imports
11+
;; and calls $C. $C contains utilities used by $D to perform all the tests.
12+
;; Most of the tests trap, $Tester exports 1 function per test and a fresh
13+
;; $Tester is created to run each test.
14+
(component definition $Tester
15+
(component $C
16+
(core module $Memory (memory (export "mem") 1))
17+
(core instance $memory (instantiate $Memory))
18+
(core module $CM
19+
(import "" "mem" (memory 1))
20+
(import "" "waitable.join" (func $waitable.join (param i32 i32)))
21+
(import "" "waitable-set.new" (func $waitable-set.new (result i32)))
22+
(import "" "waitable-set.wait" (func $waitable-set.wait (param i32 i32) (result i32)))
23+
(import "" "future.new" (func $future.new (result i64)))
24+
(import "" "future.read" (func $future.read (param i32 i32) (result i32)))
25+
(import "" "future.write" (func $future.write (param i32 i32) (result i32)))
26+
27+
;; $ws is waited on by 'blocker' and added to by 'unblocker'
28+
(global $ws (mut i32) (i32.const 0))
29+
(func $start (global.set $ws (call $waitable-set.new)))
30+
(start $start)
31+
32+
(func (export "blocker") (result i32)
33+
;; wait on $ws, which is initially empty, but will be populated with
34+
;; a completed future when "unblocker" synchronously barges in.
35+
(local $ret i32)
36+
(local.set $ret (call $waitable-set.wait (global.get $ws) (i32.const 0)))
37+
(if (i32.ne (i32.const 4 (; FUTURE_READ ;)) (local.get $ret))
38+
(then unreachable))
39+
(if (i32.ne (i32.const 0 (; COMPLETED ;)) (i32.load (i32.const 4)))
40+
(then unreachable))
41+
42+
(i32.const 42)
43+
)
44+
45+
(func (export "unblocker") (result i32)
46+
(local $ret i32) (local $ret64 i64)
47+
(local $futr i32) (local $futw i32)
48+
49+
;; create read/write futures that will be used to unblock 'blocker'
50+
(local.set $ret64 (call $future.new))
51+
(local.set $futr (i32.wrap_i64 (local.get $ret64)))
52+
(local.set $futw (i32.wrap_i64 (i64.shr_u (local.get $ret64) (i64.const 32))))
53+
54+
;; perform a future.read which will block, and add this future to the waitable-set
55+
;; being waited on by 'blocker'
56+
(local.set $ret (call $future.read (local.get $futr) (i32.const 0xdeadbeef)))
57+
(if (i32.ne (i32.const -1 (; BLOCKED ;)) (local.get $ret))
58+
(then unreachable))
59+
(call $waitable.join (local.get $futr) (global.get $ws))
60+
61+
;; perform a future.write which will rendezvous with the write and complete
62+
(local.set $ret (call $future.write (local.get $futw) (i32.const 0xdeadbeef)))
63+
(if (i32.ne (i32.const 0 (; COMPLETED ;)) (local.get $ret))
64+
(then unreachable))
65+
66+
(i32.const 43)
67+
)
68+
69+
(func (export "sync-async-func")
70+
unreachable
71+
)
72+
(func (export "async-async-func") (result i32)
73+
unreachable
74+
)
75+
(func (export "async-async-func-cb") (param i32 i32 i32) (result i32)
76+
unreachable
77+
)
78+
)
79+
(type $FT (future))
80+
(canon waitable.join (core func $waitable.join))
81+
(canon waitable-set.new (core func $waitable-set.new))
82+
(canon waitable-set.wait (memory $memory "mem") (core func $waitable-set.wait))
83+
(canon future.new $FT (core func $future.new))
84+
(canon future.read $FT async (core func $future.read))
85+
(canon future.write $FT async (core func $future.write))
86+
(core instance $cm (instantiate $CM (with "" (instance
87+
(export "mem" (memory $memory "mem"))
88+
(export "waitable.join" (func $waitable.join))
89+
(export "waitable-set.new" (func $waitable-set.new))
90+
(export "waitable-set.wait" (func $waitable-set.wait))
91+
(export "future.new" (func $future.new))
92+
(export "future.read" (func $future.read))
93+
(export "future.write" (func $future.write))
94+
))))
95+
(func (export "blocker") async (result u32) (canon lift (core func $cm "blocker")))
96+
(func (export "unblocker") (result u32) (canon lift (core func $cm "unblocker")))
97+
(func (export "sync-async-func") async (canon lift (core func $cm "sync-async-func")))
98+
(func (export "async-async-func") async (canon lift (core func $cm "async-async-func") async (callback (func $cm "async-async-func-cb"))))
99+
)
100+
(component $D
101+
(import "c" (instance $c
102+
(export "blocker" (func async (result u32)))
103+
(export "unblocker" (func (result u32)))
104+
(export "sync-async-func" (func async))
105+
(export "async-async-func" (func async))
106+
))
107+
108+
(core module $Memory (memory (export "mem") 1))
109+
(core instance $memory (instantiate $Memory))
110+
(core module $Core
111+
(import "" "mem" (memory 1))
112+
(import "" "task.return" (func $task.return (param i32)))
113+
(import "" "subtask.cancel" (func $subtask.cancel (param i32) (result i32)))
114+
(import "" "thread.yield" (func $thread.yield (result i32)))
115+
(import "" "thread.suspend" (func $thread.suspend (result i32)))
116+
(import "" "waitable.join" (func $waitable.join (param i32 i32)))
117+
(import "" "waitable-set.new" (func $waitable-set.new (result i32)))
118+
(import "" "waitable-set.wait" (func $waitable-set.wait (param i32 i32) (result i32)))
119+
(import "" "waitable-set.poll" (func $waitable-set.poll (param i32 i32) (result i32)))
120+
(import "" "stream.read" (func $stream.read (param i32 i32 i32) (result i32)))
121+
(import "" "stream.write" (func $stream.write (param i32 i32 i32) (result i32)))
122+
(import "" "future.read" (func $future.read (param i32 i32) (result i32)))
123+
(import "" "future.write" (func $future.write (param i32 i32) (result i32)))
124+
(import "" "stream.cancel-read" (func $stream.cancel-read (param i32) (result i32)))
125+
(import "" "stream.cancel-write" (func $stream.cancel-write (param i32) (result i32)))
126+
(import "" "future.cancel-read" (func $future.cancel-read (param i32) (result i32)))
127+
(import "" "future.cancel-write" (func $future.cancel-write (param i32) (result i32)))
128+
(import "" "blocker" (func $blocker (param i32) (result i32)))
129+
(import "" "unblocker" (func $unblocker (result i32)))
130+
(import "" "await-sync-async-func" (func $await-sync-async-func))
131+
(import "" "await-async-async-func" (func $await-async-async-func))
132+
133+
(func (export "sync-barges-in") (result i32)
134+
(local $ret i32) (local $retp1 i32) (local $retp2 i32)
135+
(local $subtask i32) (local $ws i32) (local $event_code i32)
136+
137+
(local.set $retp1 (i32.const 8))
138+
(local.set $retp2 (i32.const 12))
139+
140+
;; call $blocker which will block during a synchronous function.
141+
(local.set $ret (call $blocker (local.get $retp1)))
142+
(if (i32.ne (i32.const 1 (; STARTED ;)) (i32.and (local.get $ret) (i32.const 0xf)))
143+
(then unreachable))
144+
(local.set $subtask (i32.shr_u (local.get $ret) (i32.const 4)))
145+
146+
;; normally calling another function would hit backpressure until
147+
;; $blocker was done, but calling the sync-typed function $unblocker
148+
;; barges in synchronously.
149+
(local.set $ret (call $unblocker))
150+
(if (i32.ne (local.get $ret) (i32.const 43))
151+
(then unreachable))
152+
153+
;; now wait to confirm that $subtask was actually unblocked
154+
(local.set $ws (call $waitable-set.new))
155+
(call $waitable.join (local.get $subtask) (local.get $ws))
156+
(local.set $event_code (call $waitable-set.wait (local.get $ws) (local.get $retp2)))
157+
(if (i32.ne (i32.const 1 (; SUBTASK ;)) (local.get $event_code))
158+
(then unreachable))
159+
(if (i32.ne (local.get $subtask) (i32.load (local.get $retp2)))
160+
(then unreachable))
161+
(if (i32.ne (i32.const 2 (; RETURNED=2 ;)) (i32.load offset=4 (local.get $retp2)))
162+
(then unreachable))
163+
(if (i32.ne (i32.const 42) (i32.load (local.get $retp1)))
164+
(then unreachable))
165+
166+
(i32.const 44)
167+
)
168+
169+
(func (export "unreachable-cb") (param i32 i32 i32) (result i32)
170+
unreachable
171+
)
172+
(func (export "return-42-cb") (param i32 i32 i32) (result i32)
173+
(call $task.return (i32.const 42))
174+
(i32.const 0 (; EXIT ;))
175+
)
176+
177+
(func (export "trap-if-sync-call-async1")
178+
(call $await-sync-async-func)
179+
)
180+
(func (export "trap-if-sync-call-async2")
181+
(call $await-async-async-func)
182+
)
183+
(func (export "trap-if-suspend")
184+
(call $thread.suspend)
185+
unreachable
186+
)
187+
(func (export "trap-if-wait")
188+
(call $waitable-set.wait (call $waitable-set.new) (i32.const 0xdeadbeef))
189+
unreachable
190+
)
191+
(func (export "trap-if-wait-cb") (result i32)
192+
(i32.or
193+
(i32.const 2 (; WAIT ;))
194+
(i32.shl (call $waitable-set.new) (i32.const 4)))
195+
)
196+
(func (export "trap-if-poll")
197+
(call $waitable-set.poll (call $waitable-set.new) (i32.const 0xdeadbeef))
198+
unreachable
199+
)
200+
(func (export "trap-if-poll-cb") (result i32)
201+
(i32.or
202+
(i32.const 3 (; POLL ;))
203+
(i32.shl (call $waitable-set.new) (i32.const 4)))
204+
)
205+
(func (export "yield-is-fine") (result i32)
206+
(drop (call $thread.yield))
207+
(i32.const 42)
208+
)
209+
(func (export "yield-is-fine-cb") (result i32)
210+
(i32.or
211+
(i32.const 1 (; YIELD ;))
212+
(i32.shl (i32.const 0xdead) (i32.const 4)))
213+
)
214+
(func (export "trap-if-sync-cancel")
215+
(call $subtask.cancel (i32.const 0xdeadbeef))
216+
unreachable
217+
)
218+
(func (export "trap-if-sync-stream-read")
219+
(call $stream.read (i32.const 0xdead) (i32.const 0xbeef) (i32.const 0xdeadbeef))
220+
unreachable
221+
)
222+
(func (export "trap-if-sync-stream-write")
223+
(call $stream.write (i32.const 0xdead) (i32.const 0xbeef) (i32.const 0xdeadbeef))
224+
unreachable
225+
)
226+
(func (export "trap-if-sync-future-read")
227+
(call $future.read (i32.const 0xdead) (i32.const 0xdeadbeef))
228+
unreachable
229+
)
230+
(func (export "trap-if-sync-future-write")
231+
(call $future.write (i32.const 0xdead) (i32.const 0xdeadbeef))
232+
unreachable
233+
)
234+
(func (export "trap-if-sync-stream-cancel-read")
235+
(call $stream.cancel-read (i32.const 0xdead))
236+
unreachable
237+
)
238+
(func (export "trap-if-sync-stream-cancel-write")
239+
(call $stream.cancel-write (i32.const 0xdead))
240+
unreachable
241+
)
242+
(func (export "trap-if-sync-future-cancel-read")
243+
(call $future.cancel-read (i32.const 0xdead) (i32.const 0xdeadbeef))
244+
unreachable
245+
)
246+
(func (export "trap-if-sync-future-cancel-write")
247+
(call $future.cancel-write (i32.const 0xdead) (i32.const 0xdeadbeef))
248+
unreachable
249+
)
250+
)
251+
(type $FT (future u8))
252+
(type $ST (stream u8))
253+
(canon task.return (result u32) (core func $task.return))
254+
(canon subtask.cancel (core func $subtask.cancel))
255+
(canon thread.yield (core func $thread.yield))
256+
(canon thread.suspend (core func $thread.suspend))
257+
(canon waitable.join (core func $waitable.join))
258+
(canon waitable-set.new (core func $waitable-set.new))
259+
(canon waitable-set.wait (memory $memory "mem") (core func $waitable-set.wait))
260+
(canon waitable-set.poll (memory $memory "mem") (core func $waitable-set.poll))
261+
(canon stream.read $ST (memory $memory "mem") (core func $stream.read))
262+
(canon stream.write $ST (memory $memory "mem") (core func $stream.write))
263+
(canon future.read $FT (memory $memory "mem") (core func $future.read))
264+
(canon future.write $FT (memory $memory "mem") (core func $future.write))
265+
(canon stream.cancel-read $ST (core func $stream.cancel-read))
266+
(canon stream.cancel-write $ST (core func $stream.cancel-write))
267+
(canon future.cancel-read $FT (core func $future.cancel-read))
268+
(canon future.cancel-write $FT (core func $future.cancel-write))
269+
(canon lower (func $c "blocker") (memory $memory "mem") async (core func $blocker'))
270+
(canon lower (func $c "unblocker") (core func $unblocker'))
271+
(canon lower (func $c "sync-async-func") (core func $await-sync-async-func'))
272+
(canon lower (func $c "async-async-func") (core func $await-async-async-func'))
273+
(core instance $core (instantiate $Core (with "" (instance
274+
(export "mem" (memory $memory "mem"))
275+
(export "task.return" (func $task.return))
276+
(export "subtask.cancel" (func $subtask.cancel))
277+
(export "thread.yield" (func $thread.yield))
278+
(export "thread.suspend" (func $thread.suspend))
279+
(export "waitable.join" (func $waitable.join))
280+
(export "waitable-set.new" (func $waitable-set.new))
281+
(export "waitable-set.wait" (func $waitable-set.wait))
282+
(export "waitable-set.poll" (func $waitable-set.poll))
283+
(export "stream.read" (func $stream.read))
284+
(export "stream.write" (func $stream.write))
285+
(export "future.read" (func $future.read))
286+
(export "future.write" (func $future.write))
287+
(export "stream.cancel-read" (func $stream.cancel-read))
288+
(export "stream.cancel-write" (func $stream.cancel-write))
289+
(export "future.cancel-read" (func $future.cancel-read))
290+
(export "future.cancel-write" (func $future.cancel-write))
291+
(export "blocker" (func $blocker'))
292+
(export "unblocker" (func $unblocker'))
293+
(export "await-sync-async-func" (func $await-sync-async-func'))
294+
(export "await-async-async-func" (func $await-async-async-func'))
295+
))))
296+
(func (export "sync-barges-in") async (result u32) (canon lift (core func $core "sync-barges-in")))
297+
(func (export "trap-if-suspend") (canon lift (core func $core "trap-if-suspend")))
298+
(func (export "trap-if-wait") (canon lift (core func $core "trap-if-wait")))
299+
(func (export "trap-if-wait-cb") (canon lift (core func $core "trap-if-wait-cb") async (callback (func $core "unreachable-cb"))))
300+
(func (export "trap-if-poll") (canon lift (core func $core "trap-if-poll")))
301+
(func (export "trap-if-poll-cb") (canon lift (core func $core "trap-if-poll-cb") async (callback (func $core "unreachable-cb"))))
302+
(func (export "yield-is-fine") (result u32) (canon lift (core func $core "yield-is-fine")))
303+
(func (export "yield-is-fine-cb") (result u32) (canon lift (core func $core "yield-is-fine-cb") async (callback (func $core "return-42-cb"))))
304+
(func (export "trap-if-sync-call-async1") (canon lift (core func $core "trap-if-sync-call-async1")))
305+
(func (export "trap-if-sync-call-async2") (canon lift (core func $core "trap-if-sync-call-async2")))
306+
(func (export "trap-if-sync-cancel") (canon lift (core func $core "trap-if-sync-cancel")))
307+
(func (export "trap-if-sync-stream-read") (canon lift (core func $core "trap-if-sync-stream-read")))
308+
(func (export "trap-if-sync-stream-write") (canon lift (core func $core "trap-if-sync-stream-write")))
309+
(func (export "trap-if-sync-future-read") (canon lift (core func $core "trap-if-sync-future-read")))
310+
(func (export "trap-if-sync-future-write") (canon lift (core func $core "trap-if-sync-future-write")))
311+
(func (export "trap-if-sync-stream-cancel-read") (canon lift (core func $core "trap-if-sync-stream-cancel-read")))
312+
(func (export "trap-if-sync-stream-cancel-write") (canon lift (core func $core "trap-if-sync-stream-cancel-write")))
313+
(func (export "trap-if-sync-future-cancel-read") (canon lift (core func $core "trap-if-sync-future-cancel-read")))
314+
(func (export "trap-if-sync-future-cancel-write") (canon lift (core func $core "trap-if-sync-future-cancel-write")))
315+
)
316+
(instance $c (instantiate $C))
317+
(instance $d (instantiate $D (with "c" (instance $c))))
318+
(func (export "sync-barges-in") (alias export $d "sync-barges-in"))
319+
(func (export "trap-if-sync-call-async1") (alias export $d "trap-if-sync-call-async1"))
320+
(func (export "trap-if-sync-call-async2") (alias export $d "trap-if-sync-call-async2"))
321+
(func (export "trap-if-suspend") (alias export $d "trap-if-suspend"))
322+
(func (export "trap-if-wait") (alias export $d "trap-if-wait"))
323+
(func (export "trap-if-wait-cb") (alias export $d "trap-if-wait-cb"))
324+
(func (export "trap-if-poll") (alias export $d "trap-if-poll"))
325+
(func (export "trap-if-poll-cb") (alias export $d "trap-if-poll-cb"))
326+
(func (export "yield-is-fine") (alias export $d "yield-is-fine"))
327+
(func (export "yield-is-fine-cb") (alias export $d "yield-is-fine-cb"))
328+
(func (export "trap-if-sync-cancel") (alias export $d "trap-if-sync-cancel"))
329+
(func (export "trap-if-sync-stream-read") (alias export $d "trap-if-sync-stream-read"))
330+
(func (export "trap-if-sync-stream-write") (alias export $d "trap-if-sync-stream-write"))
331+
(func (export "trap-if-sync-future-read") (alias export $d "trap-if-sync-future-read"))
332+
(func (export "trap-if-sync-future-write") (alias export $d "trap-if-sync-future-write"))
333+
(func (export "trap-if-sync-stream-cancel-read") (alias export $d "trap-if-sync-stream-cancel-read"))
334+
(func (export "trap-if-sync-stream-cancel-write") (alias export $d "trap-if-sync-stream-cancel-write"))
335+
(func (export "trap-if-sync-future-cancel-read") (alias export $d "trap-if-sync-future-cancel-read"))
336+
(func (export "trap-if-sync-future-cancel-write") (alias export $d "trap-if-sync-future-cancel-write"))
337+
)
338+
339+
(component instance $i $Tester)
340+
(assert_return (invoke "sync-barges-in") (u32.const 44))
341+
342+
(component instance $i $Tester)
343+
(assert_trap (invoke "trap-if-sync-call-async1") "cannot block a synchronous task before returning")
344+
(component instance $i $Tester)
345+
(assert_trap (invoke "trap-if-sync-call-async2") "cannot block a synchronous task before returning")
346+
(component instance $i $Tester)
347+
(assert_trap (invoke "trap-if-suspend") "cannot block a synchronous task before returning")
348+
(component instance $i $Tester)
349+
(assert_trap (invoke "trap-if-wait") "cannot block a synchronous task before returning")
350+
(component instance $i $Tester)
351+
(assert_trap (invoke "trap-if-wait-cb") "cannot block a synchronous task before returning")
352+
(component instance $i $Tester)
353+
(assert_trap (invoke "trap-if-poll") "cannot block a synchronous task before returning")
354+
(component instance $i $Tester)
355+
(assert_trap (invoke "trap-if-poll-cb") "cannot block a synchronous task before returning")
356+
(component instance $i $Tester)
357+
(assert_return (invoke "yield-is-fine") (u32.const 42))
358+
(component instance $i $Tester)
359+
(assert_return (invoke "yield-is-fine-cb") (u32.const 42))
360+
(component instance $i $Tester)
361+
(assert_trap (invoke "trap-if-sync-cancel") "cannot block a synchronous task before returning")
362+
(component instance $i $Tester)
363+
(assert_trap (invoke "trap-if-sync-stream-read") "cannot block a synchronous task before returning")
364+
(component instance $i $Tester)
365+
(assert_trap (invoke "trap-if-sync-stream-write") "cannot block a synchronous task before returning")
366+
(component instance $i $Tester)
367+
(assert_trap (invoke "trap-if-sync-future-read") "cannot block a synchronous task before returning")
368+
(component instance $i $Tester)
369+
(assert_trap (invoke "trap-if-sync-future-write") "cannot block a synchronous task before returning")
370+
(component instance $i $Tester)
371+
(assert_trap (invoke "trap-if-sync-stream-cancel-read") "cannot block a synchronous task before returning")
372+
(component instance $i $Tester)
373+
(assert_trap (invoke "trap-if-sync-stream-cancel-write") "cannot block a synchronous task before returning")
374+
(component instance $i $Tester)
375+
(assert_trap (invoke "trap-if-sync-future-cancel-read") "cannot block a synchronous task before returning")
376+
(component instance $i $Tester)
377+
(assert_trap (invoke "trap-if-sync-future-cancel-write") "cannot block a synchronous task before returning")

0 commit comments

Comments
 (0)