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