You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: component-model/src/concepts.md
+5-3
Original file line number
Diff line number
Diff line change
@@ -19,19 +19,21 @@ The component model defines a **canonical ABI** - an ABI to which all components
19
19
20
20
A **world** is a higher-level contract that describes a component's capabilities and needs.
21
21
22
-
In one sense, a world _defines_ a component - it says what interfaces the component exposes for other code to call, and what interfaces the component depends on - but it defines only the surface of a component, not the internal behaviour. This is a useful way to think about "business logic" components, like libraries that export APIs for other components to use. Most of the worlds you define will be these kind of custom, library worlds.
22
+
In one sense, a world _defines_ a component - it says what interfaces the component exposes for other code to call, and what interfaces the component depends on - but it defines only the surface of a component, not the internal behaviour. This is a useful way to think about "business logic" components, like libraries that export APIs for other components to use. If you're an application or library developer, you'll define custom worlds to expose the functionality of each component you create - and to declare the functionality your component depends on.
23
23
24
-
In another sense, though, a world defines a _hosting environment_ for components. For example, WASI (the WebAssembly System Interface) defines a "command line" world which exports interfaces such as file I/O, random number generation, clocks and so on - the sort of APIs a piece of code running in a POSIX or Win32 environment might want to call. Worlds like this are more akin to operating systems or server frameworks; unless you're building a Wasm host, you'll mostly use the worlds these environments define for you. The 'world' concept unifies the "library" and "host" senses at a technical level, which enables some powerful techniques, but can also be daunting when first encountering the component model!
24
+
In another sense, though, a world defines a _hosting environment_ for components. For example, WASI (the WebAssembly System Interface) defines a "command line" world which exports interfaces such as file I/O, random number generation, clocks and so on - the sort of APIs a piece of code running in a POSIX or Win32 environment might want to call. Worlds like this are more akin to operating systems or server frameworks; unless you're building a Wasm host, you'll never define or implement one of these worlds, only _use_ the worlds these environments define for you. The 'world' concept unifies the "library" and "host" senses at a technical level, which enables some powerful techniques, but can also be daunting when first encountering the component model!
25
25
26
26
A world is composed of interfaces, but each interface is _directional_ - it indicates whether the interface is available for outside code to call, or outside code must fulfil the interface for the component to call. These interfaces strictly bounds the component. A component cannot interact with anything outside itself except by having its exports called, or by calling its imports. This provides very strong sandboxing: for example, if a component does not have an import for a secret store, then it _cannot_ access that secret store, even if the store is running in the same process.
27
27
28
28
For a component to run, its imports must be fulfilled, by a host or by other components. Connecting up one component's imports to another component's matching exports is called _composition_.
29
29
30
30
* A (trivial) "HTTP proxy" world would export a "receive HTTP requests" interface, and import a "send HTTP requests" interface. A host, or another component, would call the exported "receive" interface, passing an HTTP request; the component would forward it on via the imported "send" interface. To be a _useful_ proxy, the component would also need to import interfaces such as I/O and clock time - without those imports the component could not perform, for example, caching.
31
+
* The "WASI (WebAssembly System Interface) command line" world is a classic example of a "hosting environment" use of the world concept. This world exports APIs such as file I/O, sockets, random number generation, and other POSIX-style functionality, so that application components that depend on this world - that is, command line applications - can use those familiar capabilities.
32
+
* A "regex parser" world would export a "parse regex" function, and would import nothing. This declares not only that the component implementing this world can parse regular expressions, but also that it calls no other APIs. A user of such a parser could know, without looking at the implementation, that is does not access the file system, or send the user's regexes to a network service.
31
33
32
34
## Components
33
35
34
-
Physically, a **component** is a specially formatted WebAssembly file. Internally, the component could include multiple traditional WebAssembly modules, and sub-components, composed via their imports and exports.
36
+
Physically, a **component** is a specially formatted WebAssembly file. Internally, the component could include multiple traditional ("core") WebAssembly modules, and sub-components, composed via their imports and exports.
35
37
36
38
The external interface of a component - its imports and exports - corresponds to a world. The component, however, defines behaviour and internal state.
If you've tried out WebAssembly, you'll be familiar with the concept of a _module_. Roughly speaking, a module corresponds to a single `.wasm` file, with functions, types, memory, imports and exports, and so on. These modules can run in the browser, or via a separate runtime such as Wasmtime or Wamr. A module is what you get by default when you compile a program written in Rust, C, Go or whatever to WebAssembly.
3
+
If you've tried out WebAssembly, you'll be familiar with the concept of a _module_. Roughly speaking, a module corresponds to a single `.wasm` file, with functions, types, memory, imports and exports, and so on. These "core" modules can run in the browser, or via a separate runtime such as Wasmtime or Wamr. A module is defined by the base Wasm specification, and if you compile a program written in Rust, C, Go or whatever for the browser, then a core module is what you'd get.
4
4
5
-
Modules are, however, limited to describing themselves in terms of core WebAssembly types - integers and floating-point numbers. Just as in native assembly code, richer types, such as strings or records (structs), have to be represented in terms of integers and floating point numbers, for example by the use of pointers and offsets. And just as in native code, those representations are not interchangeable. A string in C might be represented entirely differently from a string in Rust, or a string in JavaScript.
5
+
Core modules are, however, limited to describing themselves in terms of core WebAssembly types - integers and floating-point numbers. Just as in native assembly code, richer types, such as strings or records (structs), have to be represented in terms of integers and floating point numbers, for example by the use of pointers and offsets. And just as in native code, those representations are not interchangeable. A string in C might be represented entirely differently from a string in Rust, or a string in JavaScript.
6
6
7
7
For Wasm modules to interoperate, therefore, there needs to be an agreed-upon way of defining those richer types, and an agreed-upon way of expressing them at module boundaries.
8
8
@@ -12,4 +12,6 @@ Such an agreement adds a new dimension to Wasm portability. Not only are modules
12
12
13
13
Combined with Wasm's strong sandboxing, this opens the door to yet further benefits. By expressing higher-level semantics than integers and floats, it becomes possible to statically analyse and reason about a module's behaviour - to enforce and guarantee properties just by looking at the surface of the module. The relationships between a graph of modules can be analysed, for example to verify that a module containing business logic has no access to a module containing personally identifiable information.
14
14
15
-
This guide doesn't try to formally specify what a component _is_. Physically, components are Wasm modules, such as `.wasm` files, with a specific internal format. Logically, components are containers for modules - or other components - which express their interfaces and dependencies via WIT and the Canonical ABI. Conceptually, components are self-describing units of code.
15
+
Moreover, components interact _only_ through the Canonical ABI. Specifically, unlike core modules, components may not export Wasm memory. This not only reinforces sandboxing, but enables interoperation between languages that make different assumptions about memory - for example, allowing a component that relies on Wasm GC (garbage collected) memory to collaborate with one that uses conventional linear memory.
16
+
17
+
This guide doesn't try to formally specify what a component _is_. Physically, components are Wasm modules, such as `.wasm` files, with a specific internal format. Logically, components are containers for modules - or other components - which express their interfaces and dependencies via WIT and the Canonical ABI. Conceptually, components are self-describing units of code that interact only through interfaces instead of shared memory.
0 commit comments