|
1 | 1 | # Why the Component Model? |
2 | 2 |
|
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, 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 [WebAssembly Core Specification](https://webassembly.github.io/spec/core/), and if you compile a program written in Rust, C, Go or whatever to WebAssembly, then a core module is what you'll get. |
| 3 | +WebAssembly programs can be written by hand, |
| 4 | +but it's more likely that you will use a compiler to generate your programs. |
| 5 | +In general, a compiler translates programs from a source language |
| 6 | +to a target language. |
| 7 | +Compilers whose target language is WebAssembly may take |
| 8 | +Rust, C, Go, or a variety of other languages as a source language. |
| 9 | +In this case, the compiler produces a WebAssembly _core module_. |
| 10 | +Core modules have some limitations, which components address. |
4 | 11 |
|
5 | | -Core modules are, however, limited in how they expose their functionality to the outside world to functions that take and return only a small number of core WebAssembly types (essentially only integers and floating-point numbers). Richer types, such as strings, lists, records (a.k.a. structs), etc. have to be represented in terms of integers and floating point numbers, for example by the use of pointers and offsets. Those representations are often times not interchangeable across languages. For example, a string in C might be represented entirely differently from a string in Rust or in JavaScript. |
| 12 | +## Core modules |
6 | 13 |
|
7 | | -For Wasm modules to interoperate, therefore, there needs to be an agreed-upon way for exposing those richer types across module boundaries. |
| 14 | +Typically, a core module defines a set of _functions_ |
| 15 | +along with auxiliary definitions |
| 16 | +that are necessary for executing those functions. |
| 17 | +Functions are made up of _instructions_. |
| 18 | +Auxiliary definitions include: |
| 19 | +* _Linear memories_ define untyped buffers that can be read from |
| 20 | + and written to by instructions. |
| 21 | +* _Imports_ define the names of other modules |
| 22 | + that are required to be available to execute |
| 23 | + the functions in the module, |
| 24 | + along with type signatures for required functions |
| 25 | + in the imported module. |
| 26 | +* _Exports_ define the names of functions within |
| 27 | + the module that should be accessible externally. |
| 28 | +* And others; see [the Core Specification](https://webassembly.github.io/spec/core/syntax/modules.html) |
| 29 | + for the complete list. |
8 | 30 |
|
9 | | -In the component model, these type definitions are written in a language called [WIT (Wasm Interface Type)](./wit.md), and the way they translate into bits and bytes is called the [Canonical ABI (Application Binary Interface)](./../advanced/canonical-abi.md). A Wasm [component](./components.md) is thus a wrapper around a core module that specifies its imports and exports using such [Interfaces](./interfaces.md). |
| 31 | +A core module usually corresponds to a single `.wasm` file. |
| 32 | +These modules can be run in the browser, |
| 33 | +or via a separate runtime such as [Wasmtime](https://wasmtime.dev/) |
| 34 | +or [WAMR](https://github.com/bytecodealliance/wasm-micro-runtime). |
10 | 35 |
|
11 | | -The agreement of an interface adds a new dimension to Wasm portability. Not only are components portable across architectures and operating systems, but they are now portable across languages. A Go component can communicate directly and safely with a C or Rust component. It need not even know which language another component was written in - it needs only the component interface, expressed in WIT. Additionally, components can be linked into larger graphs, with one component's exports satisfying another's imports. |
| 36 | +A module is defined by the [WebAssembly Core Specification](https://webassembly.github.io/spec/core/). |
12 | 37 |
|
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 component's behaviour - to enforce and guarantee properties just by looking at the surface of the component. The relationships within a graph of components can be analysed, for example to verify that a component containing business logic has no access to a component containing personally identifiable information. |
| 38 | +### Limitations of core modules |
14 | 39 |
|
15 | | -Moreover, a component interacts with a runtime or other components _only_ by calling its imports and having its exports called. Specifically, unlike core modules, a component may not export Wasm memory, and thus it cannot indirectly communicate to others by writing to its memory and having others read from that 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. |
| 40 | +Core modules are, however, limited in how they expose their functionality to the outside world. |
| 41 | +Core modules expose their functionality by exporting functions. |
| 42 | +These functions' argument and return types are restricted, essentially, |
| 43 | +to only integers and floating-point numbers. |
| 44 | +Compound types, such as strings, lists, arrays, records, or structs, |
| 45 | +have to be represented in terms of integers and floating-point numbers. |
| 46 | + |
| 47 | +Recall that a linear memory is an uninitialized region of bytes |
| 48 | +declared within a module. |
| 49 | +So, a string argument might be represented as two separate arguments: |
| 50 | +an integer offset into a memory, |
| 51 | +and an integer representing the length of the string. |
| 52 | +These representations are frequently specific to each programming language. |
| 53 | +For example, a string in C might be represented entirely differently |
| 54 | +from a string in Rust or in JavaScript. |
| 55 | +Moreover, to make this approach work, modules must import and export memories, |
| 56 | +which can be error-prone, as different languages |
| 57 | +make different assumptions about memory layout. |
| 58 | + |
| 59 | +For WebAssembly modules to interoperate, therefore, there needs to be an agreed-upon way |
| 60 | +to expose these richer types across module boundaries. |
| 61 | + |
| 62 | +## Components |
| 63 | + |
| 64 | +Components were developed to ease interoperability between modules. |
| 65 | +Conceptually, a component is a module that is restricted |
| 66 | +to interact only through its imported and exported functions. |
| 67 | +Compared to core modules, components also use a richer |
| 68 | +mechanism for expressing the types of functions. |
| 69 | + |
| 70 | +### Interfaces |
| 71 | + |
| 72 | +These interfaces are expressed in a separate language called [WIT (Wasm Interface Type)](./wit.md). |
| 73 | +Interfaces contain _types_. |
| 74 | +The bit-level representations of these types are specified by |
| 75 | +the [Canonical ABI (Application Binary Interface)](./../advanced/canonical-abi.md). |
| 76 | + |
| 77 | +### Interoperability |
| 78 | + |
| 79 | +Interfaces make it possible to write components that are |
| 80 | +portable across different architectures and operating systems. |
| 81 | +Not only that, components are portable across different programming languages. |
| 82 | +A component implemented in Go can communicate directly and safely |
| 83 | +with a C or Rust component. |
| 84 | +Writing a component doesn't even require knowledge |
| 85 | +of which language its dependent components are implemented in, |
| 86 | +only the component interface expressed in WIT. |
| 87 | +Additionally, components can be linked into larger graphs, |
| 88 | +with one component's exports satisfying another's imports. |
| 89 | + |
| 90 | +### Benefits of the component model |
| 91 | + |
| 92 | +Putting all of the pieces together: |
| 93 | +the component model is a way of writing WebAssembly modules |
| 94 | +that interact with each other only through exports and imports of functions |
| 95 | +whose types are expressed using WIT. |
| 96 | + |
| 97 | +When combined with Wasm's strong [sandboxing](https://webassembly.org/docs/security/), |
| 98 | +the component model has further benefits. |
| 99 | +Richer type signatures express richer semantic properties |
| 100 | +than type signatures made up only of integers and floats. |
| 101 | +Rich types make it possible to statically analyse |
| 102 | +and reason about a component's behaviour. |
| 103 | +Simply by examining the surface of the component—the types |
| 104 | +of its imports and exports—properties can be |
| 105 | +enforced and guaranteed. |
| 106 | +The relationships within a graph of components can be analysed: |
| 107 | +for example, to verify that a component containing business logic |
| 108 | +has no access to a component containing personally identifiable information. |
| 109 | + |
| 110 | +Moreover, a component interacts with a runtime or other components |
| 111 | +_only_ by calling its imports and having its exports called. |
| 112 | +Specifically, unlike core modules, a component may not export a memory |
| 113 | +and thus it cannot indirectly communicate to others |
| 114 | +by writing to its memory and having others read from that memory. |
| 115 | +This not only reinforces sandboxing, but enables interoperation |
| 116 | +between languages that make different assumptions about memory: |
| 117 | +for example, allowing a component that relies garbage-collected memory |
| 118 | +to interoperate with one that uses conventional linear memory. |
| 119 | + |
| 120 | +## Using components |
16 | 121 |
|
17 | 122 | Now that you have a better idea about how the component model can help you, take a look at [how to build components](../language-support.md) in your favorite language! |
18 | 123 |
|
| 124 | +## Further reading |
| 125 | + |
19 | 126 | > For more background on why the component model was created, take a look at the specification's [goals](https://github.com/WebAssembly/component-model/blob/main/design/high-level/Goals.md), [use cases](https://github.com/WebAssembly/component-model/blob/main/design/high-level/UseCases.md) and [design choices](https://github.com/WebAssembly/component-model/blob/main/design/high-level/Choices.md). |
0 commit comments