|
| 1 | +# Capabilities in WASI |
| 2 | + |
| 3 | +What is a capability? |
| 4 | + |
| 5 | +The Wasm language has no syscall instructions or builtin I/O facilities. |
| 6 | +To let interact with the outside world, Wasm programs can be provided |
| 7 | +with *capabilities*. |
| 8 | + |
| 9 | +There are two main kinds of capabilities in WASI, link-time capabilities |
| 10 | +and runtime capabilities. |
| 11 | + |
| 12 | +## Link-time capabilities |
| 13 | + |
| 14 | +In short, link-time capabilities are functions that you can import that |
| 15 | +do things. |
| 16 | + |
| 17 | +They're called link-time capabilities, because the exports that satisfy the |
| 18 | +imports are chosen at link time. And if someone wants to virtualize those |
| 19 | +capabilities, or attenuate them to provide a restricted functionality, they |
| 20 | +may use a component that provides the needed exports and link them in |
| 21 | +instead, also at link time. |
| 22 | + |
| 23 | +Strictly speaking, link-time capabilities in the Wasm component model are |
| 24 | +*instance imports*. These imports request an already-instantiated instance. |
| 25 | +Being already instantiated, the instance already has some capabilities of |
| 26 | +its own that were granted to it at its own link time. |
| 27 | + |
| 28 | +Link-time capabilities may also be called *instantiation-time* capabilties, |
| 29 | +because the linking we're talking about here is the linking that happens |
| 30 | +as part of instantiation. |
| 31 | + |
| 32 | +When these imports are satisfied by the host, the host doesn't need to |
| 33 | +literally create a new Wasm instance, but from the perspective of the guest |
| 34 | +it behaves the same way. |
| 35 | + |
| 36 | +## Runtime capabilities |
| 37 | + |
| 38 | +In short, runtime capabilities are [handles] that you can pass around that |
| 39 | +grant access to resources. |
| 40 | + |
| 41 | +Handles are first-class, so they can flow anywhere at runtime, and they're |
| 42 | +unforgeable, so they can be used to pass around access to individual |
| 43 | +resources without exposing other resources. |
| 44 | + |
| 45 | +In programming languages that can't directly manipulate unforgeable references, |
| 46 | +handles may be exposed to applications in the form of `i32` indices into |
| 47 | +per-component-instance tables, that conceptually hold the real handles, and |
| 48 | +the bindings take care of the bookkeeping when handles are passed from one |
| 49 | +instance to another. |
| 50 | + |
| 51 | +## How should one decide when to use link-time vs. runtime capabilities? |
| 52 | + |
| 53 | +If you have use cases that need multiple distinct resources live at the |
| 54 | +same time, and the ability to dynamically distinguish between them, you'll |
| 55 | +need runtime capabilities. For example, it's common for programs using |
| 56 | +filesystem to have multiple files open at once, so files need to be |
| 57 | +exposed as handles. |
| 58 | + |
| 59 | +If you have an API where most use cases will only ever have one resource |
| 60 | +that gets used, such as a clock API with a "get the time" function where |
| 61 | +most users will just have one instance of the clock, link-time capabilities |
| 62 | +can be more convenient to use. |
| 63 | + |
| 64 | +There may eventually be situations where an API has been designed to use |
| 65 | +link-time capabilities, and someone needs to use it with runtime capabilities. |
| 66 | +In our clock API example, if someone does wish to have multiple distinct |
| 67 | +clocks at runtime, they'll want handles. In the future, the component model |
| 68 | +will hopefully help out here, by adding features to allow component instances |
| 69 | +to be usable as handles, which would allow link-time capabilities to be |
| 70 | +used as runtime capabilities. |
| 71 | + |
| 72 | +[*handles*]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#handle-types |
0 commit comments