@@ -1671,6 +1671,38 @@ impl ZyntaxPromise {
16711671 }
16721672 }
16731673
1674+ /// Create a new promise with separate constructor and poll functions
1675+ ///
1676+ /// This follows the Zyntax async ABI where:
1677+ /// - `init_fn`: `{fn}_new(params...) -> *mut StateMachine` - constructor
1678+ /// - `poll_fn`: `async_wrapper(self: *StateMachine, cx: *Context) -> Poll` - poll function
1679+ ///
1680+ /// See `crates/compiler/src/async_support.rs` for the full async ABI.
1681+ pub fn with_poll_fn ( init_fn : * const u8 , poll_fn : * const u8 , args : Vec < DynamicValue > ) -> Self {
1682+ let task_id = NEXT_TASK_ID . fetch_add ( 1 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
1683+ Self {
1684+ state : Arc :: new ( Mutex :: new ( PromiseInner {
1685+ init_fn,
1686+ poll_fn : Some ( poll_fn) ,
1687+ args,
1688+ state : PromiseState :: Pending ,
1689+ state_machine : None ,
1690+ ready_queue : Arc :: new ( Mutex :: new ( std:: collections:: VecDeque :: new ( ) ) ) ,
1691+ task_id,
1692+ poll_count : 0 ,
1693+ waker : None ,
1694+ } ) ) ,
1695+ }
1696+ }
1697+
1698+ /// Set the poll function for this promise
1699+ ///
1700+ /// Call this before polling if the promise was created with just an init function.
1701+ pub fn set_poll_fn ( & self , poll_fn : * const u8 ) {
1702+ let mut inner = self . state . lock ( ) . unwrap ( ) ;
1703+ inner. poll_fn = Some ( poll_fn) ;
1704+ }
1705+
16741706 /// Poll the promise for completion
16751707 ///
16761708 /// Returns the current state without blocking.
@@ -1765,10 +1797,14 @@ impl ZyntaxPromise {
17651797
17661798 inner. state_machine = Some ( state_machine) ;
17671799
1768- // For now, assume the poll function follows right after the state machine
1769- // In a real implementation, this would be part of the async function's vtable
1770- // or returned alongside the state machine pointer
1771- inner. poll_fn = Some ( inner. init_fn ) ; // Use same function for polling
1800+ // The async ABI in Zyntax generates two functions:
1801+ // 1. Constructor: `{fn}_new(params...) -> StateMachine` (init_fn)
1802+ // 2. Poll: `async_wrapper(self: *StateMachine, cx: *Context) -> Poll`
1803+ //
1804+ // The poll function pointer should be provided separately when creating
1805+ // the promise. For now, we use the same function pointer pattern but
1806+ // the caller should pass the correct poll function via set_poll_fn().
1807+ // See: crates/compiler/src/async_support.rs for the async ABI details.
17721808 }
17731809 }
17741810
0 commit comments