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