Skip to content

Commit

Permalink
Add a "Wit in WASI" document. (#517)
Browse files Browse the repository at this point in the history
* Add a "Wit in WASI" document.

Add a "Wit in WASI" document explaining how to use Wit in WASI
proposals, including some conventions, and the recommended workarounds
for component-model features that are not available yet.

* Update use syntax.

* Add a note about value-import emulation.
  • Loading branch information
sunfishcode authored Feb 27, 2023
1 parent 992611e commit ddfe3d1
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Once you feel ready, you can add a vote to the [WASI meeting agenda] to move to

### Phase 1: Write spec text

At this point, the WASI SG chair will create a new repo for the proposal in the WebAssembly GitHub org. This will follow the conventions of the [proposal template]. If you have any questions about how to fill in the spec template, you can reach out to the WASI SG chair.
At this point, the WASI SG chair will create a new repo for the proposal in the WebAssembly GitHub org. This will follow the conventions of the [proposal template] and [Wit in WASI](docs/WitInWasi.md). If you have any questions about how to fill in the spec template, you can reach out to the WASI SG chair.

As part of moving to the next phase, the champions need to define the acceptance criteria for Phase 4. This is because WASI includes APIs that cover a diversity of different domains and use cases, so the acceptance criteria can be very different between different proposals.

Expand Down
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ WASI is transitioning away from the `witx` format and its early experimental ABI

All new API proposals should use the new format and the new repo structure that is shown in the [proposal template](https://github.com/WebAssembly/wasi-proposal-template).

Some APIs can not yet be supported in the `wit` format. The advancement of these proposals will be unblocked with work that is ongoing:

- Proposals that require async/streams are expected to be unblocked in early Q2 2022
- Proposals that depend on libc are expected to be unblocked by work in `wasi-libc` and elsewhere. Until then, implementers of these APIs should continue to use the snapshots in this repo, which use the `witx` format. We will provide updates on the progress of this work in the bi-weekly meetings.
See the [Wit in WASI](docs/WitInWasi.md) document for more information about using Wit for WASI proposals.

---

Expand Down
158 changes: 158 additions & 0 deletions docs/WitInWasi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# Wit in WASI

Starting in Preview2, WASI APIs are defined using the [Wit IDL].

[Wit IDL]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md

To set up a git repository, start by cloning the [wasi-proposal-template],
renaming the wit file, and adding content and new files as needed.

[wasi-proposal-template]: https://github.com/WebAssembly/wasi-proposal-template/

## Conventions

### Getters

TODO: Should we have a recommendation for whether to say `get-` or not? Or
maybe even build a concept of getters into wit itself?

## Temporary workarounds

The component model specification and implementations are still in development,
so at this time some features or planned features in the component model are
not ready for use in WASI APIs. Here's a list of those features and what to use
for now in their place.

### Resources

Resources are expected to be available in time for Preview2, but at this time
still in development.

As a temporary workaround, WASI proposals are using `u32` types, which
represent indices into an implied global table of handles. Since it is
implied and global, this table doesn't provide any isolation between
components; it intended to be a temporary workaround to support prototyping.

In place of a resource like this:

```wit
/// An example resource.
///
/// A description of the example resource.
resource resource-name {
/// An example function.
///
/// A description of the example function.
function-name: func()
}
```

Define a `u32` type alias, an explicit `drop` function, and change all
functions inside the resource to have an explicit `this` argument, like this:

```wit
/// An example resource.
///
/// A description of the example resource.
///
/// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources).
type resource-name = 32
/// An example function.
///
/// A description of the example function.
function-name: func(this: resource-name)
/// Dispose of the specified `resource-name`, after which it may no longer
/// be used.
drop-resource-name: func(this: resource-name)
```

### Streams

Streams are expected to be available in the Preview 3 timeframe, as part of the
[Component Model async proposal].

As a temporary workaround for use cases that need byte streams, [use] the
`input-stream` and `output-stream` types defined in [wasi-io].

```wit
use io.streams.{input-stream, output-stream}
```

For use cases that need typed streams, another option is to define a [resource]
with a function returning `option<T>` or `result<option<T>, E>` for returning
the elements with `none` indicating the end of the stream.

This resource-based workaround can be used for asynchronous I/O by using
[wasi-poll] to poll for multiple streams, however it doesn't support
composing asynchronous work across multiple components, and it has some scaling
limitations. These limitations will be fixed when built in `stream` types are
available.

[Component Model async proposal]: https://docs.google.com/presentation/d/1MNVOZ8hdofO3tI0szg_i-Yoy0N2QPU2C--LzVuoGSlE/edit#slide=id.g1270ef7d5b6_0_662
[use]: #Dependencies
[wasi-io]: https://github.com/WebAssembly/wasi-io
[wasi-poll]: https://github.com/WebAssembly/wasi-poll
[resource]: #Resources

### Value Imports

As a temporary workaround for the lack of value imports, link-time authority
functions may be used.

In place of a value import like this:

```wit
/// An example value import.
///
/// A description of the value import.
values: list<i32>
```

Define an `instance` function, like this:

```
/// An example value import.
///
/// A description of the value import.
///
/// This [represents a value import](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Value_Imports).
instance-values: func() -> list<u32>
```

If the value type contains any handles, for now specify that calling the
function more than once creates new handles each time.

It is often desirable to put these functions in their own interface, so that
worlds may chose to include or exclude them independently of the rest of the
APIs they're associated with.

### Star Imports

TODO: Are there specific patterns we should recommend for working around star imports?

And add this comment:

```wit
/// This [represents a star import](https://github.com/WebAssembly/WASI/blob/main/WasiWitdocs/WitInWasi.md#Star_Imports).
```

To avoid trouble when migrating to star imports in the future, also avoid
depending on dynamic keys.

### Dependencies

To use types from one package in another, use a `use` declaration:

```wit
use io.streams.{input-stream, output-stream}
```

For now, the tooling requires the wit files defining types to be colocated with
the wit files using them. The convention for now is to have a "deps" directory
underneath the top-level "wit" directory containing copies of any needed wit
files.

In the future, wit is expected to support an identifier syntax for naming
types in other packages.

0 comments on commit ddfe3d1

Please sign in to comment.