Skip to content
This repository was archived by the owner on Aug 17, 2022. It is now read-only.

Commit 09c0da2

Browse files
authored
Merge pull request #35 from WebAssembly/component-rebase
Reframe Module Linking as the first proposal of the Component Model
2 parents 99f2c5a + fb37f40 commit 09c0da2

8 files changed

+1115
-1184
lines changed

README.md

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,17 @@
1-
# Component Model design and specification
1+
# Module Linking proposal
22

3-
This repository contains documents describing the high-level [goals],
4-
[use cases], [design choices] and [FAQ] of the component model.
3+
This repository contains the Module Linking proposal, which is the
4+
first proposal of the [Component Model].
55

6-
In the future, as proposals get merged, the repository will additionally
7-
contain the spec, a reference interpreter, a test suite, and directories for
8-
each proposal with the proposal's explainer and specific design documents.
9-
10-
## Design Process & Contributing
11-
12-
At this early stage, this repository only contains high-level design documents
13-
and discussions about the Component Model in general. Detailed explainers,
14-
specifications and discussions are broken into the following two repositories
15-
which, together, will form the "MVP" of the Component Model:
16-
17-
* The [module-linking] proposal will initialize the Component Model
18-
specification, adding the ability for WebAssembly to import, nest,
19-
instantiate and link multiple Core WebAssembly modules without host-specific
20-
support.
21-
22-
* The [interface-types] proposal will extend the Component Model specification
23-
with a new set of high-level types for defining shared-nothing,
24-
language-neutral "components".
6+
Links:
7+
* the general [explainer](design/proposals/module-linking/Explainer.md) for this proposal
8+
* a sketch of the [binary format](design/proposals/module-linking/Binary.md)
9+
* a description of [module subtyping](design/proposals/module-linking/Subtyping.md)
2510

2611
All Component Model work is done as part of the [W3C WebAssembly Community Group].
2712
To contribute to any of these repositories, see the Community Group's
2813
[Contributing Guidelines].
2914

30-
31-
[goals]: design/high-level/Goals.md
32-
[use cases]: design/high-level/UseCases.md
33-
[design choices]: design/high-level/Choices.md
34-
[FAQ]: design/high-level/FAQ.md
35-
[module-linking]: https://github.com/webassembly/module-linking/
36-
[interface-types]: https://github.com/webassembly/interface-types/
15+
[Component Model]: https://github.com/webassembly/component-model/
3716
[W3C WebAssembly Community Group]: https://www.w3.org/community/webassembly/
3817
[Contributing Guidelines]: https://webassembly.org/community/contributing/

design/proposals/module-linking/Binary.md

Lines changed: 147 additions & 170 deletions
Large diffs are not rendered by default.

design/proposals/module-linking/Example-LinkTimeVirtualization.md

Lines changed: 51 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5,96 +5,89 @@ This document walks through the
55
use case.
66

77
We start with a child module that has been written and compiled separately,
8-
without regard to the parent module. It imports `wasi_file` to do file I/O:
9-
8+
without regard to the parent module. It imports `wasi:filesystem` to do file I/O:
109
```wasm
11-
(module $CHILD
12-
(import "wasi_file" (instance $wasi-file
13-
(export "read" (func (param i32 i32 i32) (result i32)))
14-
(export "write" (func (param i32 i32 i32) (result i32)))
15-
))
10+
(module $Child
11+
(import "wasi:filesystem" "read" (func (param i32 i32 i32) (result i32)))
12+
(import "wasi:filesystem" "write" (func (param i32 i32 i32) (result i32)))
1613
(func $play (export "play")
1714
...
18-
call (func $wasi-file "read")
19-
...
2015
)
2116
)
2217
```
2318

24-
We want to write a `parent` module that reuses `child`, but we don't want to
25-
give it real file operations, but rather some file operations we virtualized.
26-
For example, maybe we want an adapter that automatically compresses on write
27-
and decompresses on read. This adapter module can be factored out and reused
28-
as a separate module that imports a "real" `wasi_file` instance and uses it
29-
to implement a new virtualized `wasi_file` instance:
30-
19+
We want to write a parent module that reuses the child module, but we don't
20+
want to give it real file operations, but rather some virtual filesystem.
21+
This virtual filesystem can be factored out and reused as a separate module
22+
that imports the "real" `wasi:filesystem` and exports a virtualized
23+
implementation of all the `wasi:filesystem` operations:
3124
```wasm
32-
(module $VIRTUALIZE
33-
(type $WasiFile (instance
34-
(export "read" (func (param i32 i32 i32) (result i32)))
35-
(export "write" (func (param i32 i32 i32) (result i32)))
36-
))
37-
(import "wasi_file" (instance $wasi-file (type $WasiFile)))
25+
(module $VirtualFS
26+
(import "wasi:filesystem" "read" (func (param i32 i32 i32) (result i32)))
27+
(import "wasi:filesystem" "write" (func (param i32 i32 i32) (result i32)))
3828
3929
(func (export "read") (param i32 i32 i32) (result i32)
40-
... impl
30+
...
4131
)
4232
(func (export "write") (param i32 i32 i32) (result i32)
43-
... impl
33+
...
4434
)
4535
)
4636
```
4737

