@@ -26,6 +26,7 @@ more user-focused explanation, take a look at the
2626 * [ Canonical ABI] ( #canonical-abi )
2727 * [ Canonical built-ins] ( #canonical-built-ins )
2828 * [ Resource built-ins] ( #resource-built-ins )
29+ * [ Optionality built-ins] ( #-optionality-built-ins )
2930 * [ Concurrency built-ins] ( #-concurrency-built-ins )
3031 * [ Error Context built-ins] ( #-error-context-built-ins )
3132 * [ Value definitions] ( #-value-definitions )
@@ -75,6 +76,7 @@ shipped as part of a future WASI Developer Preview release:
7576* 🐘: [ memory64]
7677* 📡: getters and setters
7778* ➡️: ` stream.forward ` and ` future.forward ` built-ins
79+ * ❓: ` optional ` imports and exports
7880
7981
8082## Grammar
@@ -643,8 +645,9 @@ instancedecl ::= core-prefix(<core:type>)
643645 | <type>
644646 | <alias>
645647 | <exportdecl>
646- importdecl ::= (import <externnamelit> <attributes> bind-id(<externtype>))
647- exportdecl ::= (export <externnamelit> <attributes> bind-id(<externtype>))
648+ importdecl ::= (import <externnamelit> <attributes> <optexterntype>)
649+ exportdecl ::= (export <externnamelit> <attributes> <optexterntype>)
650+ optexterntype ::= optional? bind-id(<externtype>)
648651externtype ::= (<sort> (type <idx>) )
649652 | core-prefix(<core:moduletype>)
650653 | <functype>
@@ -918,19 +921,20 @@ capabilities of the component model.
918921
919922#### Declarators
920923
921- The ` importdecl ` and ` exportdecl ` declarators correspond to component ` import `
922- and ` export ` definitions, respectively, allowing an identifier to be bound for
923- use by subsequent declarators. The definitions of ` labellit ` , ` externnamelit `
924- and ` attribute ` are given in the [ imports and exports] ( #import-and-export-definitions )
925- section below. Following the precedent of [ ` core:typeuse ` ] , the text format
924+ The ` importdecl ` and ` exportdecl ` rules describe component-level ` import ` and
925+ ` export ` definitions at the type level. Thus, * both* imports and exports have an
926+ ` externtype ` , not just imports. Both declarators allow an identifier to be bound
927+ for use by subsequent declarators, so that imported and exported types can
928+ be used to define imported or exported function types.
929+
930+ The definitions of ` labellit ` , ` externnamelit ` and ` attribute ` are given in the
931+ [ imports and exports] ( #import-and-export-definitions ) section below.
932+
933+ Following the precedent of [ ` core:typeuse ` ] , the text format of ` externtype `
926934allows both references to out-of-line type definitions (via ` (type <typeidx>) ` )
927935and inline type expressions that the text format desugars into out-of-line type
928936definitions.
929937
930- 🪙 The ` value ` case of ` externtype ` describes a runtime value that is imported or
931- exported at instantiation time as described in the
932- [ value definitions] ( #value-definitions ) section below.
933-
934938The ` type ` case of ` externtype ` describes an imported or exported type along
935939with its "bound":
936940
@@ -955,6 +959,38 @@ to some preceding type definition. This allows:
955959 could generate in C++ a ` typedef std::vector<uint64_t> bytes ` or in JS an
956960 exported field named ` bytes ` that aliases ` Uint64Array ` .
957961
962+ 🪙 The ` value ` case of ` externtype ` describes a runtime value that is imported or
963+ exported at instantiation time as described in the
964+ [ value definitions] ( #value-definitions ) section below.
965+
966+ ❓ The ` optional ` immediate indicates that the containing import or export may
967+ or may not be "present" at instantiation time.
968+ export unconditionally adds an index to ` T ` 's index space so that index spaces
969+ have runtime-invariant contents. The meaning of "not present" depends on the
970+ ` externtype' ` :
971+ * For ` func ` , "not present" means "traps if called".
972+ * For ` instance ` , "not present" means "the contained exports are either
973+ all-present or all not-present". Consequently, ` alias export $i "e" `
974+ produces an ` optional ` alias for ` "e" ` if ` $i ` is ` optional ` .
975+ * For ` type ` , "not present" means that any ` func ` or ` instance ` ` externtype `
976+ that transitively refers to a "not present" ` type ` also becomes "not present",
977+ (even if that ` func ` or ` instance ` is not declared ` optional ` ).
978+ * 🪙 For ` value ` , "not present" means "a ` none ` value will be passed into any
979+ ` start ` function that takes this value as a parameter" (as described below).
980+ Consequently, an import of ` (optional (value T)) ` is given the value type
981+ ` (option T) ` when validating a ` start ` call.
982+
983+ To determine whether an ` optional ` -typed ` sortidx ` is present at runtime, Core
984+ WebAssembly code can import a ` global i32 ` boolean for that ` sortidx ` using the
985+ ABI built-in ` optional.present ` (as described below).
986+
987+ TODO: For example...
988+ ``` wat
989+ ... dependent explicitly optional
990+ ... dependent implicitly optional
991+ ... maybe show `optional.present` for a few and describe the relationship
992+ ```
993+
958994The ` alias ` declarator reuses the syntax for component-level ` alias ` definitions
959995so that ` export ` and ` outer ` aliases can be used inside ` component ` and
960996` instance ` * types* . For example, ` export ` aliases are necessary to define the
@@ -1090,6 +1126,11 @@ in the future to better support API Evolution (being careful to understand how
10901126subtyping manifests itself in the wide variety of source languages so that
10911127subtype-compatible updates don't inadvertently break source-level clients).
10921128
1129+ ❓ TODO: mention ` optional ` in subtyping:
1130+ * ` (X ...) <: (X optional ...) `
1131+ * ` (instance (X optional ...)) <: (instance optional (X ...)) `
1132+ * dependently optional on all the parts: present iff all parts are
1133+
10931134Module, component and instance subtyping allows a subtype to export more and
10941135import less than is declared by the supertype, ignoring the exact order of
10951136imports and exports and considering only names. For example, here, ` $I1 ` is a
@@ -1335,6 +1376,15 @@ replaced by `$R` when validating the instantiations of `$c1` and `$c2`. These
13351376type-checking rules for instantiating type imports mirror the * elimination*
13361377rule of [ universal types] (∀T).
13371378
1379+ ❓ TODO:
1380+ * for ` optional ` import:
1381+ * if provide nothing: substitute bottom type (can't name: no valid functions)
1382+ * e.g., but can still lower (to trap) and call ` optional.present `
1383+ * else: substitute
1384+ * ` optional ` is part of what's substituted, so it goes away if provide
1385+ non-optional def to ` with `
1386+ * e.g., can export with non-optional type
1387+
13381388Importantly, this type substitution performed by the parent is not visible to
13391389the child at validation- or run-time. In particular, there are no runtime
13401390casts that can "see through" to the original type parameter, avoiding
@@ -1558,6 +1608,7 @@ canon ::= ...
15581608 | (canon resource.new <typeidx> (core func <id>?))
15591609 | (canon resource.drop <typeidx> (core func <id>?))
15601610 | (canon resource.rep <typeidx> (core func <id>?))
1611+ | (canon optional.present <sortidx> (core global <id>?)) ❓
15611612 | (canon context.get <core:valtype> <u32> (core func <id>?)) 🔀
15621613 | (canon context.set <core:valtype> <u32> (core func <id>?)) 🔀
15631614 | (canon backpressure.inc (core func <id>?)) 🔀
@@ -1684,6 +1735,12 @@ transferring ownership of the newly-created resource to the export's caller.
16841735
16851736For details, see [ ` canon_resource_rep ` ] in the Canonical ABI explainer.
16861737
1738+ ##### ❓ Optionality built-ins
1739+
1740+ ###### ❓ ` optional.present `
1741+
1742+ TODO
1743+
16871744##### 🔀🧵 Concurrency built-ins
16881745
16891746See the [ concurrency explainer] for background.
@@ -2658,27 +2715,29 @@ A third difference is that not only import definitions, but also export
26582715definitions append a new element to the index space of the imported/exported
26592716` sort ` which can be optionally bound to an identifier in the text format. In the
26602717case of imports, the identifier is bound just like Core WebAssembly, as part of
2661- the ` externtype ` (e.g., ` (import "x" (func $x)) ` binds the identifier ` $x ` ). In
2662- the case of exports, the ` <id>? ` right after the ` export ` is bound while the
2718+ the ` externtype ` (e.g., ` (import "x" (func $x)) ` binds the identifier ` $x ` ).
2719+ In the case of exports, the ` <id>? ` right after the ` export ` is bound while the
26632720` <id> ` inside the ` <externidx> ` is a reference to the preceding definition being
26642721exported (e.g., ` (export $x "x" (func $f)) ` binds a new identifier ` $x ` ).
26652722
26662723Given this, the syntax of imports and exports are defined as follows:
26672724``` ebnf
2668- import ::= (import <externnamelit> <attributes> bind-id(<externtype>) )
2669- export ::= (export <id>? <externnamelit> <attributes> <externidx> <externtype >?)
2725+ import ::= (import <externnamelit> <attributes> <optexterntype> )
2726+ export ::= (export <id>? <externnamelit> <attributes> <externidx> <optexterntype >?)
26702727attributes ::= <implements>? <versionsuffix>? <externid>?
26712728implements ::= (implements <interfacenamelit>) 🏷️
26722729versionsuffix ::= (version-suffix <semversuffixlit>) 🔗
26732730externid ::= (external-id <name>) 🏷️
26742731```
26752732Imports and exports both have a * name* (` externnamelit ` ) and a list of
2676- * attributes* (` attributes ` ). Imports always include a type (` externtype ` ).
2733+ * attributes* (` attributes ` ). Imports always include a type (` optexterntype ` ).
26772734Exports always refer to a preceding definition (` externidx ` ) whose type is used
26782735by default as the type of the export. However, this "inferred" type can be
2679- overridden with an optional type ascription (` externtype ` ) which must be
2736+ overridden with an optional type ascription (` optexterntype ` ) which must be
26802737compatible with the exported definition's type.
26812738
2739+ TODO: ` optional `
2740+
26822741Import and export names are used by hosts and [ parent] [ Donut Wrapped ] components
26832742to * identify* imports and exports. Names are expected to be bound to source
26842743language variable-, function- and type-names. Thus, names are required to be
0 commit comments