@@ -1310,10 +1310,10 @@ and empty results.
1310
1310
🔀 The ` async ` option specifies that the component wants to make (for imports)
1311
1311
or support (for exports) multiple concurrent (asynchronous) calls. This option
1312
1312
can 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).
1317
1317
1318
1318
🔀 The ` (callback ...) ` option may only be present in ` canon lift ` when the
1319
1319
` 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:
1324
1324
(param $payload i32)
1325
1325
(result $done i32))
1326
1326
```
1327
- Again, see the [ async explainer] ( Async.md ) for more details.
1327
+ Again, see the [ async explainer] for more details.
1328
1328
1329
1329
🔀 The ` always-task-return ` option may only be present in ` canon lift ` when
1330
1330
` 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.
1547
1547
1548
1548
##### 🔀 Async built-ins
1549
1549
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.
1552
1552
1553
1553
###### 🔀 ` context.get `
1554
1554
@@ -1657,10 +1657,10 @@ where `event` is defined in WIT as:
1657
1657
variant event {
1658
1658
none,
1659
1659
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 ),
1664
1664
task-cancelled,
1665
1665
}
1666
1666
@@ -1672,7 +1672,6 @@ enum subtask-state {
1672
1672
cancelled-before-returned,
1673
1673
}
1674
1674
```
1675
-
1676
1675
The ` waitable-set.wait ` built-in waits for any one of the [ waitables] in the
1677
1676
given [ waitable set] ` s ` to make progress and then returns an ` event `
1678
1677
describing 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
1685
1684
code until ` wait ` returns (however, * other* component instances may execute
1686
1685
code in the interim).
1687
1686
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
+
1688
1694
In the Canonical ABI, the ` event-code ` return value provides the ` event `
1689
1695
discriminant and the case payloads are stored as two contiguous ` i32 ` s at the
1690
1696
8-byte-aligned address ` payload-addr ` . (See also [ ` canon_waitable_set_wait ` ]
@@ -1791,119 +1797,106 @@ An analogous relationship exists among `readable-future-end<T>`,
1791
1797
1792
1798
###### 🔀 ` stream.read ` and ` stream.write `
1793
1799
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] ` |
1799
1805
1800
- where ` read-status ` is defined in WIT as:
1806
+ where ` copy-result ` is defined in WIT as:
1801
1807
``` 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
1813
1811
}
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),
1822
1812
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,
1827
1816
1828
- // The reader is no longer reading data .
1817
+ // The other end closed and so there will be no more copies .
1829
1818
closed,
1819
+
1820
+ // The read/write was cancelled by {stream,future}.cancel-{read,write}.
1821
+ cancelled
1830
1822
}
1831
1823
```
1832
1824
1833
1825
The ` stream.read ` and ` stream.write ` built-ins take the matching [ readable or
1834
1826
writable 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.)
1852
1852
1853
1853
###### 🔀 ` future.read ` and ` future.write `
1854
1854
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] ` |
1860
1860
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.
1863
1864
1864
1865
The ` future.{read,write} ` built-ins take the matching [ readable or writable
1865
1866
end] 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 ` .
1872
1869
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.)
1878
1873
1879
1874
###### 🔀 ` stream.cancel-read ` , ` stream.cancel-write ` , ` future.cancel-read ` , and ` future.cancel-write `
1880
1875
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
1907
1900
[ ` canon_stream_cancel_read ` ] in the Canonical ABI explainer for details.)
1908
1901
1909
1902
###### 🔀 ` stream.close-readable ` , ` stream.close-writable ` , ` future.close-readable ` , and ` future.close-writable `
@@ -2372,8 +2365,7 @@ the function has a compatible signature.
2372
2365
When a function is annotated with ` async ` , bindings generators are expected to
2373
2366
emit whatever asynchronous language construct is appropriate (such as an
2374
2367
` 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.
2377
2369
2378
2370
The ` label ` production used inside ` plainname ` as well as the labels of
2379
2371
` 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:
2900
2892
[ `canon_thread_spawn_ref` ] : CanonicalABI.md#-canon-threadspawn_ref
2901
2893
[ `canon_thread_spawn_indirect` ] : CanonicalABI.md#-canon-threadspawn_indirect
2902
2894
[ `canon_thread_available_parallelism` ] : CanonicalABI.md#-canon-threadavailable_parallelism
2903
- [ `pack_async_copy_result` ] : CanonicalABI.md#-canon-streamfuturereadwrite
2904
2895
[ the `close` built-ins ] : CanonicalABI.md#-canon-streamfutureclose-readablewritable
2905
2896
[ Shared-Nothing ] : ../high-level/Choices.md
2906
2897
[ Use Cases ] : ../high-level/UseCases.md
2907
2898
[ Host Embeddings ] : ../high-level/UseCases.md#hosts-embedding-components
2908
2899
2900
+ [ Async Explainer ] : Async.md
2909
2901
[ Task ] : Async.md#task
2910
2902
[ Current Task ] : Async.md#current-task
2911
2903
[ Context-Local Storage ] : Async.md#context-local-storage
0 commit comments