Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/test-programs/src/bin/async_poll_stackless.rs
3069 views
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
198