@@ -14,7 +14,7 @@ JavaScript runtimes. For a more user-focussed explanation, take a look at the
1414 * [ Canonical definitions] ( #canonical-definitions )
1515 * [ Canonical ABI] ( #canonical-built-ins )
1616 * [ Canonical built-ins] ( #canonical-built-ins )
17- * [ Start definitions] ( #start-definitions )
17+ * [ Start definitions] ( #- start-definitions )
1818 * [ Import and export definitions] ( #import-and-export-definitions )
1919* [ Component invariants] ( #component-invariants )
2020* [ JavaScript embedding] ( #JavaScript-embedding )
@@ -23,6 +23,15 @@ JavaScript runtimes. For a more user-focussed explanation, take a look at the
2323* [ Examples] ( #examples )
2424* [ TODO] ( #TODO )
2525
26+ By default, the features described in this explainer (as well as the supporting
27+ [ Binary.md] ( Binary.md ) , [ WIT.md] ( WIT.md ) and [ CanonicalABI.md] ( CanonicalABI.md ) )
28+ have been implemented and are included in the [ WASI Preview 2] stability
29+ milestone. Features that are not part of Preview 2 are demarcated by one of the
30+ emoji symbols listed below; these emojis will be removed once they are
31+ implemented, considered stable and included in a future milestone:
32+ * 🪙: value imports/exports and component-level start function
33+ * 🪺: nested namespaces and packages in import/export names
34+
2635(Based on the previous [ scoping and layering] proposal to the WebAssembly CG,
2736this repo merges and supersedes the [ module-linking] and [ interface-types]
2837proposals, pushing some of their original features into the post-MVP [ future
@@ -63,7 +72,7 @@ definition ::= core-prefix(<core:module>)
6372 | <alias>
6473 | <type>
6574 | <canon>
66- | <start>
75+ | <start> 🪺
6776 | <import>
6877 | <export>
6978
@@ -197,7 +206,7 @@ instantiatearg ::= (with <string> <sortidx>)
197206sortidx ::= (<sort> <u32>)
198207sort ::= core <core:sort>
199208 | func
200- | value
209+ | value 🪙
201210 | type
202211 | component
203212 | instance
@@ -221,7 +230,7 @@ future include `data`). Thus, component-level `sort` injects the full set
221230of ` core:sort ` , so that they may be referenced (leaving it up to validation
222231rules to throw out the core sorts that aren't allowed in various contexts).
223232
224- The ` value ` sort refers to a value that is provided and consumed during
233+ 🪙 The ` value ` sort refers to a value that is provided and consumed during
225234instantiation. How this works is described in the
226235[ start definitions] ( #start-definitions ) section.
227236
@@ -489,7 +498,7 @@ defvaltype ::= bool
489498 | float32 | float64
490499 | char | string
491500 | (record (field <label> <valtype>)+)
492- | (variant (case <id>? <label> <valtype>? (refines <id>)? )+)
501+ | (variant (case <id>? <label> <valtype>?)+)
493502 | (list <valtype>)
494503 | (tuple <valtype>+)
495504 | (flags <label>+)
@@ -520,7 +529,7 @@ externdesc ::= (<sort> (type <u32>) )
520529 | <functype>
521530 | <componenttype>
522531 | <instancetype>
523- | (value <valtype>)
532+ | (value <valtype>) 🪙
524533 | (type <typebound>)
525534typebound ::= (eq <typeidx>)
526535 | (sub resource)
@@ -574,13 +583,6 @@ through these canonical definitions. The `typeidx` immediate of a handle type
574583must refer to a ` resource ` type (described below) that statically classifies
575584the particular kinds of resources the handle can point to.
576585
577- The [ subtyping] between all these types is described in a separate
578- [ subtyping explainer] ( Subtyping.md ) . Of note here, though: the optional
579- ` refines ` field in the ` case ` s of ` variant ` s is exclusively concerned with
580- subtyping. In particular, a ` variant ` subtype can contain a ` case ` not present
581- in the supertype if the subtype's ` case ` ` refines ` (directly or transitively)
582- some ` case ` in the supertype.
583-
584586The sets of values allowed for the remaining * specialized value types* are
585587defined by the following mapping:
586588```
@@ -649,7 +651,7 @@ references to out-of-line type definitions (via `(type <typeidx>)`) and inline
649651type expressions that the text format desugars into out-of-line type
650652definitions.
651653
652- The ` value ` case of ` externdesc ` describes a runtime value that is imported or
654+ 🪙 The ` value ` case of ` externdesc ` describes a runtime value that is imported or
653655exported at instantiation time as described in the
654656[ start definitions] ( #start-definitions ) section below.
655657
@@ -729,11 +731,7 @@ Like core modules, components have an up-front validation phase in which the
729731definitions of a component are checked for basic consistency. Type checking
730732is a central part of validation and, e.g., occurs when validating that the
731733` with ` arguments of an [ ` instantiate ` ] ( #instance-definitions ) expression are
732- type-compatible with the ` import ` s of the component being instantiated. To allow
733- backwards-compatible API evolution, "compatibility" is defined in terms of a
734- [ subtyping] relation, saying that ` t1 ` is "compatible" with ` t2 ` when a value
735- of type ` t1 ` is * substitutable* for a value of ` t2 ` without breaking any basic
736- assumptions the receiver has about ` t2 ` values.
734+ type-compatible with the ` import ` s of the component being instantiated.
737735
738736To incrementally describe how type-checking works, we'll start by asking how
739737* type equality* works for non-resource, non-handle, local type definitions and
@@ -766,28 +764,42 @@ all 5 variations of `$ListListStringX` are considered equal since, after
766764decoding, they all have the same AST.
767765
768766Next, the type equality relation on ASTs is relaxed to a more flexible
769- subtyping relation. This subtyping relation is recursively defined starting
770- with a set of base-case rules such as:
771- * ` u8 ` is a subtype of ` u16 `
772- * ` f32 ` is a subtype of ` f64 `
773-
774- and then a set of inductive rules like:
775- * If ` t1 ` is a subtype of ` t2 ` , ` list t1 ` is a subtype of ` list t2 `
776- * If ` t1 ` is a subtype of ` t2 ` , ` option t1 ` is a subtype of ` option t2 `
777-
778- The full list of rules is in [ ` Subtyping.md ` ] ( Subtyping.md ) . The rules are
779- defined so that a type-checking implementation can simply recurse on the ASTs
780- of two types in tandem to determine at each node whether the "left-hand side" is
781- a subtype of the "right-hand side". For example, the following component is
782- valid because, using the rules just given, the decoded AST of ` $L1 ` is a
783- subtype of the decoded AST of ` $L2 ` :
784- ``` wasm
767+ [ subtyping] relation. Currently, subtyping is only relaxed for ` instance ` and
768+ ` component ` types, but may be relaxed for more type constructors in the future
769+ to better support API Evolution (being careful to understand how subtyping
770+ manifests itself in the wide variety of source languages so that
771+ subtype-compatible updates don't inadvertantly break source-level clients).
772+
773+ Component and instance subtyping allows a subtype to export more and import
774+ less than is declared by the supertype, ignoring the exact order of imports and
775+ exports and considering only names. For example, here, ` $I1 ` is a subtype of
776+ ` $I2 ` :
777+ ``` wat
785778(component
786- (import "v1" (value $v1 (list (list u8))))
787- (component $C
788- (import "v2" (value $v2 (list (list u16))))
789- )
790- (instance $c (instantiate $C (with "v2" (value $v1))))
779+ (type $I1 (instance
780+ (export "foo" (func))
781+ (export "bar" (func))
782+ (export "baz" (func))
783+ ))
784+ (type $I2 (instance
785+ (export "bar" (func))
786+ (export "foo" (func))
787+ ))
788+ )
789+ ```
790+ and ` $C1 ` is a subtype of ` $C2 ` :
791+ ``` wat
792+ (component
793+ (type $C1 (component
794+ (import "a" (func))
795+ (export "x" (func))
796+ (export "y" (func))
797+ ))
798+ (type $C2 (component
799+ (import "a" (func))
800+ (import "b" (func))
801+ (export "x" (func))
802+ ))
791803)
792804```
793805
@@ -1239,7 +1251,7 @@ See the [CanonicalABI.md](CanonicalABI.md#canonical-definitions) for detailed
12391251definitions of each of these built-ins and their interactions.
12401252
12411253
1242- ### Start Definitions
1254+ ### 🪙 Start Definitions
12431255
12441256Like modules, components can have start functions that are called during
12451257instantiation. Unlike modules, components can call start functions at multiple
@@ -1306,19 +1318,22 @@ exported). The grammar for imports and exports is:
13061318import ::= (import <importname> bind-id(<externdesc>))
13071319export ::= (export <id>? <exportname> <sortidx> <externdesc>?)
13081320exportname ::= <name>
1309- | (interface "<regid>")
1321+ | (interface "<iid>")
1322+ iid ::= <namespace><label><projection><version>?
1323+ | <namespace>+<label><projection>+<version>? 🪺
1324+ namespace ::= <label>:
1325+ projection ::= /<label>
1326+ version ::= @<valid semver>
13101327importname ::= <exportname>
13111328 | <name> (url <string> <integrity>?)
13121329 | <name> (relative-url <string> <integrity>?)
13131330 | <name> <integrity>
1314- | (locked-dep "<regid>" <integrity>?)
1315- | (unlocked-dep "<regidset>")
1316- regname ::= <namespace>+<label><projection>*
1317- namespace ::= <label>:
1318- projection ::= /<label>
1319- regid ::= <regname><version>?
1320- regidset ::= <regname><verrange>?
1321- version ::= @<valid semver>
1331+ | (locked-dep "<pkgid>" <integrity>?)
1332+ | (unlocked-dep "<pkgidset>")
1333+ pkgname ::= <namespace><label>
1334+ | <namespace>+<label><projection>* 🪺
1335+ pkgid ::= <pkgname><version>?
1336+ pkgidset ::= <pkgname><verrange>?
13221337verrange ::= <version>
13231338 | @*
13241339 | @{<verlower>}
@@ -1385,11 +1400,12 @@ host must locate the contents using the hash (e.g., using an [OCI Registry]).
13851400
13861401The "registry" referred to by dependency names serves to map a hierarchical
13871402name and version to either a component or an export of a component. For
1388- example, in the registry name ` a:b:c/d/e/f ` , ` a:b:c ` traverses a path
1389- through namespaces ` a ` and ` b ` to a component ` c ` and ` /d/e/f ` traverses the
1390- exports of ` c ` (where ` d ` and ` e ` must be component exports but ` f ` can be
1391- anything). Given this abstract definition, a number of concrete data sources
1392- can be interpreted by developer tooling as "registries":
1403+ example, in the full generality of nested namespaces and packages (🪺),
1404+ in a registry name ` a:b:c/d/e/f ` , ` a:b:c ` traverses a path through namespaces
1405+ ` a ` and ` b ` to a component ` c ` and ` /d/e/f ` traverses the exports of ` c ` (where
1406+ ` d ` and ` e ` must be component exports but ` f ` can be anything). Given this
1407+ abstract definition, a number of concrete data sources can be interpreted by
1408+ developer tooling as "registries":
13931409* a live registry (perhaps accessed via [ ` warg ` ] )
13941410* a local filesystem directory (perhaps containing vendored dependencies)
13951411* a fixed set of host-provided functionality (see also the [ built-in modules] proposal)
@@ -1415,8 +1431,8 @@ sequence of labels in a registry name can be translated to nested scopes in the
14151431source language, thereby leveraging existing namespacing in the registry to
14161432avoid conflicts in the source bindings. Note that, because of the mandatory ` : `
14171433in registry names, the set of kebab names and registry names is disjoint and so
1418- no discriminant is required to distinguish between a ` name ` and ` regname ` ; a
1419- plain ` string ` covers both cases.
1434+ no discriminant is required to distinguish between a ` name ` , ` iid ` or ` pkgid ` ;
1435+ a plain ` string ` covers both cases.
14201436
14211437Components provide two options for naming exports, symmetric to the first two
14221438options for naming imports:
@@ -1609,7 +1625,7 @@ For example, the following component:
16091625;; a.wasm
16101626(component
16111627 (import "one" (func))
1612- (import "two" (value string))
1628+ (import "two" (value string)) 🪙
16131629 (import "three" (instance
16141630 (export "four" (instance
16151631 (export "five" (core module
@@ -1634,7 +1650,7 @@ could be successfully instantiated via:
16341650``` js
16351651WebAssembly .instantiateStreaming (fetch (' ./a.wasm' ), {
16361652 one : () => (),
1637- two: " hi" ,
1653+ two: " hi" , 🪙
16381654 three: {
16391655 four: {
16401656 five: await WebAssembly .compileStreaming (fetch (' ./b.wasm' ))
@@ -1878,6 +1894,7 @@ and will be added over the coming months to complete the MVP proposal:
18781894[ stack-switching ] : https://github.com/WebAssembly/stack-switching/blob/main/proposals/stack-switching/Overview.md
18791895[ esm-integration ] : https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration
18801896[ gc ] : https://github.com/WebAssembly/gc/blob/main/proposals/gc/MVP.md
1897+ [ WASI Preview 2 ] : https://github.com/WebAssembly/WASI/tree/main/preview2
18811898
18821899[ Adapter Functions ] : FutureFeatures.md#custom-abis-via-adapter-functions
18831900[ Canonical ABI ] : CanonicalABI.md
0 commit comments