48-
We can now write the parent module by composing `$VIRTUALIZE` and `$CHILD`:
49-
38+
We can now write the parent module as an adapter module that composes `$Child`
39+
and `$VirtualFS`:
5040
```wasm
51-
(module $PARENT
52-
(type $WasiFile (instance
41+
(adapter module $Parent
42+
(type $FSInstance (instance
5343
(export "read" (func (param i32 i32 i32) (result i32)))
5444
(export "write" (func (param i32 i32 i32) (result i32)))
5545
))
56-
(import "wasi_file" (instance $real-wasi (type $WasiFile)))
46+
(import "wasi:filesystem" (instance $real-fs (type $FSInstance)))
5747
58-
(import "virtualize" (module $VIRTUALIZE
59-
(import "wasi_file" (instance (type outer $PARENT $WasiFile)))
60-
(export (type outer $PARENT $WasiFile))
48+
(import "./virtualize.wasm" (module $VirtualFS
49+
(import "wasi:filesystem" (instance (type $FSInstance)))
50+
(export (type $FSInstance))
6151
))
62-
(import "child" (module $CHILD
63-
(import "wasi_file" (instance (type outer $PARENT $WasiFile)))
52+
(import "./child.wasm" (module $Child
53+
(import "wasi:filesystem" (instance (type $FSInstance)))
6454
(export "play" (func))
6555
))
6656
67-
(instance $virt-wasi (instantiate $VIRTUALIZE (import "wasi_file" (instance $real-wasi))))
68-
(instance $child (instantiate $CHILD (import "wasi_file" (instance $virt-wasi))))
69-
70-
(func (export "work")
71-
...
72-
call (func $child "play")
73-
...
74-
)
57+
(instance $virt-fs (instantiate $VirtualFS (import "wasi:filesystem" (instance $real-fs))))
58+
(instance $child (instantiate $Child (import "wasi:filesystem" (instance $virt-fs))))
7559
)
7660
```
77-
78-
Here, we assume the host understands relative file paths, but we could also bundle
79-
all 3 files into one compound `$PARENT-BUNDLE` module:
80-
61+
This example demonstrates several features of the Module Linking proposal:
62+
* The first line of the module is a [type definition](Explainer.md#type-definitions),
63+
factoring out an instance type so it can be reused four times below.
64+
* The next line is an [import definition](Explainer.md#import-definitions),
65+
importing an instance of `wasi:filesystem`. This instance import is logically
66+
equivalent to two two-level imports in a core module with `wasi:filesystem` as the
67+
"module" name and `read`/`write` as the "field" name.
68+
* The following two imports import *modules*, which is the other new importable
69+
type (after instances).
70+
* The final two lines are [instance definitions](Explainer.md#instance-definitions),
71+
instantiating and wiring up the `VirtualizeFS` and `Child` modules.
72+
73+
Here, we assume that the host understands relative file paths. To remove this host
74+
assumption, a tool could replace the imports definitions in `$Parent` with
75+
[module definitions](Explainer.md#module-definitions):
8176
```wasm
82-
(module $PARENT-BUNDLE
83-
(type $WasiFile ...same as above)
84-
(import "wasi_file" ...same as above)
85-
86-
(module $VIRTUALIZE ... copied inline)
87-
(module $CHILD ... copied inline)
77+
(adapter module $Parent
78+
(type $FSInstance ... same as above)
79+
(import "wasi:filesystem" ... same as above)
8880
89-
(instance $virt-wasi ...same as above)
90-
(instance $child ...same as above)
81+
(module $VirtualizeFS ... copied inline)
82+
(module $Child ... copied inline)
9183
92-
(func (export "work") ...same as above)
84+
(instance $virt-fs ... same as above)
85+
(instance $child ... same as above)
9386
)
9487
```
9588

96-
In general, a tool can trivially transform between nested modules and module
97-
imports without any understanding of their contents which allows bundling tools
98-
to optimize for the deployment target. For example, on the Web, the choice to
89+
In general, a tool can trivially go between nested modules and module imports
90+
without any understanding of their contents which allows bundling tools to
91+
optimize for the deployment target. For example, on the Web, the choice to
9992
import vs. nest modules can be based on the usual bundling considerations of
10093
caching, reuse and minimizing fetches.

0 commit comments

Comments
 (0)