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(handle: u32) -> u32 { 31 #[cfg(not(target_arch = "wasm32"))] 32 { 33 _ = handle; 34 unreachable!() 35 } 36 37 #[cfg(target_arch = "wasm32")] 38 { 39 #[link(wasm_import_module = "local:local/ready")] 40 unsafe extern "C" { 41 #[link_name = "[async-lower][method]thing.when-ready"] 42 fn call_when_ready(handle: u32) -> u32; 43 } 44 unsafe { call_when_ready(handle) } 45 } 46 } 47 48 enum State { 49 S0, 50 S1 { 51 thing: Option<ready::Thing>, 52 set: u32, 53 }, 54 S2 { 55 thing: Option<ready::Thing>, 56 set: u32, 57 call: u32, 58 }, 59 S3 { 60 thing: Option<ready::Thing>, 61 set: u32, 62 call: u32, 63 }, 64 S4 { 65 thing: Option<ready::Thing>, 66 set: u32, 67 }, 68 S5 { 69 set: u32, 70 }, 71 } 72 73 #[unsafe(export_name = "[async-lift]local:local/run#run")] 74 unsafe extern "C" fn export_run() -> u32 { 75 context_set(u32::try_from(Box::into_raw(Box::new(State::S0)) as usize).unwrap()); 76 callback_run(EVENT_NONE, 0, 0) 77 } 78 79 #[unsafe(export_name = "[callback][async-lift]local:local/run#run")] 80 unsafe extern "C" fn callback_run(event0: u32, _: u32, _: u32) -> u32 { 81 let state = &mut *(usize::try_from(context_get()).unwrap() as *mut State); 82 match state { 83 State::S0 => { 84 assert_eq!(event0, EVENT_NONE); 85 86 let thing = ready::Thing::new(); 87 thing.set_ready(false); 88 89 let set = waitable_set_new(); 90 91 *state = State::S1 { 92 thing: Some(thing), 93 set, 94 }; 95 96 CALLBACK_CODE_YIELD 97 } 98 99 &mut State::S1 { ref mut thing, set } => { 100 let thing = thing.take().unwrap(); 101 let (event0, _, _) = waitable_set_poll(set); 102 103 assert_eq!(event0, EVENT_NONE); 104 105 let result = async_when_ready(thing.handle()); 106 let status = result & 0xf; 107 let call = result >> 4; 108 assert!(status != STATUS_RETURNED); 109 waitable_join(call, set); 110 111 *state = State::S2 { 112 thing: Some(thing), 113 set, 114 call, 115 }; 116 117 CALLBACK_CODE_YIELD 118 } 119 120 &mut State::S2 { 121 ref mut thing, 122 set, 123 call, 124 } => { 125 let thing = thing.take().unwrap(); 126 let (event0, _, _) = waitable_set_poll(set); 127 128 assert_eq!(event0, EVENT_NONE); 129 130 thing.set_ready(true); 131 132 *state = State::S3 { 133 thing: Some(thing), 134 set, 135 call, 136 }; 137 138 CALLBACK_CODE_YIELD 139 } 140 141 &mut State::S3 { 142 ref mut thing, 143 set, 144 call, 145 } => { 146 let (event0, event1, event2) = waitable_set_poll(set); 147 148 if event0 != EVENT_NONE { 149 assert_eq!(event0, EVENT_SUBTASK); 150 assert_eq!(event1, call); 151 assert_eq!(event2, STATUS_RETURNED); 152 153 subtask_drop(call); 154 155 *state = State::S4 { 156 thing: thing.take(), 157 set, 158 }; 159 } 160 161 CALLBACK_CODE_YIELD 162 } 163 164 &mut State::S4 { ref mut thing, set } => { 165 let thing = thing.take().unwrap(); 166 let (event0, _, _) = waitable_set_poll(set); 167 168 assert_eq!(event0, EVENT_NONE); 169 170 assert_eq!(async_when_ready(thing.handle()), STATUS_RETURNED); 171 172 *state = State::S5 { set }; 173 174 CALLBACK_CODE_YIELD 175 } 176 177 &mut State::S5 { set } => { 178 let (event0, _, _) = waitable_set_poll(set); 179 180 assert_eq!(event0, EVENT_NONE); 181 182 waitable_set_drop(set); 183 184 drop(Box::from_raw(state)); 185 186 context_set(0); 187 188 task_return_run(); 189 190 CALLBACK_CODE_EXIT 191 } 192 } 193 } 194 195 // Unused function; required since this file is built as a `bin`: 196 fn main() {} 197