1;;! component_model_async = true
2;;! reference_types = true
3;;! gc_types = true
4
5;; This test previously caused Wasmtime to panic while handling a trap due to an
6;; improperly disposed fiber.  That bug is fixed now, and this test helps ensure
7;; it stays fixed.
8;;
9;; (Copied from https://github.com/bytecodealliance/wasmtime/issues/11668#issue-3402875697)
10(component
11  (component $A
12    (core module $a
13      (func (export "run") (result i32)
14        i32.const 1)
15      (func (export "run-cb") (param i32 i32 i32) (result i32)
16        unreachable)
17    )
18
19    (core instance $a (instantiate $a))
20    (func (export "run") async
21      (canon lift (core func $a "run") async (callback (func $a "run-cb"))))
22  )
23  (component $B
24    (import "a" (instance $a (export "run" (func async))))
25
26    (core module $libc (memory (export "memory") 1))
27    (core instance $libc (instantiate $libc))
28
29    (core func $run (canon lower (func $a "run") async))
30    (core func $new (canon waitable-set.new))
31    (core func $join (canon waitable.join))
32    (core func $drop (canon waitable-set.drop))
33    (core func $wait (canon waitable-set.wait (memory $libc "memory")))
34
35    (core module $b
36      (import "" "run" (func $run_a (result i32)))
37      (import "" "new" (func $new (result i32)))
38      (import "" "join" (func $join (param i32 i32)))
39      (import "" "drop" (func $drop (param i32)))
40      (import "" "wait" (func $wait (param i32 i32) (result i32)))
41
42      (func (export "run")
43        (local $ret i32)
44        (local $set i32)
45
46        (local.set $ret (call $run_a))
47
48        ;; make sure it's in the "started" state
49        (if (i32.ne (i32.and (local.get $ret) (i32.const 0xf)) (i32.const 1))
50          (then (unreachable)))
51
52        ;; extract the waitable handle
53        (local.set $ret (i32.shr_u (local.get $ret) (i32.const 4)))
54
55        ;; Make a waitable set and insert our handle into it
56        (local.set $set (call $new))
57        (call $join (local.get $ret) (local.get $set))
58
59        ;; wait for something to happen filling in memory address 4, but don't
60        ;; actually see what happened since this traps right now.
61        (call $wait (local.get $set) (i32.const 4))
62        drop
63      )
64    )
65    (core instance $b (instantiate $b
66      (with "" (instance
67        (export "run" (func $run))
68        (export "new" (func $new))
69        (export "join" (func $join))
70        (export "drop" (func $drop))
71        (export "wait" (func $wait))
72      ))
73    ))
74    (func (export "run") async
75      (canon lift (core func $b "run")))
76  )
77
78  (instance $a (instantiate $A))
79  (instance $b (instantiate $B (with "a" (instance $a))))
80  (export "run" (func $b "run"))
81)
82
83(assert_trap (invoke "run") "wasm `unreachable` instruction executed")
84