1 #![expect(unsafe_op_in_unsafe_fn, reason = "old code, not worth updating yet")] 2 3 mod bindings { 4 wit_bindgen::generate!({ 5 path: "../misc/component-async-tests/wit", 6 world: "poll", 7 }); 8 } 9 10 use { 11 bindings::local::local::ready, 12 test_programs::async_::{ 13 CALLBACK_CODE_EXIT, CALLBACK_CODE_YIELD, EVENT_NONE, EVENT_SUBTASK, STATUS_RETURNED, 14 context_get, context_set, subtask_drop, waitable_join, waitable_set_drop, waitable_set_new, 15 waitable_set_poll, 16 }, 17 }; 18 19 #[cfg(target_arch = "wasm32")] 20 #[link(wasm_import_module = "[export]local:local/run")] 21 unsafe extern "C" { 22 #[link_name = "[task-return]run"] 23 fn task_return_run(); 24 } 25 #[cfg(not(target_arch = "wasm32"))] 26 unsafe extern "C" fn task_return_run() { 27 unreachable!() 28 } 29 30 fn async_when_ready() -> u32 { 31 #[cfg(not(target_arch = "wasm32"))] 32 { 33 unreachable!() 34 } 35 36 #[cfg(target_arch = "wasm32")] 37 { 38 #[link(wasm_import_module = "local:local/ready")] 39 unsafe extern "C" { 40 #[link_name = "[async-lower]when-ready"] 41 fn call_when_ready() -> u32; 42 } 43 unsafe { call_when_ready() } 44 } 45 } 46 47 enum State { 48 S0, 49 S1 { set: u32 }, 50 S2 { set: u32, call: u32 }, 51 S3 { set: u32, call: u32 }, 52 S4 { set: u32 }, 53 S5 { set: u32 }, 54 } 55 56 #[unsafe(export_name = "[async-lift]local:local/run#run")] 57 unsafe extern "C" fn export_run() -> u32 { 58 context_set(u32::try_from(Box::into_raw(Box::new(State::S0)) as usize).unwrap()); 59 callback_run(EVENT_NONE, 0, 0) 60 } 61 62 #[unsafe(export_name = "[callback][async-lift]local:local/run#run")] 63 unsafe extern "C" fn callback_run(event0: u32, _: u32, _: u32) -> u32 { 64 let state = &mut *(usize::try_from(context_get()).unwrap() as *mut State); 65 match state { 66 State::S0 => { 67 assert_eq!(event0, EVENT_NONE); 68 69 ready::set_ready(false); 70 71 let set = waitable_set_new(); 72 73 *state = State::S1 { set }; 74 75 CALLBACK_CODE_YIELD 76 } 77 78 &mut State::S1 { set } => { 79 let (event0, _, _) = waitable_set_poll(set); 80 81 assert_eq!(event0, EVENT_NONE); 82 83 let result = async_when_ready(); 84 let status = result & 0xf; 85 let call = result >> 4; 86 assert!(status != STATUS_RETURNED); 87 waitable_join(call, set); 88 89 *state = State::S2 { set, call }; 90 91 CALLBACK_CODE_YIELD 92 } 93 94 &mut State::S2 { set, call } => { 95 let (event0, _, _) = waitable_set_poll(set); 96 97 assert_eq!(event0, EVENT_NONE); 98 99 ready::set_ready(true); 100 101 *state = State::S3 { set, call }; 102 103 CALLBACK_CODE_YIELD 104 } 105 106 &mut State::S3 { set, call } => { 107 let (event0, event1, event2) = waitable_set_poll(set); 108 109 if event0 != EVENT_NONE { 110 assert_eq!(event0, EVENT_SUBTASK); 111 assert_eq!(event1, call); 112 assert_eq!(event2, STATUS_RETURNED); 113 114 subtask_drop(call); 115 116 *state = State::S4 { set }; 117 } 118 119 CALLBACK_CODE_YIELD 120 } 121 122 &mut State::S4 { set } => { 123 let (event0, _, _) = waitable_set_poll(set); 124 125 assert_eq!(event0, EVENT_NONE); 126 127 assert_eq!(async_when_ready(), STATUS_RETURNED); 128 129 *state = State::S5 { set }; 130 131 CALLBACK_CODE_YIELD 132 } 133 134 &mut State::S5 { set } => { 135 let (event0, _, _) = waitable_set_poll(set); 136 137 assert_eq!(event0, EVENT_NONE); 138 139 waitable_set_drop(set); 140 141 drop(Box::from_raw(state)); 142 143 context_set(0); 144 145 task_return_run(); 146 147 CALLBACK_CODE_EXIT 148 } 149 } 150 } 151 152 // Unused function; required since this file is built as a `bin`: 153 fn main() {} 154