|
| 1 | +;;! component_model_async = true |
| 2 | +;;! reference_types = true |
| 3 | + |
| 4 | +;; This test checks that an `EVENT_CANCELLED` can be delivered to a task that's |
| 5 | +;; in a `CALLBACK_CODE_YIELD` loop. |
| 6 | +(component |
| 7 | + (component $a |
| 8 | + (core module $m |
| 9 | + (import "" "task.cancel" (func $task-cancel)) |
| 10 | + (import "" "thread.yield" (func $thread-yield (result i32))) |
| 11 | + |
| 12 | + (func (export "f") (result i32) |
| 13 | + ;; first, yield in a non-cancellable way a few times to give the caller |
| 14 | + ;; a chance to queue up an `EVENT_CANCELLED` |
| 15 | + (local $i i32) |
| 16 | + (loop $loop |
| 17 | + (i32.ne (i32.const 0 (; NOT_CANCELLED ;) (call $thread-yield))) |
| 18 | + if unreachable end |
| 19 | + (local.set $i (i32.add (i32.const 1) (local.get $i))) |
| 20 | + (i32.ne (i32.const 10) (local.get $i)) |
| 21 | + br_if $loop |
| 22 | + ) |
| 23 | + |
| 24 | + i32.const 1 ;; CALLBACK_CODE_YIELD |
| 25 | + ) |
| 26 | + |
| 27 | + (func (export "f-callback") (param i32 i32 i32) (result i32) |
| 28 | + (i32.eq (i32.const 6 (; EVENT_CANCELLED ;)) (local.get 0)) |
| 29 | + (if (result i32) |
| 30 | + (then |
| 31 | + call $task-cancel |
| 32 | + i32.const 0 ;; CALLBACK_CODE_EXIT |
| 33 | + ) |
| 34 | + (else |
| 35 | + i32.const 1 ;; CALLBACK_CODE_YIELD |
| 36 | + ) |
| 37 | + ) |
| 38 | + ) |
| 39 | + ) |
| 40 | + |
| 41 | + (core func $task-cancel (canon task.cancel)) |
| 42 | + (core func $thread-yield (canon thread.yield)) |
| 43 | + |
| 44 | + (core instance $i (instantiate $m |
| 45 | + (with "" (instance |
| 46 | + (export "task.cancel" (func $task-cancel)) |
| 47 | + (export "thread.yield" (func $thread-yield)) |
| 48 | + )) |
| 49 | + )) |
| 50 | + |
| 51 | + (func (export "f") async (canon lift (core func $i "f") async (callback (func $i "f-callback")))) |
| 52 | + ) |
| 53 | + (instance $a (instantiate $a)) |
| 54 | + |
| 55 | + (component $b |
| 56 | + (import "a" (instance $a |
| 57 | + (export "f" (func async)) |
| 58 | + )) |
| 59 | + |
| 60 | + (core module $m |
| 61 | + (import "" "f" (func $f (result i32))) |
| 62 | + (import "" "subtask.cancel" (func $subtask-cancel (param i32) (result i32))) |
| 63 | + |
| 64 | + (func (export "f") |
| 65 | + (local $status i32) |
| 66 | + (local $subtask i32) |
| 67 | + |
| 68 | + (local.set $status (call $f)) |
| 69 | + (local.set $subtask (i32.shr_u (i32.const 4) (local.get $status))) |
| 70 | + (local.set $status (i32.and (i32.const 0xF) (local.get $status))) |
| 71 | + (i32.ne (i32.const 1 (; STATUS_STARTED ;)) (local.get $status)) |
| 72 | + if unreachable end |
| 73 | + (i32.ne (i32.const 4 (; STATUS_RETURN_CANCELLED ;)) (call $subtask-cancel (local.get $subtask))) |
| 74 | + if unreachable end |
| 75 | + ) |
| 76 | + ) |
| 77 | + |
| 78 | + (core func $f (canon lower (func $a "f") async)) |
| 79 | + (core func $subtask-cancel (canon subtask.cancel)) |
| 80 | + |
| 81 | + (core instance $i (instantiate $m |
| 82 | + (with "" (instance |
| 83 | + (export "f" (func $f)) |
| 84 | + (export "subtask.cancel" (func $subtask-cancel)) |
| 85 | + )) |
| 86 | + )) |
| 87 | + |
| 88 | + (func (export "f") async (canon lift (core func $i "f"))) |
| 89 | + ) |
| 90 | + (instance $b (instantiate $b |
| 91 | + (with "a" (instance $a)) |
| 92 | + )) |
| 93 | + |
| 94 | + (func (export "f") (alias export $b "f")) |
| 95 | +) |
| 96 | + |
| 97 | +(assert_return (invoke "f")) |
0 commit comments