@@ -1310,10 +1310,10 @@ and empty results.
13101310🔀 The ` async ` option specifies that the component wants to make (for imports)
13111311or support (for exports) multiple concurrent (asynchronous) calls. This option
13121312can be applied to any component-level function type and changes the derived
1313- Canonical ABI significantly. See the [ async explainer] ( Async.md ) for more
1314- details. When a function signature contains a ` future ` or ` stream ` , validation
1315- of ` canon lower` requires the ` async ` option to be set (since a synchronous
1316- call to a function using these types is highly likely to deadlock).
1313+ Canonical ABI significantly. See the [ async explainer] for more details. When
1314+ a function signature contains a ` future ` or ` stream ` , validation of `canon
1315+ lower` requires the ` async` option to be set (since a synchronous call to a
1316+ function using these types is highly likely to deadlock).
13171317
13181318🔀 The ` (callback ...) ` option may only be present in ` canon lift ` when the
13191319` async ` option has also been set and specifies a core function that is
@@ -1324,7 +1324,7 @@ validated to have the following core function type:
13241324 (param $payload i32)
13251325 (result $done i32))
13261326```
1327- Again, see the [ async explainer] ( Async.md ) for more details.
1327+ Again, see the [ async explainer] for more details.
13281328
13291329🔀 The ` always-task-return ` option may only be present in ` canon lift ` when
13301330` post-return ` is not set and specifies that even synchronously-lifted functions
@@ -1547,8 +1547,8 @@ transferring ownership of the newly-created resource to the export's caller.
15471547
15481548##### 🔀 Async built-ins
15491549
1550- See the [ async explainer] ( Async.md ) for high-level context and terminology and
1551- the [ Canonical ABI explainer] for detailed runtime semantics.
1550+ See the [ async explainer] for high-level context and terminology and the
1551+ [ Canonical ABI explainer] for detailed runtime semantics.
15521552
15531553###### 🔀 ` context.get `
15541554
@@ -1657,10 +1657,10 @@ where `event` is defined in WIT as:
16571657variant event {
16581658 none,
16591659 subtask(subtask-index, subtask-state),
1660- stream-read(stream-index, read-status ),
1661- stream-write(stream-index, write-status ),
1662- future-read(future-index, read-status ),
1663- future-write(future-index, write-status ),
1660+ stream-read(stream-index, copy-result ),
1661+ stream-write(stream-index, copy-result ),
1662+ future-read(future-index, copy-result ),
1663+ future-write(future-index, copy-result ),
16641664 task-cancelled,
16651665}
16661666
@@ -1672,7 +1672,6 @@ enum subtask-state {
16721672 cancelled-before-returned,
16731673}
16741674```
1675-
16761675The ` waitable-set.wait ` built-in waits for any one of the [ waitables] in the
16771676given [ waitable set] ` s ` to make progress and then returns an ` event `
16781677describing the event. The ` event ` ` none ` is never returned. Waitable sets
@@ -1685,6 +1684,13 @@ can be started (via export call) or resumed while the current task blocks. If
16851684code until ` wait ` returns (however, * other* component instances may execute
16861685code in the interim).
16871686
1687+ A ` subtask ` event notifies the supertask that its subtask is now in the given
1688+ state (the meanings of which are described by the [ async explainer] ).
1689+
1690+ The meanings of the ` {stream,future}-{read,write} ` events as well as the
1691+ definition of ` copy-result ` is given as part [ ` stream.read ` and
1692+ ` stream.write ` ] ( #-streamread-and-streamwrite ) below.
1693+
16881694In the Canonical ABI, the ` event-code ` return value provides the ` event `
16891695discriminant and the case payloads are stored as two contiguous ` i32 ` s at the
169016968-byte-aligned address ` payload-addr ` . (See also [ ` canon_waitable_set_wait ` ]
@@ -1791,119 +1797,106 @@ An analogous relationship exists among `readable-future-end<T>`,
17911797
17921798###### 🔀 ` stream.read ` and ` stream.write `
17931799
1794- | Synopsis | |
1795- | -------------------------------------------- | --------------------------------------------------------------------------- |
1796- | Approximate WIT signature for ` stream.read ` | ` func<T>(e: readable-stream-end<T>, b: writable-buffer<T>) -> read-status ` |
1797- | Approximate WIT signature for ` stream.write ` | ` func<T>(e: writable-stream-end<T>, b: readable-buffer<T>) -> write-status ` |
1798- | Canonical ABI signature | ` [stream-end:i32 ptr:i32 num:i32] -> [i32] ` |
1800+ | Synopsis | |
1801+ | -------------------------------------------- | ---------------------------------------------------------------------------------- |
1802+ | Approximate WIT signature for ` stream.read ` | ` func<T>(e: readable-stream-end<T>, b: writable-buffer<T>) -> option<copy-result> ` |
1803+ | Approximate WIT signature for ` stream.write ` | ` func<T>(e: writable-stream-end<T>, b: readable-buffer<T>) -> option<copy-result> ` |
1804+ | Canonical ABI signature | ` [stream-end:i32 ptr:i32 num:i32] -> [i32] ` |
17991805
1800- where ` read-status ` is defined in WIT as:
1806+ where ` copy-result ` is defined in WIT as:
18011807``` wit
1802- enum read-status {
1803- // The operation completed and read this many elements.
1804- complete(u32),
1805-
1806- // The operation did not complete immediately, so callers must wait for
1807- // the operation to complete by using `task.wait` or by returning to the
1808- // event loop.
1809- blocked,
1810-
1811- // The end of the stream has been reached.
1812- closed,
1808+ record copy-result {
1809+ progress: u32,
1810+ status: copy-status
18131811}
1814- ```
1815-
1816- and ` write-status ` is the same as ` read-status ` except without the optional
1817- error on ` closed ` , so it is defined in WIT as:
1818- ``` wit
1819- enum write-status {
1820- // The operation completed and wrote this many elements.
1821- complete(u32),
18221812
1823- // The operation did not complete immediately, so callers must wait for
1824- // the operation to complete by using `task.wait` or by returning to the
1825- // event loop.
1826- blocked,
1813+ enum copy-status {
1814+ // The read/write completed successfully and is ready for more.
1815+ completed,
18271816
1828- // The reader is no longer reading data .
1817+ // The other end closed and so there will be no more copies .
18291818 closed,
1819+
1820+ // The read/write was cancelled by {stream,future}.cancel-{read,write}.
1821+ cancelled
18301822}
18311823```
18321824
18331825The ` stream.read ` and ` stream.write ` built-ins take the matching [ readable or
18341826writable end] of a stream as the first parameter and a buffer for the ` T `
1835- values to be read from or written to. The return value is either the number of
1836- elements (possibly zero) that have been eagerly read or written, a sentinel
1837- indicating that the operation did not complete yet (` blocked ` ), or a sentinel
1838- indicating that the stream is closed (` closed ` ). For reads, ` closed ` has an
1839- optional error context describing the error that caused to the stream to close.
1840-
1841- In the Canonical ABI, the buffer is passed as a pointer to a buffer in linear
1842- memory and the size in elements of the buffer. (See [ ` canon_stream_read ` ] in
1843- the Canonical ABI explainer for details.)
1844-
1845- ` read-status ` and ` write-status ` are lowered in the Canonical ABI as:
1846- - The value ` 0xffff_ffff ` represents ` blocked ` .
1847- - Otherwise, if the bit ` 0x8000_0000 ` is set, the value represents ` closed ` .
1848- - Otherwise, the value represents ` complete ` and contains the number of
1849- element read or written.
1850-
1851- (See [ ` pack_async_copy_result ` ] in the Canonical ABI explainer for details.)
1827+ values to be read from or written to.
1828+
1829+ If the return value is a ` copy-result ` , then the ` progress ` field indicates how
1830+ many ` T ` elements were read or written from the given buffer before the stream
1831+ or future reached the status indicated in the ` status ` field. For example, a
1832+ return value of ` {progress:4, status:closed} ` from a ` stream<u32>.read ` means
1833+ that 32 bytes were copied into the given buffer before the writer end closed
1834+ the stream. The ` cancelled ` case can only arise as the result of a
1835+ ` {stream,future}.cancel-{read,write} ` operation (defined below) and is included
1836+ in ` copy-status ` because the ` copy-result ` type is shared.
1837+
1838+ If the return value is ` none ` , then the operation blocked and the caller needs
1839+ to [ wait] ( Async.md#waiting ) for progress (via ` waitable-set.{wait,poll} ` or, if
1840+ using a ` callback ` , by returning to the event loop) which will asynchronously
1841+ produce an ` event ` containing a ` copy-result ` .
1842+
1843+ In the Canonical ABI, the buffer is passed as an ` i32 ` offset into linear
1844+ memory and the ` i32 ` size in elements of the buffer and the
1845+ ` option<copy-result> ` return value is bit-packed into the single ` i32 ` return
1846+ value where:
1847+ * ` 0xffff_ffff ` represents ` none ` .
1848+ * Otherwise, the ` status ` is in the low 4 bits and the ` progress ` is in the
1849+ high 28 bits.
1850+
1851+ (See [ ` canon_stream_read ` ] in the Canonical ABI explainer for details.)
18521852
18531853###### 🔀 ` future.read ` and ` future.write `
18541854
1855- | Synopsis | |
1856- | -------------------------------------------- | ------------------------------------------------------------------------------ |
1857- | Approximate WIT signature for ` future.read ` | ` func<T>(e: readable-future-end<T>, b: writable-buffer<T; 1>) -> read-status ` |
1858- | Approximate WIT signature for ` future.write ` | ` func<T>(e: writable-future-end<T>, b: readable-buffer<T; 1>) -> write-status ` |
1859- | Canonical ABI signature | ` [future-end:i32 ptr:i32] -> [i32] ` |
1855+ | Synopsis | |
1856+ | -------------------------------------------- | ------------------------------------------------------------------------------------- |
1857+ | Approximate WIT signature for ` future.read ` | ` func<T>(e: readable-future-end<T>, b: writable-buffer<T; 1>) -> option<copy-result> ` |
1858+ | Approximate WIT signature for ` future.write ` | ` func<T>(e: writable-future-end<T>, b: readable-buffer<T; 1>) -> option<copy-result> ` |
1859+ | Canonical ABI signature | ` [future-end:i32 ptr:i32] -> [i32] ` |
18601860
1861- where ` read-status ` and ` write-status ` are defined as in
1862- [ ` stream.read ` and ` stream.write ` ] ( #-streamread-and-streamwrite ) .
1861+ where ` copy-result ` is defined as in [ ` stream.read ` and
1862+ ` stream.write ` ] ( #-streamread-and-streamwrite ) . The ` <T; 1> ` in the buffer types
1863+ indicates that these buffers may hold at most one ` T ` element.
18631864
18641865The ` future.{read,write} ` built-ins take the matching [ readable or writable
18651866end] of a future as the first parameter, and a buffer for a single ` T ` value to
1866- read into or write from. The return value is either ` complete ` if the future
1867- value was eagerly read or written, a sentinel indicating that the operation did
1868- not complete yet (` blocked ` ), or a sentinel indicating that the future is
1869- closed (` closed ` ).
1870-
1871- The number of elements returned when the value is ` complete ` is at most ` 1 ` .
1867+ read into or write from. The return value has the same meaning as with
1868+ ` stream.{read,write} ` , where the buffer-size has been fixed to ` 1 ` .
18721869
1873- The ` <T; 1> ` in the buffer types indicates that these buffers may hold at most
1874- one ` T ` element.
1875-
1876- In the Canonical ABI, the buffer is passed as a pointer to a buffer in linear
1877- memory. (See [ ` canon_future_read ` ] in the Canonical ABI explainer for details.)
1870+ The Canonical ABI is the same as ` stream.{read,write} ` except for the removal
1871+ of the ` num ` ` i32 ` parameter. (See [ ` canon_future_read ` ] in the Canonical ABI
1872+ explainer for details.)
18781873
18791874###### 🔀 ` stream.cancel-read ` , ` stream.cancel-write ` , ` future.cancel-read ` , and ` future.cancel-write `
18801875
1881- | Synopsis | |
1882- | --------------------------------------------------- | ---------------------------------------------------- |
1883- | Approximate WIT signature for ` stream.cancel-read ` | ` func<T>(e: readable-stream-end<T>) -> read-status ` |
1884- | Approximate WIT signature for ` stream.cancel-write ` | ` func<T>(e: writable-stream-end<T>) -> write-status ` |
1885- | Approximate WIT signature for ` future.cancel-read ` | ` func<T>(e: readable-future-end<T>) -> read-status ` |
1886- | Approximate WIT signature for ` future.cancel-write ` | ` func<T>(e: writable-future-end<T>) -> write-status ` |
1887- | Canonical ABI signature | ` [e: i32] -> [i32] ` |
1888-
1889- where ` read-status ` and ` write-status ` are defined as in
1890- [ ` stream.read ` and ` stream.write ` ] ( #-streamread-and-streamwrite ) .
1891-
1892- The ` stream.cancel-read ` , ` stream.cancel-write ` , ` future.cancel-read ` , and
1893- ` future.cancel-write ` built-ins take the matching [ readable or writable end] of
1894- a stream or future that has an outstanding ` blocked ` read or write. If
1895- cancellation finished eagerly, the return value is ` complete ` , and provides the
1896- number of elements read or written into the given buffer (` 0 ` or ` 1 ` for a
1897- ` future ` ). If cancellation blocks, the return value is ` blocked ` and the caller
1898- must ` task.wait ` . If the stream or future is closed, the return value is
1899- ` closed ` .
1900-
1901- For ` future.* ` , the number of elements returned when the value is ` complete `
1902- is at most ` 1 ` .
1903-
1904- In the Canonical ABI with the ` callback ` option, returning to the event loop is
1905- equivalent to a ` task.wait ` , and a ` {STREAM,FUTURE}_{READ,WRITE} ` event will be
1906- delivered to indicate the completion of the ` read ` or ` write ` . (See
1876+ | Synopsis | |
1877+ | --------------------------------------------------- | ----------------------------------------------------------- |
1878+ | Approximate WIT signature for ` stream.cancel-read ` | ` func<T>(e: readable-stream-end<T>) -> option<copy-result> ` |
1879+ | Approximate WIT signature for ` stream.cancel-write ` | ` func<T>(e: writable-stream-end<T>) -> option<copy-result> ` |
1880+ | Approximate WIT signature for ` future.cancel-read ` | ` func<T>(e: readable-future-end<T>) -> option<copy-result> ` |
1881+ | Approximate WIT signature for ` future.cancel-write ` | ` func<T>(e: writable-future-end<T>) -> option<copy-result> ` |
1882+ | Canonical ABI signature | ` [e: i32] -> [i32] ` |
1883+
1884+ where ` copy-result ` is defined as in [ ` stream.read ` and
1885+ ` stream.write ` ] ( #-streamread-and-streamwrite ) .
1886+
1887+ The ` {stream,future}.cancel-{read,write} ` built-ins take the matching [ readable
1888+ or writable end] of a stream or future that has a pending
1889+ ` {stream,future}.{read,write} ` .
1890+
1891+ If cancellation finishes eagerly, the return value is a ` copy-result ` . If
1892+ cancellation blocks, the return value is ` none ` and the caller must wait for a
1893+ corresponding ` {stream,future}-{read,write} ` event via
1894+ ` waitable-set.{wait,poll} ` or, when using a ` callback ` , returning to the event
1895+ loop. In either case, the ` status ` of the ` copy-result ` may be ` cancelled ` but
1896+ may also be ` completed ` or ` closed ` , if one of these racily happened first.
1897+
1898+ In the Canonical ABI, the ` option<copy-result> ` is bit-packed into the single
1899+ returned ` i32 ` in the same way as ` {stream,future}.{read,write} ` . (See
19071900[ ` canon_stream_cancel_read ` ] in the Canonical ABI explainer for details.)
19081901
19091902###### 🔀 ` stream.close-readable ` , ` stream.close-writable ` , ` future.close-readable ` , and ` future.close-writable `
@@ -2372,8 +2365,7 @@ the function has a compatible signature.
23722365When a function is annotated with ` async ` , bindings generators are expected to
23732366emit whatever asynchronous language construct is appropriate (such as an
23742367` async ` function in JS, Python or Rust). Note the absence of
2375- ` [async constructor] ` . See the [ async
2376- explainer] ( Async.md#sync-and-async-functions ) for more details.
2368+ ` [async constructor] ` . See the [ async explainer] for more details.
23772369
23782370The ` label ` production used inside ` plainname ` as well as the labels of
23792371` record ` and ` variant ` types are required to have [ kebab case] . The reason for
@@ -2900,12 +2892,12 @@ For some use-case-focused, worked examples, see:
29002892[ `canon_thread_spawn_ref` ] : CanonicalABI.md#-canon-threadspawn_ref
29012893[ `canon_thread_spawn_indirect` ] : CanonicalABI.md#-canon-threadspawn_indirect
29022894[ `canon_thread_available_parallelism` ] : CanonicalABI.md#-canon-threadavailable_parallelism
2903- [ `pack_async_copy_result` ] : CanonicalABI.md#-canon-streamfuturereadwrite
29042895[ the `close` built-ins ] : CanonicalABI.md#-canon-streamfutureclose-readablewritable
29052896[ Shared-Nothing ] : ../high-level/Choices.md
29062897[ Use Cases ] : ../high-level/UseCases.md
29072898[ Host Embeddings ] : ../high-level/UseCases.md#hosts-embedding-components
29082899
2900+ [ Async Explainer ] : Async.md
29092901[ Task ] : Async.md#task
29102902[ Current Task ] : Async.md#current-task
29112903[ Context-Local Storage ] : Async.md#context-local-storage
0 commit comments