-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Document proposed
WIT
to enable component Worlds
This PR sketches out the initial format for WebAssembly profiles, i.e. world files. Signed-off-by: Brian H <[email protected]>
- Loading branch information
1 parent
ca2851c
commit dfb3113
Showing
1 changed file
with
125 additions
and
0 deletions.
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 |
---|---|---|
@@ -0,0 +1,125 @@ | ||
# WIT + `world` | ||
|
||
As it exists today [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md) is a format for describing the interface of a singular [instance](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#instance-definitions). Toolchains like [wit-bindgen](https://github.com/bytecodealliance/wit-bindgen) consume `*.wit` files as *imports* or *exports* to generate *guest* or *host* components implying **4** ways to consume an interface: | ||
|
||
| {guest,host}⋅{export, import} | export | import | | ||
| -------- | -------- | -------- | | ||
| **guest** | _guest export_ | _guest import_ | | ||
| **host** | _host export_ | _host import_ | | ||
|
||
Furthermore, a single component may refer to 0..N interfaces in its imports and exports. | ||
|
||
The `world` syntax described below allows collecting *N* _imports_ and *N* _exports_ into a single definition reducing this number of perspectives to **2**: | ||
1. As a *guest* **targeting** the `world` | ||
|
||
From the perspective of a guest the *imports* declared in a `world` describe the **maximum** set of imports that the component may `import`, whereas the *exports* describe the **minimum** set of imports that the component must `export`. | ||
|
||
2. A a *host* **supporting** the `world` | ||
|
||
From the perspective of a host, the *imports* declared in a `world` describe the **minimum** set of functions that must be supported by the host and supplied as imports to components running on that host, whereas the exports declared describe the **maximum** set of functions that the host may call in response to host events. | ||
|
||
Thus, there are inherently two opposing perspectives on each `world`: the **host** and **guest**. | ||
|
||
> NOTE: As a developer, assuming the *guest* or *host* perspective is inherent in whether we are embedding a WASM runtime or compiling to WASM. so a world effectively gives us 1 thing to say, and it implies all the rest, i.e. (imports and exports). | ||
> | ||
> Because the [Component Model](https://github.com/WebAssembly/component-model) allows one component to [instantiate]() and link other components, components can technically take either the host or guest perspective for a given `world` (although it will be far more common for components to take the guest perspective). Native host runtimes traditionally only take the host perspective, but in theory a native runtime could implement a component that is imported and instantiated by a wasm component, with the native runtime thereby taking the guest perspective. | ||
In the examples shown below, because *import* and *export* in the syntax go in the same direction as they are defined in a guest component, we can say that a `world` is **written** from the *guest* perspective. | ||
|
||
|
||
--- | ||
|
||
The lexical structure of the following syntax is identical to that of [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#lexical-structure) with the following additions: | ||
|
||
- keywords ```world import export``` | ||
- a new token `quoted-string` | ||
|
||
## `world` | ||
A `world` declaration defines a set of imports and exports. From a component-model POV a `world` is syntax for a [componenttype](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#type-definitions), e.g.: | ||
|
||
``` | ||
// wasi:http/proxy | ||
world proxy { | ||
import frontend: "wasi:http/handler" | ||
export backend: "wasi:http/handler" | ||
} | ||
``` | ||
|
||
By way of metaphor, a `world` is like a function type: | ||
* `world` imports and exports are like parameters and results | ||
* `world` hosts are like the callers of a given function type | ||
* `world` guests are like functions that have a given function type | ||
* The rules for when a given guest is compatible with a given host are like traditional function subtyping | ||
|
||
> Given any component `.wasm`, one should be able to derive a `WIT` file containing a `world` that represents the syntax for that `.wasm`'s component type. | ||
|
||
Conceretely, the structure of a `world` declaration is: | ||
|
||
``` | ||
world-item ::= 'world' id '{' world-items* '}' . | ||
world-items ::= import-item | export-item . | ||
``` | ||
|
||
### `import` | ||
|
||
An `import` declaration states that a component type depends on an externally provided [function](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#item-func), [value](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#types), instance of an interface type, or component type. | ||
|
||
For example, consider the following `import` declarations: | ||
|
||
``` | ||
world { | ||
// Import instance of "wasi:filesystem" interface and give it name "fs" | ||
import fs: "wasi:filesystem" | ||
// Import function with functype and give it name "some-func" | ||
import some-func: func(arg: string) -> result<_, _> | ||
// Import the inlined interface and give it name "foobar" | ||
import foobar: interface { | ||
foo: func() | ||
bar: func() | ||
} | ||
} | ||
// ... | ||
``` | ||
|
||
Concretely, the structure of an `import` declaration is: | ||
|
||
``` | ||
import-item ::= 'import' id ':' import-type . | ||
import-type ::= id | extern-type . | ||
extern-type ::= wit-url | func-type | value-type | instance-type | component-type . | ||
instance-type ::= 'interface' '{' interface-items* '}' . | ||
component-type ::= 'world' '{' world-items* '}' . | ||
``` | ||
|
||
> NOTE: `wit-url` is lexically a `quoted-string` describing a [URL](https://url.spec.whatwg.org/) resolving to a `*.wit` document. | ||
### `export` | ||
|
||
An `export` declaration states that a component type can provide a instance of a [function](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#item-func), [value](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#types), instance of an interface type, or component type. | ||
|
||
For example: | ||
|
||
``` | ||
world { | ||
// Export an instance of the "wasi:http/handler" interface. | ||
export frontend: "wasi:http/handler" | ||
} | ||
// ... | ||
``` | ||
|
||
Concretely, the structure of an `export` statement is: | ||
|
||
``` | ||
export-item ::= `export` id `:` export-type . | ||
export-type ::= id | extern-type . | ||
``` | ||
|
||
> NOTE: `extern-type` as specified in `import`. |