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"]
task_return_run()23 fn task_return_run();
24 }
25 #[cfg(not(target_arch = "wasm32"))]
task_return_run()26 unsafe extern "C" fn task_return_run() {
27 unreachable!()
28 }
29
async_when_ready(handle: u32) -> u3230 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")]
export_run() -> u3274 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")]
callback_run(event0: u32, _: u32, _: u32) -> u3280 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`:
main()196 fn main() {}
197