1;;! component_model_async = true
2;;! reference_types = true
3;;! gc_types = true
4;;! multi_memory = true
5
6(component
7  (component $C
8    (core module $Memory (memory (export "mem") 1))
9    (core instance $memory (instantiate $Memory))
10    (core module $CM
11      (import "" "mem" (memory 1))
12      (import "" "waitable-set.new" (func $waitable-set.new (result i32)))
13
14      (func (export "f") (result i32)
15        (local $ws i32)
16        ;; return WAIT on an empty waitable set
17        (local.set $ws (call $waitable-set.new))
18        (i32.or (i32.const 2 (; WAIT ;)) (i32.shl (local.get $ws) (i32.const 4)))
19      )
20      (func (export "cb") (param $event_code i32) (param $index i32) (param $payload i32) (result i32)
21        unreachable
22      )
23    )
24    (canon waitable-set.new (core func $waitable-set.new))
25    (core instance $cm (instantiate $CM (with "" (instance
26      (export "mem" (memory $memory "mem"))
27      (export "waitable-set.new" (func $waitable-set.new))
28    ))))
29    (func (export "f") async (result u32) (canon lift
30      (core func $cm "f")
31      async (memory $memory "mem") (callback (func $cm "cb"))
32    ))
33  )
34
35  (component $D
36    (import "f" (func $f async (result u32)))
37
38    (core module $Memory (memory (export "mem") 1))
39    (core instance $memory (instantiate $Memory))
40    (core module $DM
41      (import "" "mem" (memory 1))
42      (import "" "waitable.join" (func $waitable.join (param i32 i32)))
43      (import "" "waitable-set.new" (func $waitable-set.new (result i32)))
44      (import "" "waitable-set.wait" (func $waitable-set.wait (param i32 i32) (result i32)))
45      (import "" "f" (func $f (param i32) (result i32)))
46
47      (func (export "g") (result i32)
48        (local $ws i32) (local $ret i32) (local $subtaski i32)
49        (local.set $ws (call $waitable-set.new))
50        (local.set $ret (call $f (i32.const 0)))
51        (local.set $subtaski (i32.shr_u (local.get $ret) (i32.const 4)))
52        (call $waitable.join (local.get $subtaski) (local.get $ws))
53        (call $waitable-set.wait (local.get $ws) (i32.const 0))
54        unreachable
55      )
56    )
57    (canon waitable.join (core func $waitable.join))
58    (canon waitable-set.new (core func $waitable-set.new))
59    (canon waitable-set.wait (memory $memory "mem") (core func $waitable-set.wait))
60    (canon lower (func $f) async (memory $memory "mem") (core func $f'))
61    (core instance $dm (instantiate $DM (with "" (instance
62      (export "mem" (memory $memory "mem"))
63      (export "waitable.join" (func $waitable.join))
64      (export "waitable-set.new" (func $waitable-set.new))
65      (export "waitable-set.wait" (func $waitable-set.wait))
66      (export "f" (func $f'))
67    ))))
68    (func (export "f") async (result u32) (canon lift (core func $dm "g")))
69  )
70
71  (instance $c (instantiate $C))
72  (instance $d (instantiate $D (with "f" (func $c "f"))))
73  (func (export "f") (alias export $d "f"))
74)
75
76(assert_trap (invoke "f") "deadlock detected")
77