Path: blob/main/crates/test-programs/src/bin/async_poll_stackless.rs
3069 views
#![expect(unsafe_op_in_unsafe_fn, reason = "old code, not worth updating yet")]12mod bindings {3wit_bindgen::generate!({4path: "../misc/component-async-tests/wit",5world: "poll",6});7}89use {10bindings::local::local::ready,11test_programs::async_::{12CALLBACK_CODE_EXIT, CALLBACK_CODE_YIELD, EVENT_NONE, EVENT_SUBTASK, STATUS_RETURNED,13context_get, context_set, subtask_drop, waitable_join, waitable_set_drop, waitable_set_new,14waitable_set_poll,15},16};1718#[cfg(target_arch = "wasm32")]19#[link(wasm_import_module = "[export]local:local/run")]20unsafe extern "C" {21#[link_name = "[task-return]run"]22fn task_return_run();23}24#[cfg(not(target_arch = "wasm32"))]25unsafe extern "C" fn task_return_run() {26unreachable!()27}2829fn async_when_ready(handle: u32) -> u32 {30#[cfg(not(target_arch = "wasm32"))]31{32_ = handle;33unreachable!()34}3536#[cfg(target_arch = "wasm32")]37{38#[link(wasm_import_module = "local:local/ready")]39unsafe extern "C" {40#[link_name = "[async-lower][method]thing.when-ready"]41fn call_when_ready(handle: u32) -> u32;42}43unsafe { call_when_ready(handle) }44}45}4647enum State {48S0,49S1 {50thing: Option<ready::Thing>,51set: u32,52},53S2 {54thing: Option<ready::Thing>,55set: u32,56call: u32,57},58S3 {59thing: Option<ready::Thing>,60set: u32,61call: u32,62},63S4 {64thing: Option<ready::Thing>,65set: u32,66},67S5 {68set: u32,69},70}7172#[unsafe(export_name = "[async-lift]local:local/run#run")]73unsafe extern "C" fn export_run() -> u32 {74context_set(u32::try_from(Box::into_raw(Box::new(State::S0)) as usize).unwrap());75callback_run(EVENT_NONE, 0, 0)76}7778#[unsafe(export_name = "[callback][async-lift]local:local/run#run")]79unsafe extern "C" fn callback_run(event0: u32, _: u32, _: u32) -> u32 {80let state = &mut *(usize::try_from(context_get()).unwrap() as *mut State);81match state {82State::S0 => {83assert_eq!(event0, EVENT_NONE);8485let thing = ready::Thing::new();86thing.set_ready(false);8788let set = waitable_set_new();8990*state = State::S1 {91thing: Some(thing),92set,93};9495CALLBACK_CODE_YIELD96}9798&mut State::S1 { ref mut thing, set } => {99let thing = thing.take().unwrap();100let (event0, _, _) = waitable_set_poll(set);101102assert_eq!(event0, EVENT_NONE);103104let result = async_when_ready(thing.handle());105let status = result & 0xf;106let call = result >> 4;107assert!(status != STATUS_RETURNED);108waitable_join(call, set);109110*state = State::S2 {111thing: Some(thing),112set,113call,114};115116CALLBACK_CODE_YIELD117}118119&mut State::S2 {120ref mut thing,121set,122call,123} => {124let thing = thing.take().unwrap();125let (event0, _, _) = waitable_set_poll(set);126127assert_eq!(event0, EVENT_NONE);128129thing.set_ready(true);130131*state = State::S3 {132thing: Some(thing),133set,134call,135};136137CALLBACK_CODE_YIELD138}139140&mut State::S3 {141ref mut thing,142set,143call,144} => {145let (event0, event1, event2) = waitable_set_poll(set);146147if event0 != EVENT_NONE {148assert_eq!(event0, EVENT_SUBTASK);149assert_eq!(event1, call);150assert_eq!(event2, STATUS_RETURNED);151152subtask_drop(call);153154*state = State::S4 {155thing: thing.take(),156set,157};158}159160CALLBACK_CODE_YIELD161}162163&mut State::S4 { ref mut thing, set } => {164let thing = thing.take().unwrap();165let (event0, _, _) = waitable_set_poll(set);166167assert_eq!(event0, EVENT_NONE);168169assert_eq!(async_when_ready(thing.handle()), STATUS_RETURNED);170171*state = State::S5 { set };172173CALLBACK_CODE_YIELD174}175176&mut State::S5 { set } => {177let (event0, _, _) = waitable_set_poll(set);178179assert_eq!(event0, EVENT_NONE);180181waitable_set_drop(set);182183drop(Box::from_raw(state));184185context_set(0);186187task_return_run();188189CALLBACK_CODE_EXIT190}191}192}193194// Unused function; required since this file is built as a `bin`:195fn main() {}196197198