@@ -5,96 +5,89 @@ This document walks through the
5
5
use case.
6
6
7
7
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:
10
9
``` 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)))
16
13
(func $play (export "play")
17
14
...
18
- call (func $wasi-file "read")
19
- ...
20
15
)
21
16
)
22
17
```
23
18
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:
31
24
``` 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)))
38
28
39
29
(func (export "read") (param i32 i32 i32) (result i32)
40
- ... impl
30
+ ...
41
31
)
42
32
(func (export "write") (param i32 i32 i32) (result i32)
43
- ... impl
33
+ ...
44
34
)
45
35
)
46
36
```
47
37
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 ` :
50
40
``` wasm
51
- (module $PARENT
52
- (type $WasiFile (instance
41
+ (adapter module $Parent
42
+ (type $FSInstance (instance
53
43
(export "read" (func (param i32 i32 i32) (result i32)))
54
44
(export "write" (func (param i32 i32 i32) (result i32)))
55
45
))
56
- (import "wasi_file " (instance $real-wasi (type $WasiFile )))
46
+ (import "wasi:filesystem " (instance $real-fs (type $FSInstance )))
57
47
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 ))
61
51
))
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 )))
64
54
(export "play" (func))
65
55
))
66
56
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))))
75
59
)
76
60
```
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 ) :
81
76
``` 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)
88
80
89
- (instance $virt-wasi ...same as above )
90
- (instance $child ...same as above )
81
+ (module $VirtualizeFS ... copied inline )
82
+ (module $Child ... copied inline )
91
83
92
- (func (export "work") ...same as above)
84
+ (instance $virt-fs ... same as above)
85
+ (instance $child ... same as above)
93
86
)
94
87
```
95
88
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
99
92
import vs. nest modules can be based on the usual bundling considerations of
100
93
caching, reuse and minimizing fetches.
0 commit comments