@@ -443,26 +443,8 @@ by an `<import-arg>` with a matching `<name>`. Validation also requires all
443443described above, superfluous ` <name> ` s are valid.
444444
445445In 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
467449In general, the arguments of ` instantiate ` can refer to any preceding type,
468450import, 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:
519501Unlike most source-language nested functions/classes, nested modules have no
520502special access to their parents' state. However, since modules and types are
521503closed, 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
561578In the future, nested modules may be independently useful for [ feature testing]
562579or 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
610627module * definitions* as a convenient way to define a module's exports to be
611628that 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