Path: blob/main/crates/test-programs/src/bin/async_poll_stackless.rs
1693 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_POLL, EVENT_NONE, EVENT_SUBTASK, STATUS_RETURNED,13context_get, context_set, subtask_drop, waitable_join, waitable_set_drop, waitable_set_new,14},15};1617#[cfg(target_arch = "wasm32")]18#[link(wasm_import_module = "[export]local:local/run")]19unsafe extern "C" {20#[link_name = "[task-return][async]run"]21fn task_return_run();22}23#[cfg(not(target_arch = "wasm32"))]24unsafe extern "C" fn task_return_run() {25unreachable!()26}2728fn async_when_ready() -> u32 {29#[cfg(not(target_arch = "wasm32"))]30{31unreachable!()32}3334#[cfg(target_arch = "wasm32")]35{36#[link(wasm_import_module = "local:local/ready")]37unsafe extern "C" {38#[link_name = "[async-lower][async]when-ready"]39fn call_when_ready() -> u32;40}41unsafe { call_when_ready() }42}43}4445enum State {46S0,47S1 { set: u32 },48S2 { set: u32, call: u32 },49S3 { set: u32, call: u32 },50S4 { set: u32 },51S5 { set: u32 },52}5354#[unsafe(export_name = "[async-lift]local:local/run#[async]run")]55unsafe extern "C" fn export_run() -> u32 {56context_set(u32::try_from(Box::into_raw(Box::new(State::S0)) as usize).unwrap());57callback_run(EVENT_NONE, 0, 0)58}5960#[unsafe(export_name = "[callback][async-lift]local:local/run#[async]run")]61unsafe extern "C" fn callback_run(event0: u32, event1: u32, event2: u32) -> u32 {62let state = &mut *(usize::try_from(context_get()).unwrap() as *mut State);63match state {64State::S0 => {65assert_eq!(event0, EVENT_NONE);6667ready::set_ready(false);6869let set = waitable_set_new();7071*state = State::S1 { set };7273CALLBACK_CODE_POLL | (set << 4)74}7576State::S1 { set } => {77assert_eq!(event0, EVENT_NONE);7879let set = *set;80let result = async_when_ready();81let status = result & 0xf;82let call = result >> 4;83assert!(status != STATUS_RETURNED);84waitable_join(call, set);8586*state = State::S2 { set, call };8788CALLBACK_CODE_POLL | (set << 4)89}9091State::S2 { set, call } => {92assert_eq!(event0, EVENT_NONE);9394let set = *set;95let call = *call;96ready::set_ready(true);9798*state = State::S3 { set, call };99100CALLBACK_CODE_POLL | (set << 4)101}102103State::S3 { set, call } => {104let set = *set;105106if event0 != EVENT_NONE {107assert_eq!(event0, EVENT_SUBTASK);108assert_eq!(event1, *call);109assert_eq!(event2, STATUS_RETURNED);110111subtask_drop(*call);112113*state = State::S4 { set };114}115116CALLBACK_CODE_POLL | (set << 4)117}118119State::S4 { set } => {120assert_eq!(event0, EVENT_NONE);121122let set = *set;123assert_eq!(async_when_ready(), STATUS_RETURNED);124125*state = State::S5 { set };126127CALLBACK_CODE_POLL | (set << 4)128}129130State::S5 { set } => {131assert_eq!(event0, EVENT_NONE);132133waitable_set_drop(*set);134135drop(Box::from_raw(state));136137context_set(0);138139task_return_run();140141CALLBACK_CODE_EXIT142}143}144}145146// Unused function; required since this file is built as a `bin`:147fn main() {}148149150