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

Generalize Module Types to Module Linking #3

Merged
merged 33 commits into from
Jun 9, 2020
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6e8eb1f
First draft for feedback
Mar 30, 2020
d6649ad
Apply suggestions from code review
lukewagner Apr 27, 2020
9a5adc5
Fix libimg.wat code
May 1, 2020
81b0e06
Mention ref.memory, ref.table and ref.global
May 1, 2020
32e815d
Apply Ms2ger's suggestions
lukewagner May 1, 2020
52310ca
Address Ms2ger's feedback
May 1, 2020
a179a06
Address Ms2ger's second round of feedback
May 4, 2020
2c20546
Apply suggestions from Ms2ger
lukewagner May 4, 2020
06e287d
Tweak Module Imports intro
May 5, 2020
c7bcd1f
Reframe (exports) as 'zero-level (export)'
May 5, 2020
86bbfc5
Add missing typedef to Summary section
May 5, 2020
85a4cec
Nuance GC commentary
May 5, 2020
64b42fb
Reword wasm merging para
May 5, 2020
c91c611
Refine discussion of aliases
May 5, 2020
137c1b8
Remove all the first-class bits
May 7, 2020
9fd79ed
Switch from instance flattening to explicit aliases
May 8, 2020
cb5c5cb
Split Module Section into Module/ModuleCode Sections to mirror Functi…
May 8, 2020
c5ae920
Tweaks and fixes
May 8, 2020
76b6c66
Rename proposal back to Module Linking
May 11, 2020
4ad7309
Tweak wording of instance definition rule
May 11, 2020
5a893f0
Fix typo in instance type example
acfoltzer May 13, 2020
07ad0a4
Merge pull request #5 from acfoltzer/patch-1
lukewagner May 13, 2020
33367d1
Imports and exports of ordered in the type, but subtyping is permissive
May 14, 2020
74bc689
Tweak wording
May 17, 2020
73950e7
Put aliases into their own section and allow flexible section interle…
May 18, 2020
3469268
Include igrep's fix
lukewagner May 19, 2020
7876a71
Syntactically distinguish parent vs instance aliases
May 19, 2020
40e3f9c
Add zero-level exports
May 19, 2020
73f9952
Update the Summary to reflect recent changes
May 19, 2020
f607aae
Add subtype relation between single-level instance and two-level fiel…
May 19, 2020
9565517
Recast multi-level imports as single-level instance imports
May 27, 2020
ff434ea
Address Sam's feedback
May 27, 2020
6b30a85
Add note about the linear memory stack pointer to the example
May 27, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions proposals/module-types/Example-LinkTimeVirtualization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Link-Time Virtualization Example

This document walks through the
[Link-time Virtualization](Explainer.md#link-time-virtualization)
use case.

We start with a child module that has been written and compiled separately,
without regard to the parent module. It imports `wasi_file` to do file I/O:

```wasm
;; child.wat
(module
(type $WasiFile (instance
(export "read" (func $read (param i32 i32 i32) (result i32)))
(export "write" (func $write (param i32 i32 i32) (result i32)))
))
(import "wasi_file" (instance $wasi-file (type $WasiFile)))
(func $play (export "play")
...
call $wasi-file.$read
...
)
)
```

We want to write a `parent` module that reuses `child`, but we don't want to
give it real file operations, but rather some file operations we virtualized.
For example, maybe we want an adapter that automatically compresses on write
and decompresses on read. This adapter module can be factored out and reused
as a separate module that imports a "real" `wasi_file` instance and uses it
to implement a new virtualized `wasi_file` instance:

```wasm
;; virtualize.wat
(module
(import "wasi_file" (instance $wasi-file (type $WasiFile)))

(func (export "read") (param i32 i32 i32) (result i32)
... impl
)
(func (export "write") (param i32 i32 i32) (result i32)
... impl
)
)
```

We can now write the parent module by composing `virtualize.wasm` and
`child.wasm` appropriately:

```wasm
;; parent.wat
(module
(type $WasiFile (instance
(export "read" (func $read (param i32 i32 i32) (result i32)))
(export "write" (func $write (param i32 i32 i32) (result i32)))
))
(import "wasi_file" (instance $real-wasi (type $WasiFile)))

(import "./virtualize.wasm" (module $VIRTUALIZE
(import "wasi_file" (instance (type $WasiFile)))
(exports $WasiFile)
))
(import "./child.wasm" (module $CHILD
(import "wasi_file" (instance (type $WasiFile)))
(export "play" (func))
))

(instance $virt-wasi (instance.instantiate $VIRTUALIZE (ref.instance $real-file)))
(instance $child (instance.instantiate $CHILD (ref.instance $virt-wasi)))

(func (export "work")
...
call $child.$play
...
)
)
```

Here, we assume the host understands relative file paths, but we could also bundle
all 3 files into one compound `parent-bundle.wasm`:

```wasm
;; parent-bundled.wat
(module
(type $WasiFile ...same as above)
(import "wasi_file" ...same as above)

(module $VIRTUALIZE ... copied inline)
(module $CHILD ... copied inline)

(instance $virt-wasi ...same as above)
(instance $child ...same as above)

(func (export "work") ...same as above)
)
```

In general, a tool can trivially transform between nested modules and module
imports without any understanding of their contents which allows bundling tools
to optimize for the deployment target. For example, on the Web, the choice to
import vs. nest modules can be based on the usual bundling considerations of
caching, reuse and minimizing fetches.
Loading