Skip to content

Commit c72b2ac

Browse files
committed
feat: Add proper async ABI support to ZyntaxPromise
- Add with_poll_fn() constructor for separate init/poll functions - Add set_poll_fn() method for setting poll function after creation - Update comments to document Zyntax async ABI: - Constructor: {fn}_new(params...) -> StateMachine - Poll: async_wrapper(self: *StateMachine, cx: *Context) -> Poll - Reference async_support.rs for full async ABI documentation
1 parent 4c30e40 commit c72b2ac

1 file changed

Lines changed: 40 additions & 4 deletions

File tree

crates/zyntax_embed/src/runtime.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)