-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reorganize the Canonical Built-ins section. #407
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -1213,6 +1213,7 @@ to wrap and a list of configuration options: | |||||||||||
```ebnf | ||||||||||||
canon ::= (canon lift core-prefix(<core:funcidx>) <canonopt>* bind-id(<externdesc>)) | ||||||||||||
| (canon lower <funcidx> <canonopt>* (core func <id>?)) | ||||||||||||
... | ||||||||||||
canonopt ::= string-encoding=utf8 | ||||||||||||
| string-encoding=utf16 | ||||||||||||
| string-encoding=latin1+utf16 | ||||||||||||
|
@@ -1361,49 +1362,59 @@ In addition to the `lift` and `lower` canonical function definitions which | |||||||||||
adapt *existing* functions, there are also a set of canonical "built-ins" that | ||||||||||||
define core functions out of nothing that can be imported by core modules to | ||||||||||||
dynamically interact with Canonical ABI entities like resources (and, when | ||||||||||||
async is added to the proposal, [tasks][Future and Stream Types]). | ||||||||||||
```ebnf | ||||||||||||
canon ::= ... | ||||||||||||
| (canon resource.new <typeidx> (core func <id>?)) | ||||||||||||
| (canon resource.drop <typeidx> async? (core func <id>?)) | ||||||||||||
| (canon resource.rep <typeidx> (core func <id>?)) | ||||||||||||
| (canon task.backpressure (core func <id>?)) 🔀 | ||||||||||||
| (canon task.return <core:typeidx> (core func <id>?)) 🔀 | ||||||||||||
| (canon task.wait (memory <core:memidx>) (core func <id>?)) 🔀 | ||||||||||||
| (canon task.poll (memory <core:memidx>) (core func <id>?)) 🔀 | ||||||||||||
| (canon task.yield (core func <id>?)) 🔀 | ||||||||||||
| (canon stream.new <typeidx> (core func <id>?)) 🔀 | ||||||||||||
| (canon stream.read <typeidx> (core func <id>?)) 🔀 | ||||||||||||
| (canon stream.write <typeidx> (core func <id>?)) 🔀 | ||||||||||||
| (canon stream.cancel-read async? (core func <id>?)) 🔀 | ||||||||||||
| (canon stream.cancel-write async? (core func <id>?)) 🔀 | ||||||||||||
| (canon future.new <typeidx> (core func <id>?)) 🔀 | ||||||||||||
| (canon future.read <typeidx> (core func <id>?)) 🔀 | ||||||||||||
| (canon future.write <typeidx> (core func <id>?)) 🔀 | ||||||||||||
| (canon future.cancel-read async? (core func <id>?)) 🔀 | ||||||||||||
| (canon future.cancel-write async? (core func <id>?)) 🔀 | ||||||||||||
| (canon waitable.drop (core func <id>?)) 🔀 | ||||||||||||
| (canon thread.spawn <typeidx> (core func <id>?)) 🧵 | ||||||||||||
| (canon thread.hw_concurrency (core func <id>?)) 🧵 | ||||||||||||
``` | ||||||||||||
async is added to the proposal, [tasks][Future and Stream Types] 🔀). | ||||||||||||
|
||||||||||||
##### Resource built-ins | ||||||||||||
|
||||||||||||
The `resource.new` built-in has type `[i32] -> [i32]` and creates a new | ||||||||||||
resource (with resource type `typeidx`) with the given `i32` value as its | ||||||||||||
representation and returning the `i32` index of a new handle pointing to this | ||||||||||||
resource. | ||||||||||||
###### `resource.new` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| -------------------------- | ------------------------- | | ||||||||||||
| Conceptual signature | `func<T>(repr: ...) -> T` | | ||||||||||||
| Binary encoding immediates | `T:<typeidx>` | | ||||||||||||
| Canonical ABI signature | `[repr:i32] -> [i32]` | | ||||||||||||
|
||||||||||||
The `resource.new` built-in creates a new resource (with resource type | ||||||||||||
`T`) with `repr` as its representation and returning the a new | ||||||||||||
handle pointing to this resource. | ||||||||||||
Comment on lines
+1378
to
+1379
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
||||||||||||
###### `resource.drop` | ||||||||||||
|
||||||||||||
When the `async` immediate is false: | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| -------------------------- | -------------------- | | ||||||||||||
| Conceptual signature | `func<T>(t: T)` | | ||||||||||||
| Binary encoding immediates | `T:<typeidx>` | | ||||||||||||
| Canonical ABI signature | `[t:i32] -> []` | | ||||||||||||
|
||||||||||||
When `async` immediate is true: | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| -------------------------- | ---------------------- | | ||||||||||||
| Conceptual signature | `func<T>(t: T) -> ...` | | ||||||||||||
| Binary encoding immediates | `T:<typeidx>` | | ||||||||||||
| Canonical ABI signature | `[t:i32] -> [i32]` | | ||||||||||||
|
||||||||||||
The `resource.drop` drops resource handle `t` (with resource type `T`). If the | ||||||||||||
dropped handle owns the resource, the resource's `dtor` is called, if present. | ||||||||||||
|
||||||||||||
The `resource.drop` drops a resource handle (with resource type `typeidx`) at | ||||||||||||
a given `i32` index. If the dropped handle owns the resource, the resource's | ||||||||||||
`dtor` is called, if present. If `async` is not specified, the core function | ||||||||||||
type of `resource.drop` is `[i32] -> []`. Otherwise, the core function type | ||||||||||||
of `async` `drop` is `[i32] -> [i32]`, where the returned `i32` is either `0` | ||||||||||||
(if the drop completed eagerly) or the index of the in-progress drop. | ||||||||||||
When the `async` immediate is true, the returned value indicates whether | ||||||||||||
the droop completed eagerly, or if not, identifies the in-progress drop. | ||||||||||||
|
||||||||||||
The `resource.rep` built-in has type `[i32] -> [i32]` and returns the `i32` | ||||||||||||
representation of the resource (with resource type `typeidx`) pointed to by the | ||||||||||||
handle at the given `i32` index. | ||||||||||||
In the Canonical ABI, the returned `i32` is either `0` (if the drop completed | ||||||||||||
eagerly) or the index of the in-progress drop. | ||||||||||||
|
||||||||||||
###### `resource.rep` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| -------------------------- | ---------------------- | | ||||||||||||
| Conceptual signature | `func<T>(t: T) -> ...` | | ||||||||||||
| Binary encoding immediates | `T:<typeidx>` | | ||||||||||||
| Canonical ABI signature | `[t:i32] -> [i32]` | | ||||||||||||
|
||||||||||||
The `resource.rep` built-in returns the representation of the resource | ||||||||||||
(with resource type `T`) pointed to by the handle `t`. | ||||||||||||
|
||||||||||||
As an example, the following component imports the `resource.new` built-in, | ||||||||||||
allowing it to create and return new resources to its client: | ||||||||||||
|
@@ -1439,11 +1450,27 @@ transferring ownership of the newly-created resource to the export's caller. | |||||||||||
See the [async explainer](Async.md) for high-level context and terminology | ||||||||||||
and the [Canonical ABI explainer] for detailed runtime semantics. | ||||||||||||
|
||||||||||||
The `task.backpressure` built-in has type `[i32] -> []` and allows the | ||||||||||||
###### 🔀 `task.backpressure` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| -------------------------- | --------------------- | | ||||||||||||
| Conceptual signature | `func(enable: bool)` | | ||||||||||||
| Binary encoding immediates | | | ||||||||||||
| Canonical ABI signature | `[enable:i32] -> []` | | ||||||||||||
|
||||||||||||
The `task.backpressure` built-in allows the | ||||||||||||
async-lifted callee to toggle a per-component-instance flag that, when set, | ||||||||||||
prevents new incoming export calls to the component (until the flag is unset). | ||||||||||||
This allows the component to exert [backpressure](Async.md#backpressure). | ||||||||||||
|
||||||||||||
###### 🔀 `task.return` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| -------------------------- | ------------------------ | | ||||||||||||
| Conceptual signature | `func<Func>(...) -> ...` | | ||||||||||||
| Binary encoding immediates | Func:<core:typeidx> | | ||||||||||||
| Canonical ABI signature | `[...] -> [...]` | | ||||||||||||
|
||||||||||||
The `task.return` built-in takes as parameters the result values of the | ||||||||||||
currently-executing task. This built-in must be called exactly once per export | ||||||||||||
activation. The `canon task.return` definition takes the type index of a core | ||||||||||||
|
@@ -1453,54 +1480,208 @@ of a component-level function taking the result types of the current task. (See | |||||||||||
also [Returning](Async.md#returning) in the async explainer and | ||||||||||||
[`canon_task_return`] in the Canonical ABI explainer.) | ||||||||||||
|
||||||||||||
The `task.wait` built-in has type `[i32] -> [i32]`, returning an event and | ||||||||||||
storing the 4-byte payload of the event at the address passed as parameter. | ||||||||||||
###### 🔀 `task.wait` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| -------------------------- | ------------------------------------- | | ||||||||||||
| Conceptual signature | `func() -> [kind:event, payload:...]` | | ||||||||||||
| Binary encoding immediates | Memory:<core:memidx> | | ||||||||||||
| Canonical ABI signature | `[payload_addr:i32] -> [kind:i32]` | | ||||||||||||
|
||||||||||||
```wit | ||||||||||||
enum event { | ||||||||||||
call-starting, | ||||||||||||
call-started, | ||||||||||||
call-returned, | ||||||||||||
call-done, | ||||||||||||
yielded, | ||||||||||||
stream-read, | ||||||||||||
stream-write, | ||||||||||||
future-read, | ||||||||||||
future-write, | ||||||||||||
} | ||||||||||||
``` | ||||||||||||
|
||||||||||||
The `task.wait` built-in returns an event code and the payload of the event. | ||||||||||||
|
||||||||||||
In the Canonical ABI, the returned payload is a 4-byte value and is stored | ||||||||||||
at address `payload_addr`. | ||||||||||||
|
||||||||||||
`task.wait` can be called whether or not `async` was present, allowing any sort | ||||||||||||
of code to synchronously wait for progress on any of the currently-executing | ||||||||||||
subtasks. (See also [Waiting](Async.md#waiting) in the async explainer and | ||||||||||||
[`canon_task_wait`] in the Canonical ABI explainer.) | ||||||||||||
|
||||||||||||
The `task.poll` built-in has type `[i32] -> [i32]`, returning whether or not | ||||||||||||
an event was immediately available as a boolean and, if true, storing the | ||||||||||||
event and its payload in the buffer pointed to by the `i32` parameter. | ||||||||||||
###### 🔀 `task.poll` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| -------------------------- | ---------------------------------------------------- | | ||||||||||||
| Conceptual signature | `func() -> [option<tuple<kind:event, payload:...>>]` | | ||||||||||||
| Binary encoding immediates | Memory:<core:memidx> | | ||||||||||||
| Canonical ABI signature | `[tuple_addr:i32] -> [is_some:i32]` | | ||||||||||||
|
||||||||||||
The `task.poll` built-in returns either `none` if no event was immediately | ||||||||||||
available, or `some` containing an event code and payload. | ||||||||||||
|
||||||||||||
In the Canonical ABI, the return value `is_some` holds a boolean value | ||||||||||||
indicating whether an event was immediately available, and if so, | ||||||||||||
the event code and payload are stored into the buffer pointed to by | ||||||||||||
`tuple_addr`. | ||||||||||||
(See also [`canon_task_poll`] in the Canonical ABI explainer.) | ||||||||||||
|
||||||||||||
The `task.yield` built-in has type `[] -> []` and simply allows the runtime to | ||||||||||||
###### 🔀 `task.yield` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| -------------------------- | ---------- | | ||||||||||||
| Conceptual signature | `func()` | | ||||||||||||
| Binary encoding immediates | | | ||||||||||||
| Canonical ABI signature | `[] -> []` | | ||||||||||||
|
||||||||||||
The `task.yield` built-in simply allows the runtime to | ||||||||||||
switch to another task, allowing a long-running computation to cooperatively | ||||||||||||
interleave with other tasks. (See also [`canon_task_yield`] in the Canonical | ||||||||||||
ABI explainer.) | ||||||||||||
|
||||||||||||
The `{stream,future}.new` built-ins have type `[] -> [i32]` and return a new | ||||||||||||
[writable end](Async.md#streams-and-futures) of a stream or future. (See | ||||||||||||
###### 🔀 `stream.new` and `future.new` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| ------------------------------------- | ------------------------ | | ||||||||||||
| Conceptual signature for `stream.new` | `func<T>() -> stream<T>` | | ||||||||||||
| Conceptual signature for `future.new` | `func<T>() -> future<T>` | | ||||||||||||
| Binary encoding immediates | `T:<typeidx>` | | ||||||||||||
| Canonical ABI signature | `[] -> [i32]` | | ||||||||||||
|
||||||||||||
The `stream.new` and `future.new` built-ins return the | ||||||||||||
[writable end](Async.md#streams-and-futures) of a new `stream<T>` or | ||||||||||||
`future<T>`. (See | ||||||||||||
[`canon_stream_new`] in the Canonical ABI explainer for details.) | ||||||||||||
|
||||||||||||
The `stream.{read,write]` built-ins have type `[i32 i32 i32] -> [i32]` and | ||||||||||||
take an index to the matching [readable or writable end](Async.md#streams-and-futures) | ||||||||||||
of a stream as the first parameter, a pointer to linear memory buffer as the | ||||||||||||
second parameter and the number of elements worth of available space in the | ||||||||||||
buffer. The return value is either the non-zero number of elements that have | ||||||||||||
been eagerly read or else a sentinel "`BLOCKED`" value. (See | ||||||||||||
###### 🔀 `stream.read` and `stream.write` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| -------------------------- | ----------------------------------------------------------- | | ||||||||||||
| Conceptual signature | `func<T>(stream: stream<T>, buffer: ...) -> stream-status` | | ||||||||||||
| Binary encoding immediates | `T:<typeidx>` | | ||||||||||||
| Canonical ABI signature | `[stream:i32 ptr:i32 num:i32] -> [i32]` | | ||||||||||||
|
||||||||||||
```wit | ||||||||||||
enum stream-status { | ||||||||||||
// The operation completed and read or wrote this many elements. | ||||||||||||
// This value is always non-zero. | ||||||||||||
complete(u64), | ||||||||||||
|
||||||||||||
// The operation did not complete immediately, so callers must wait for | ||||||||||||
// the operation to complete by using `task.wait` or by returning to the | ||||||||||||
// event loop. | ||||||||||||
blocked, | ||||||||||||
|
||||||||||||
// The stream is closed. For reading, the end of the stream has been | ||||||||||||
// reached. For writing, the reader is no longer reading data. | ||||||||||||
closed, | ||||||||||||
} | ||||||||||||
``` | ||||||||||||
|
||||||||||||
The `stream.read` and `stream.write` built-ins | ||||||||||||
take the matching [readable or writable end](Async.md#streams-and-futures) | ||||||||||||
of a stream as the first parameter, and a buffer for `T` values to | ||||||||||||
read into or write from. The return value is either the non-zero number | ||||||||||||
of elements that have been eagerly read or written, a sentinel indicating | ||||||||||||
that the operation did not complete yet (`blocked`), or a sentinel | ||||||||||||
indicating that the stream is closed (`closed`). | ||||||||||||
|
||||||||||||
In the Canonical ABI, the buffer is passed as a pointer to a buffer | ||||||||||||
in linear memory and the size in elements of the buffer. (See | ||||||||||||
[`canon_stream_read`] in the Canonical ABI explainer for details.) | ||||||||||||
|
||||||||||||
The `future.{read,write}` built-ins have type `[i32 i32] -> [i32]` and | ||||||||||||
take an index to the matching [readable or writable end](Async.md#streams-and-futures) | ||||||||||||
of a future as the first parameter and a pointer linear memory as the second | ||||||||||||
parameter. The return value is either `1` if the future value was eagerly | ||||||||||||
read from or written to the pointer or the sentinel "`BLOCKED`" value otherwise. | ||||||||||||
###### 🔀 `future.read` and `future.write` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| --------------------------------------- | ------------------------------------------------------- | | ||||||||||||
| Conceptual signature for `future.read` | `func<T>(in: future<T>, buffer: ...) -> future-status` | | ||||||||||||
| Conceptual signature for `future.write` | `func<T>(out: future<T>, buffer: ...) -> future-status` | | ||||||||||||
| Binary encoding immediates | `T:<typeidx>` | | ||||||||||||
| Canonical ABI signature | `[future:i32 ptr:i32] -> [i32]` | | ||||||||||||
|
||||||||||||
```wit | ||||||||||||
enum future-status { | ||||||||||||
// The operation completed and read or wrote the value. | ||||||||||||
complete, | ||||||||||||
|
||||||||||||
// The operation did not complete immediately, so callers must wait for | ||||||||||||
// the operation to complete by using `task.wait` or by returning to the | ||||||||||||
// event loop. | ||||||||||||
blocked, | ||||||||||||
|
||||||||||||
// The stream is closed. For reading, the end of the stream has been | ||||||||||||
// reached. For writing, the reader is no longer reading data. | ||||||||||||
closed, | ||||||||||||
} | ||||||||||||
``` | ||||||||||||
|
||||||||||||
The `future.{read,write}` built-ins | ||||||||||||
take the matching [readable or writable end](Async.md#streams-and-futures) | ||||||||||||
of a future as the first parameter, and a buffer for a single `T` value to | ||||||||||||
read into or write from. The return value is either `complete` if the future | ||||||||||||
value was eagerly read or written, a sentinel indicating that the | ||||||||||||
operation did not complete yet (`blocked`), or a sentinel indicating | ||||||||||||
that the future is closed (`closed`). | ||||||||||||
(See [`canon_future_read`] in the Canonical ABI explainer for details.) | ||||||||||||
|
||||||||||||
The `{stream,future}.cancel-{read,write}` built-ins have type `[i32] -> [i32]` | ||||||||||||
and take an index to the matching [readable or writable end](Async.md#streams-and-futures) | ||||||||||||
of a stream or future that has an outstanding "`BLOCKED`" read or write. If | ||||||||||||
cancellation finished eagerly, the return value is the number of elements read | ||||||||||||
or written into the given buffer (`0` or `1` for a `future`). If cancellation | ||||||||||||
blocks, the return value is the sentinel "`BLOCKED`" value and the caller must | ||||||||||||
`task.wait` (or, if using `callback`, return to the event loop) to receive a | ||||||||||||
`{STREAM,FUTURE}_{READ,WRITE}` event to indicate the completion of the `read` | ||||||||||||
###### 🔀 `stream.cancel-read`, `stream.cancel-write`, `future.cancel-read`, and `future.cancel-write` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| ---------------------------------------------- | ------------------------------------------ | | ||||||||||||
| Conceptual signature for `stream.cancel-read` | `func<T>(in: stream<T>) -> cancel-status` | | ||||||||||||
| Conceptual signature for `stream.cancel-write` | `func<T>(out: stream<T>) -> cancel-status` | | ||||||||||||
| Conceptual signature for `future.cancel-read` | `func<T>(in: future<T>) -> cancel-status` | | ||||||||||||
| Conceptual signature for `future.cancel-write` | `func<T>(out: future<T>) -> cancel-status` | | ||||||||||||
| Binary encoding immediates | `T:<typeidx>` | | ||||||||||||
| Canonical ABI signature | `[i32] -> [i32]` | | ||||||||||||
|
||||||||||||
```wit | ||||||||||||
enum cancel-status { | ||||||||||||
// The operation completed and read or wrote this many elements. | ||||||||||||
complete(u64), | ||||||||||||
|
||||||||||||
// The operation did not complete immediately, so callers must wait for | ||||||||||||
// the operation to complete by using `task.wait` or by returning to the | ||||||||||||
// event loop. | ||||||||||||
blocked, | ||||||||||||
|
||||||||||||
// The stream is closed. For reading, the end of the stream has been | ||||||||||||
// reached. For writing, the reader is no longer reading data. | ||||||||||||
closed, | ||||||||||||
} | ||||||||||||
``` | ||||||||||||
|
||||||||||||
The `stream.cancel-read`, `stream.cancel-write`, `future.cancel-read`, and `future.cancel-write` | ||||||||||||
builtins | ||||||||||||
take the matching [readable or writable end](Async.md#streams-and-futures) | ||||||||||||
of a stream or future that has an outstanding `blocked` read or write. If | ||||||||||||
cancellation finished eagerly, the return value is `complete`, and provides | ||||||||||||
the number of elements read or written (`0` or `1` for a `future`). If | ||||||||||||
cancellation blocks, the return value is `blocked` and the caller | ||||||||||||
must `task.wait`. If the stream or future is closed, the return value is | ||||||||||||
`closed`. | ||||||||||||
|
||||||||||||
In the Canonical ABI with the `callback` option, returning to the event | ||||||||||||
loop is equivalent to a `task.wait`, and a | ||||||||||||
`{STREAM,FUTURE}_{READ,WRITE}` event will be delivered to indicate the | ||||||||||||
completion of the `read` | ||||||||||||
or `write`. (See [`canon_stream_cancel_read`] in the Canonical ABI explainer | ||||||||||||
for details.) | ||||||||||||
|
||||||||||||
The `waitable.drop` built-in has type `[i32] -> []` and removes the indicated | ||||||||||||
TODO: Describe the `async` immediate field. | ||||||||||||
|
||||||||||||
###### 🔀 `waitable.drop` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| -------------------------- | ------------------ | | ||||||||||||
| Conceptual signature | `func(what: ...)` | | ||||||||||||
| Binary encoding immediates | | | ||||||||||||
| Canonical ABI signature | `[i32] -> []` | | ||||||||||||
|
||||||||||||
The `waitable.drop` built-in removes the indicated | ||||||||||||
[subtask](Async.md#subtask-and-supertask) or [stream or future](Async.md#streams-and-futures) | ||||||||||||
from the current instance's [waitables](Async.md#waiting) table, trapping if | ||||||||||||
the subtask isn't done or the stream or future is in the middle of reading | ||||||||||||
|
@@ -1513,10 +1694,26 @@ thread management. These are specified as built-ins and not core WebAssembly | |||||||||||
instructions because browsers expect this functionality to come from existing | ||||||||||||
Web/JS APIs. | ||||||||||||
|
||||||||||||
The `thread.spawn` built-in has type `[f:(ref null $f) c:i32] -> [i32]` and | ||||||||||||
###### 🧵 `thread.spawn` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| -------------------------- | ---------------------------------- | | ||||||||||||
| Conceptual signature | `func<FT>(f: ..., c: ...) -> bool` | | ||||||||||||
| Binary encoding immediates | `FT:<typeidx>` | | ||||||||||||
| Canonical ABI signature | `[f:(ref null $f) c:i32] -> [i32]` | | ||||||||||||
|
||||||||||||
The `thread.spawn` built-in | ||||||||||||
spawns a new thread by invoking the shared function `f` while passing `c` to it, | ||||||||||||
returning whether a thread was successfully spawned. | ||||||||||||
|
||||||||||||
###### 🧵 `resource.hw_concurrency` | ||||||||||||
|
||||||||||||
| Synopsis | | | ||||||||||||
| -------------------------- | --------------- | | ||||||||||||
| Conceptual signature | `func() -> u32` | | ||||||||||||
| Binary encoding immediates | | | ||||||||||||
| Canonical ABI signature | `[] -> [i32]` | | ||||||||||||
|
||||||||||||
The `resource.hw_concurrency` built-in has type `[] -> [i32]` and returns the | ||||||||||||
number of threads that can be expected to execute concurrently. | ||||||||||||
|
||||||||||||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Skimming through them, the 'Conceptual signature' row doesn't seem to add much value over the 'Canonical ABI Signature' row and sortof adds a bit of its own confusion, since it has '...' and its own custom syntax which one now has to extrapolate from. Independently, I think the 'Binary encoding immediates' are a bit out of place, since if you're implementing a binary decoder and interested in this information, you're going to need to read Binary.md anyways to see where and how the immediates are embedded in the overall definition. Thus, I think we should replace the 3-row table in each of these sub-headings with a single triple-backtick code block that contains only the Canonical ABI Signature.
Separately, I see the EBNF for
resource.new
and all the other built-ins is removed above, so I think we should introduce these productions in each of these subsections for reference. So, combined with the above, maybe an example forresource.new
could look like:"""
The syntax for the
resource.new
built-in is:the Core WebAssembly signature for this built-in defined by the Canonical ABI is:
... prose describing both together ...
"""