1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//! Definition of the "C ABI" of how imported functions interact with exported
//! tasks.
//!
//! Ok this crate is written in Rust, why in the world does this exist? This
//! comment is intended to explain this rationale but the tl;dr; is we want
//! this to work:
//!
//! * Within a single component ...
//! * One rust crate uses `wit-bindgen 0.A.0` to generate an exported function.
//! * One rust crate uses `wit-bindgen 0.B.0` to bind an imported function.
//! * The two crates are connected in the application with
//! `std::future::Future`.
//!
//! Without this module this situation won't work because 0.A.0 has no
//! knowledge of 0.B.0 meaning that 0.B.0 has no means of inserting a `waitable`
//! into the `waitable-set` managed by 0.A.0's export.
//!
//! To solve this problem the long-term intention is that something will live
//! in `wasi-libc` itself, but in the meantime it's living "somewhere" within
//! `wit-bindgen 0.*.0`. Specifically all `wit-bindgen` versions will
//! reference, via C linkage, a single function which is used to manipulate a
//! single pointer in linear memory. This pointer is a `wasip3_task` structure
//! which has all the various fields to use it.
//!
//! The `wasip3_task_set` symbol is itself defined in C inside of the
//! `src/wit_bindgen_cabi.c` file at this time, specifically because it's
//! annotated with `__weak__` meaning that any definition of it suffices. This
//! isn't possible to define in stable Rust (specifically `__weak__`).
//!
//! Once `wasip3_task_set` is defined everything then operates via indirection,
//! aka based off the returned pointer. The intention is that exported functions
//! will set this (it's sort of like an executor) and then imported functions
//! will all use this as the source of registering waitables. In the end that
//! means that it's possible to share types with `std::future::Future` that
//! are backed at the ABI level with this "channel".
//!
//! In the future it's hoped that this can move into `wasi-libc` itself, or if
//! `wasi-libc` provides something else that would be prioritized over this.
//! For now this is basically an affordance that we're going to be frequently
//! releaseing new major versions of `wit-bindgen` and we don't want to force
//! applications to all be using the exact same version of the bindings
//! generator and async bindings.
//!
//! Additionally for now this file is serving as documentation of this
//! interface.
//!
//! # Revisions
//!
//! This interface is intended to be evolvable over time if needed. Notably the
//! original task structure, `wasip3_task`, has a `version` field where certain
//! version levels imply the existence of certain fields. The historical
//! revisions are:
//!
//! ### V1
//!
//! This was the original version. This is the original specification of
//! `wasip3_task_set` and `wasip3_task`.
//!
//! ### V2
//!
//! This was added 2026-06-17 in response to #1618. This added
//! `wasip3_task_v2` and `wasip3_task_vtable`. This version enables cloning a
//! task to create a strong reference to it independent of the stack lifetime
//! that `wasip3_task_set` is required to uphold. This necessitated introducing
//! `clone` and `drop` callbacks to manage the lifetime of this reference.
//! While doing this everything was moved into a vtable structure instead of
//! inline in `wasip3_task` to make it easier to add more function pointers
//! in the future if necessary.
use c_void;
extern_wasm!
/// The first version of `wasip3_task` which implies the existence of the
/// fields `ptr`, `waitable_register`, and `waitable_unregister`.
pub const WASIP3_TASK_V1: u32 = 1;
pub const WASIP3_TASK_V2: u32 = 2;
/// Indirect "vtable" used to connect imported functions and exported tasks.
/// Executors (e.g. exported functions) define and manage this while imports
/// use it.
unsafe
unsafe
/// Representation when `wasip3_task::version` is `WASIP3_TASK_V2`.
/// Function pointer operations that can operate on `wasip3_task::ptr`.
///
/// This was introduced in the "v2" ABI and is a member of `wasip3_task_v2`.