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

Commit 0bd68f7

Browse files
author
Luke Wagner
committed
Put module and instance types into their own index spaces (#21)
1 parent ff45ea4 commit 0bd68f7

File tree

2 files changed

+86
-57
lines changed

2 files changed

+86
-57
lines changed

proposals/module-linking/Binary.md

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,30 +35,41 @@ Updates to
3535
typesec ::= t*:section_1(vec(type))
3636
3737
type ::=
38-
0x60 ft:functype -> ft
39-
0x61 mt:moduletype -> mt
40-
0x62 it:instancetype -> it
38+
0x60 ft:functype -> ft
39+
0x61 mt:moduletype -> mt
40+
0x62 it:instancetype -> it
4141
42-
functype ::= rt_1:resulttype rt_2:resulttype -> rt_1 -> rt-2
42+
functype ::= rt_1:resulttype rt_2:resulttype -> rt_1 -> rt-2
43+
moduletype ::= mtd*:vec(moduletypedef) -> mtd*
44+
instancetype ::= itd*:vec(instancetypedef) -> itd*
4345
44-
moduletype ::=
45-
i*:vec(import) e*:vec(exporttype) -> {imports i*, exports e*}
46+
moduletypedef ::=
47+
itd -> itd
48+
0x02 i:import -> {import i}
4649
47-
instancetype ::= e*:vec(exporttype) -> {exports e*}
50+
instancetypedef ::=
51+
0x01 t:type -> {type t}
52+
0x07 et:exporttype -> {export et}
53+
0x0f a:alias -> {alias a}
4854
49-
exporttype ::= nm:name d:importdesc -> {name nm, desc d}
55+
exporttype ::= nm:name d:importdesc -> {name nm, desc d}
5056
```
5157

52-
referencing:
58+
Note: the numeric discriminants in `moduletypedef` are chosen to match the
59+
section numbers for the corresponding sections.
5360

61+
Referencing:
5462
* [`resulttype`](https://webassembly.github.io/spec/core/binary/types.html#binary-resulttype)
5563
* [`import`](https://webassembly.github.io/spec/core/binary/modules.html#binary-import)
5664
* [`importdesc`](https://webassembly.github.io/spec/core/binary/modules.html#binary-importdesc) -
5765
although note that this is updated below as well.
5866

5967
**Validation**
6068

61-
* each `importdesc` is valid according to import section
69+
* The `moduletypedef`s of a `moduletype` are validated in a fresh set of index
70+
spaces (currently, only the type index space is used). Thus, the function
71+
type of a function export must either be defined inside the `moduletype` or
72+
aliased. The same goes for `instancetypedef`s and `instancetype`s.
6273
* Types can only reference preceding type definitions. This forces everything to
6374
be a DAG and forbids cyclic types. TODO: with type imports we may need cyclic
6475
types, so this validation will likely change in some form.

proposals/module-linking/Explainer.md

Lines changed: 65 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -443,26 +443,8 @@ by an `<import-arg>` with a matching `<name>`. Validation also requires all
443443
described above, superfluous `<name>`s are valid.
444444

445445
In the future, new productions could be added to `<instance-init>` allowing
446-
alternatives to `instantiate` for creating instances, such as directly from
447-
fields without an intermediate module.
448-
449-
Instances can also be supplied as arguments to `instantiate`, allowing whole
450-
collections of fields to be passed as a single unit. For example, this module
451-
imports a `wasi_file` instance and passes it on to the child:
452-
```wasm
453-
(module $PARENT
454-
(type $WasiFile (instance
455-
(export "read" (func (param i32 i32 i32) (result i32)))
456-
(export "write" (func (param i32 i32 i32) (result i32)))
457-
...
458-
))
459-
(import "wasi_file" (instance $wasi-file (type $WasiFile)))
460-
(import "child" (module $CHILD
461-
(import "wasi_file" (instance (type outer $PARENT $WasiFile)))
462-
))
463-
(instance (instantiate $CHILD "wasi_file" (instance $wasi-file)))
464-
)
465-
```
446+
alternatives to `instantiate` for creating instances, such as direct tupling
447+
of individual definitions into an instance, without an intermediate module.
466448

467449
In general, the arguments of `instantiate` can refer to any preceding type,
468450
import, module, instance or alias definition. This includes all imports and
@@ -519,44 +501,79 @@ space as module imports and thus can be instantiated the same way. For example:
519501
Unlike most source-language nested functions/classes, nested modules have no
520502
special access to their parents' state. However, since modules and types are
521503
closed, stateless expressions which would otherwise be duplicated, sharing is
522-
allowed between children and parents via a new kind of `outer` alias:
504+
allowed between nested and outer modules via a new kind of "outer" alias. To
505+
prevent cross-module cycles, outer aliases in a nested module can only refer to
506+
definitions in outer modules that precede it (in text, binary and abstract syntax
507+
order).
508+
509+
As an example, when an instance import is passed from a parent module to its
510+
child module, the child can use an outer alias to avoid duplicating the
511+
instance type:
523512
```wasm
524513
(module $PARENT
525-
(type $WasiFile (instance $wasi-file
526-
(export "read" (func (param i32 i32 i32) (result i32)))
514+
(type $FileOps (instance
515+
... many function exports
527516
))
517+
(import "fileops" (instance $fileops (type $FileOps)))
528518
(module $CHILD
529-
(alias (type $WasiFile outer $PARENT $WasiFile))
530-
(import "wasi_file" (instance (type $WasiFile)))
519+
(alias (type $FOps outer $PARENT $FileOps))
520+
(import "fileops" (instance $fops (type $FOps)))
521+
...
531522
)
523+
(instance $child (instantiate $CHILD "fileops" (instance $fileops)))
524+
...
532525
)
533526
```
534-
Just like for instance-export aliases, a new form of inline sugar for outer
535-
aliases:
527+
The `outer` keyword in an `alias` definition indicates that the aliased
528+
definition is found by a pair of: the outer module and the desired definition
529+
within that outer module. This pair can be specified in the text format via
530+
two identifiers, as shown in this example. In the binary format, the pair is
531+
specified via [De Bruijn index]. Each module's identifier namespace is disjoint
532+
and thus it would be a parsing error in this example if `$CHILD` attempted to
533+
use `$FileOps` directly. Moreover, `$FOps` could be renamed to `$FileOps`
534+
without any shadowing taking place.
535+
536+
A new form of inline sugar is added for outer aliases, symmetric to the export
537+
alias sugar introduced above. For example, the above `$CHILD` module could have
538+
been equivalently written:
536539
```wasm
537-
(module $PARENT
538-
(type $WasiFile (instance $wasi-file
539-
(export "read" (func (param i32 i32 i32) (result i32)))
540-
))
541540
(module $CHILD
542-
(import "wasi_file" (instance (type outer $PARENT $WasiFile)))
541+
(import "fileops" (instance $fops (type outer $PARENT $FileOps)))
542+
...
543543
)
544-
)
545544
```
546-
Thus, the above two modules produce the same abstract syntax and binary
547-
representation.
545+
which would generate the same abstract syntax and binary representation.
548546

549-
Outer aliases in a nested module can only refer to definitions in outer modules
550-
that precede it. This is necessary to ensure that type and module definitions
551-
are not cyclic across module boundaries.
547+
One subtle related detail is that ([in preparation for type imports and
548+
exports][Issue-21]) module and instance *types* are like nested modules in that
549+
they create new, *empty* index- and name-spaces. For example, in the following
550+
example, outer aliases must be used in order to reuse the `$Libc` and
551+
`$FileOps` type definitions in the module type of `$IN_MEMORY_FS`:
552+
```wasm
553+
(module $PARENT
554+
(type $Libc (instance
555+
...
556+
))
557+
(type $FileOps (instance
558+
...
559+
))
560+
(import "in-memory-fs" (module $IN_MEMORY_FS
561+
(import "libc" (instance (type outer $PARENT $Libc)))
562+
(export "fileops" (instance (type outer $PARENT $FileOps)))
563+
))
564+
...
565+
)
566+
```
567+
These aliases are necessary since, within the scope of the type of
568+
`$IN_MEMORY_FS`, the type index space is initially empty.
552569

553-
In general, language-independent tools can easily merge multiple `.wasm` files
554-
in a dependency graph into one `.wasm` file by performing simple transformations
555-
that do not require relocations or other fixup-enabling metadata. The reverse
556-
transformation is also possible and producer-toolchain-independent: a nested
557-
module of a `.wasm` file can be split out into a new `.wasm` file by duplicating
558-
aliased definitions. Thus, nested modules can be a useful tool for packaging and
559-
bundling tools.
570+
In general, language-independent tools can merge multiple `.wasm` files in a
571+
dependency graph into one `.wasm` file by performing transformations that do
572+
not require relocations or any other metadata from the toolchain. The reverse
573+
transformation is also possible: the nested modules of a `.wasm` can be split
574+
out into their own `.wasm` files by duplicating outer-aliased definitions.
575+
Thus, bundling and packaging tools have a high degree of flexibility in
576+
determining the final deployment artifacts.
560577

561578
In the future, nested modules may be independently useful for [feature testing]
562579
or supplying first-class module references (via `ref.module $module-index`) to
@@ -610,10 +627,10 @@ which is allowed in module *types*, zero-level exports are also allowed in
610627
module *definitions* as a convenient way to define a module's exports to be
611628
that of a given instance.
612629

613-
For example, this (outer) module:
630+
For example, this module:
614631
```wasm
615632
(module
616-
(module $M (func (export "foo") ...))
633+
(module $M (func (export "foo")))
617634
(instance $i (instantiate $M))
618635
(export $i)
619636
)
@@ -822,6 +839,7 @@ transparently share library code as described in
822839
[ESM-integration]: https://github.com/WebAssembly/esm-integration
823840
[Function References]: https://github.com/WebAssembly/function-references
824841
[Feature Testing]: https://github.com/WebAssembly/conditional-sections/issues/22
842+
[Issue-21]: https://github.com/WebAssembly/module-linking/issues/21
825843

826844
[`dlopen`]: https://pubs.opengroup.org/onlinepubs/009695399/functions/dlopen.html
827845
[`dlsym`]: https://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html

0 commit comments

Comments
 (0)