1804060c8SJoel Dice #![expect(unsafe_op_in_unsafe_fn, reason = "old code, not worth updating yet")]
2804060c8SJoel Dice 
3804060c8SJoel Dice mod bindings {
4804060c8SJoel Dice     wit_bindgen::generate!({
5804060c8SJoel Dice         path: "../misc/component-async-tests/wit",
6804060c8SJoel Dice         world: "poll",
7804060c8SJoel Dice     });
8804060c8SJoel Dice }
9804060c8SJoel Dice 
10804060c8SJoel Dice use {
11804060c8SJoel Dice     bindings::local::local::ready,
12804060c8SJoel Dice     test_programs::async_::{
1334ba273bSJoel Dice         CALLBACK_CODE_EXIT, CALLBACK_CODE_YIELD, EVENT_NONE, EVENT_SUBTASK, STATUS_RETURNED,
14804060c8SJoel Dice         context_get, context_set, subtask_drop, waitable_join, waitable_set_drop, waitable_set_new,
1534ba273bSJoel Dice         waitable_set_poll,
16804060c8SJoel Dice     },
17804060c8SJoel Dice };
18804060c8SJoel Dice 
19804060c8SJoel Dice #[cfg(target_arch = "wasm32")]
20804060c8SJoel Dice #[link(wasm_import_module = "[export]local:local/run")]
21804060c8SJoel Dice unsafe extern "C" {
22020727d0SAlex Crichton     #[link_name = "[task-return]run"]
task_return_run()23804060c8SJoel Dice     fn task_return_run();
24804060c8SJoel Dice }
25804060c8SJoel Dice #[cfg(not(target_arch = "wasm32"))]
task_return_run()26804060c8SJoel Dice unsafe extern "C" fn task_return_run() {
27804060c8SJoel Dice     unreachable!()
28804060c8SJoel Dice }
29804060c8SJoel Dice 
async_when_ready(handle: u32) -> u3230*6ca03af1SJoel Dice fn async_when_ready(handle: u32) -> u32 {
31804060c8SJoel Dice     #[cfg(not(target_arch = "wasm32"))]
32804060c8SJoel Dice     {
33*6ca03af1SJoel Dice         _ = handle;
34804060c8SJoel Dice         unreachable!()
35804060c8SJoel Dice     }
36804060c8SJoel Dice 
37804060c8SJoel Dice     #[cfg(target_arch = "wasm32")]
38804060c8SJoel Dice     {
39804060c8SJoel Dice         #[link(wasm_import_module = "local:local/ready")]
40804060c8SJoel Dice         unsafe extern "C" {
41*6ca03af1SJoel Dice             #[link_name = "[async-lower][method]thing.when-ready"]
42*6ca03af1SJoel Dice             fn call_when_ready(handle: u32) -> u32;
43804060c8SJoel Dice         }
44*6ca03af1SJoel Dice         unsafe { call_when_ready(handle) }
45804060c8SJoel Dice     }
46804060c8SJoel Dice }
47804060c8SJoel Dice 
48804060c8SJoel Dice enum State {
49804060c8SJoel Dice     S0,
50*6ca03af1SJoel Dice     S1 {
51*6ca03af1SJoel Dice         thing: Option<ready::Thing>,
52*6ca03af1SJoel Dice         set: u32,
53*6ca03af1SJoel Dice     },
54*6ca03af1SJoel Dice     S2 {
55*6ca03af1SJoel Dice         thing: Option<ready::Thing>,
56*6ca03af1SJoel Dice         set: u32,
57*6ca03af1SJoel Dice         call: u32,
58*6ca03af1SJoel Dice     },
59*6ca03af1SJoel Dice     S3 {
60*6ca03af1SJoel Dice         thing: Option<ready::Thing>,
61*6ca03af1SJoel Dice         set: u32,
62*6ca03af1SJoel Dice         call: u32,
63*6ca03af1SJoel Dice     },
64*6ca03af1SJoel Dice     S4 {
65*6ca03af1SJoel Dice         thing: Option<ready::Thing>,
66*6ca03af1SJoel Dice         set: u32,
67*6ca03af1SJoel Dice     },
68*6ca03af1SJoel Dice     S5 {
69*6ca03af1SJoel Dice         set: u32,
70*6ca03af1SJoel Dice     },
71804060c8SJoel Dice }
72804060c8SJoel Dice 
73020727d0SAlex Crichton #[unsafe(export_name = "[async-lift]local:local/run#run")]
export_run() -> u3274804060c8SJoel Dice unsafe extern "C" fn export_run() -> u32 {
75804060c8SJoel Dice     context_set(u32::try_from(Box::into_raw(Box::new(State::S0)) as usize).unwrap());
76804060c8SJoel Dice     callback_run(EVENT_NONE, 0, 0)
77804060c8SJoel Dice }
78804060c8SJoel Dice 
79020727d0SAlex Crichton #[unsafe(export_name = "[callback][async-lift]local:local/run#run")]
callback_run(event0: u32, _: u32, _: u32) -> u328034ba273bSJoel Dice unsafe extern "C" fn callback_run(event0: u32, _: u32, _: u32) -> u32 {
81804060c8SJoel Dice     let state = &mut *(usize::try_from(context_get()).unwrap() as *mut State);
82804060c8SJoel Dice     match state {
83804060c8SJoel Dice         State::S0 => {
84804060c8SJoel Dice             assert_eq!(event0, EVENT_NONE);
85804060c8SJoel Dice 
86*6ca03af1SJoel Dice             let thing = ready::Thing::new();
87*6ca03af1SJoel Dice             thing.set_ready(false);
88804060c8SJoel Dice 
89804060c8SJoel Dice             let set = waitable_set_new();
90804060c8SJoel Dice 
91*6ca03af1SJoel Dice             *state = State::S1 {
92*6ca03af1SJoel Dice                 thing: Some(thing),
93*6ca03af1SJoel Dice                 set,
94*6ca03af1SJoel Dice             };
95804060c8SJoel Dice 
9634ba273bSJoel Dice             CALLBACK_CODE_YIELD
97804060c8SJoel Dice         }
98804060c8SJoel Dice 
99*6ca03af1SJoel Dice         &mut State::S1 { ref mut thing, set } => {
100*6ca03af1SJoel Dice             let thing = thing.take().unwrap();
10134ba273bSJoel Dice             let (event0, _, _) = waitable_set_poll(set);
10234ba273bSJoel Dice 
103804060c8SJoel Dice             assert_eq!(event0, EVENT_NONE);
104804060c8SJoel Dice 
105*6ca03af1SJoel Dice             let result = async_when_ready(thing.handle());
106804060c8SJoel Dice             let status = result & 0xf;
107804060c8SJoel Dice             let call = result >> 4;
108804060c8SJoel Dice             assert!(status != STATUS_RETURNED);
109804060c8SJoel Dice             waitable_join(call, set);
110804060c8SJoel Dice 
111*6ca03af1SJoel Dice             *state = State::S2 {
112*6ca03af1SJoel Dice                 thing: Some(thing),
113*6ca03af1SJoel Dice                 set,
114*6ca03af1SJoel Dice                 call,
115*6ca03af1SJoel Dice             };
116804060c8SJoel Dice 
11734ba273bSJoel Dice             CALLBACK_CODE_YIELD
118804060c8SJoel Dice         }
119804060c8SJoel Dice 
120*6ca03af1SJoel Dice         &mut State::S2 {
121*6ca03af1SJoel Dice             ref mut thing,
122*6ca03af1SJoel Dice             set,
123*6ca03af1SJoel Dice             call,
124*6ca03af1SJoel Dice         } => {
125*6ca03af1SJoel Dice             let thing = thing.take().unwrap();
12634ba273bSJoel Dice             let (event0, _, _) = waitable_set_poll(set);
12734ba273bSJoel Dice 
128804060c8SJoel Dice             assert_eq!(event0, EVENT_NONE);
129804060c8SJoel Dice 
130*6ca03af1SJoel Dice             thing.set_ready(true);
131804060c8SJoel Dice 
132*6ca03af1SJoel Dice             *state = State::S3 {
133*6ca03af1SJoel Dice                 thing: Some(thing),
134*6ca03af1SJoel Dice                 set,
135*6ca03af1SJoel Dice                 call,
136*6ca03af1SJoel Dice             };
137804060c8SJoel Dice 
13834ba273bSJoel Dice             CALLBACK_CODE_YIELD
139804060c8SJoel Dice         }
140804060c8SJoel Dice 
141*6ca03af1SJoel Dice         &mut State::S3 {
142*6ca03af1SJoel Dice             ref mut thing,
143*6ca03af1SJoel Dice             set,
144*6ca03af1SJoel Dice             call,
145*6ca03af1SJoel Dice         } => {
14634ba273bSJoel Dice             let (event0, event1, event2) = waitable_set_poll(set);
147804060c8SJoel Dice 
148804060c8SJoel Dice             if event0 != EVENT_NONE {
149804060c8SJoel Dice                 assert_eq!(event0, EVENT_SUBTASK);
15034ba273bSJoel Dice                 assert_eq!(event1, call);
151804060c8SJoel Dice                 assert_eq!(event2, STATUS_RETURNED);
152804060c8SJoel Dice 
15334ba273bSJoel Dice                 subtask_drop(call);
154804060c8SJoel Dice 
155*6ca03af1SJoel Dice                 *state = State::S4 {
156*6ca03af1SJoel Dice                     thing: thing.take(),
157*6ca03af1SJoel Dice                     set,
158*6ca03af1SJoel Dice                 };
159804060c8SJoel Dice             }
160804060c8SJoel Dice 
16134ba273bSJoel Dice             CALLBACK_CODE_YIELD
162804060c8SJoel Dice         }
163804060c8SJoel Dice 
164*6ca03af1SJoel Dice         &mut State::S4 { ref mut thing, set } => {
165*6ca03af1SJoel Dice             let thing = thing.take().unwrap();
16634ba273bSJoel Dice             let (event0, _, _) = waitable_set_poll(set);
16734ba273bSJoel Dice 
168804060c8SJoel Dice             assert_eq!(event0, EVENT_NONE);
169804060c8SJoel Dice 
170*6ca03af1SJoel Dice             assert_eq!(async_when_ready(thing.handle()), STATUS_RETURNED);
171804060c8SJoel Dice 
172804060c8SJoel Dice             *state = State::S5 { set };
173804060c8SJoel Dice 
17434ba273bSJoel Dice             CALLBACK_CODE_YIELD
175804060c8SJoel Dice         }
176804060c8SJoel Dice 
17734ba273bSJoel Dice         &mut State::S5 { set } => {
17834ba273bSJoel Dice             let (event0, _, _) = waitable_set_poll(set);
17934ba273bSJoel Dice 
180804060c8SJoel Dice             assert_eq!(event0, EVENT_NONE);
181804060c8SJoel Dice 
18234ba273bSJoel Dice             waitable_set_drop(set);
183804060c8SJoel Dice 
184804060c8SJoel Dice             drop(Box::from_raw(state));
185804060c8SJoel Dice 
186804060c8SJoel Dice             context_set(0);
187804060c8SJoel Dice 
188804060c8SJoel Dice             task_return_run();
189804060c8SJoel Dice 
190804060c8SJoel Dice             CALLBACK_CODE_EXIT
191804060c8SJoel Dice         }
192804060c8SJoel Dice     }
193804060c8SJoel Dice }
194804060c8SJoel Dice 
195804060c8SJoel Dice // Unused function; required since this file is built as a `bin`:
main()196804060c8SJoel Dice fn main() {}
197