@@ -23,7 +23,8 @@ JavaScript runtimes. For a more user-focused explanation, take a look at the
2323 * [ Canonical definitions] ( #canonical-definitions )
2424 * [ Canonical ABI] ( #canonical-built-ins )
2525 * [ Canonical built-ins] ( #canonical-built-ins )
26- * [ Start definitions] ( #-start-definitions )
26+ * [ Value definitions] ( #value-definitions )
27+ * [ Start definitions] ( #start-definitions )
2728 * [ Import and export definitions] ( #import-and-export-definitions )
2829* [ Component invariants] ( #component-invariants )
2930* [ JavaScript embedding] ( #JavaScript-embedding )
@@ -87,6 +88,7 @@ definition ::= core-prefix(<core:module>)
8788 | <start> 🪺
8889 | <import>
8990 | <export>
91+ | <value> 🪙
9092
9193where core-prefix(X) parses '(' 'core' Y ')' when X parses '(' Y ')'
9294```
@@ -296,7 +298,7 @@ contain any valid UTF-8 string).
296298
297299🪙 The ` value ` sort refers to a value that is provided and consumed during
298300instantiation. How this works is described in the
299- [ start definitions] ( #start -definitions ) section.
301+ [ value definitions] ( #value -definitions ) section.
300302
301303To see a non-trivial example of component instantiation, we'll first need to
302304introduce a few other definitions below that allow components to import, define
@@ -564,10 +566,12 @@ externdesc ::= (<sort> (type <u32>) )
564566 | <functype>
565567 | <componenttype>
566568 | <instancetype>
567- | (value <valtype >) 🪙
569+ | (value <valuebound >) 🪙
568570 | (type <typebound>)
569571typebound ::= (eq <typeidx>)
570572 | (sub resource)
573+ valuebound ::= (eq <valueidx>) 🪙
574+ | <valtype> 🪙
571575
572576where bind-id(X) parses '(' sort <id>? Y ')' when X parses '(' sort Y ')'
573577```
@@ -733,7 +737,7 @@ definitions.
733737
734738🪙 The ` value ` case of ` externdesc ` describes a runtime value that is imported or
735739exported at instantiation time as described in the
736- [ start definitions] ( #start -definitions ) section below.
740+ [ value definitions] ( #value -definitions ) section below.
737741
738742The ` type ` case of ` externdesc ` describes an imported or exported type along
739743with its "bound":
@@ -1348,22 +1352,100 @@ number of threads that can be expected to execute concurrently.
13481352See the [ CanonicalABI.md] ( CanonicalABI.md#canonical-definitions ) for detailed
13491353definitions of each of these built-ins and their interactions.
13501354
1355+ ### 🪙 Value Definitions
13511356
1352- ### 🪙 Start Definitions
1357+ Value definitions (in the value index space) are like immutable ` global ` definitions
1358+ in Core WebAssembly except that validation requires them to be consumed exactly
1359+ once at instantiation-time (i.e., they are [ linear] ).
1360+
1361+ Components may define values in the value index space using following syntax:
13531362
1354- Like modules, components can have start functions that are called during
1355- instantiation. Unlike modules, components can call start functions at multiple
1356- points during instantiation with each such call having parameters and results.
1357- Thus, ` start ` definitions in components look like function calls:
13581363``` ebnf
1359- start ::= (start <funcidx> (value <valueidx>)* (result (value <id>?))*)
1364+ value ::= (value <id>? <valtype> <val>)
1365+ val ::= false | true
1366+ | <core:i64>
1367+ | <core:f64> | NaN
1368+ | '<core:char>'
1369+ | <core:name>
1370+ | (record <val>+)
1371+ | (variant "<label>" <val>?)
1372+ | (list <val>*)
1373+ | (tuple <val>+)
1374+ | (flags "<label>"*)
1375+ | (enum "<label>")
1376+ | none | (some <val>)
1377+ | ok | (ok <val>) | error | (error <val>)
1378+ ```
1379+
1380+ The validation rules for ` value ` require the ` val ` to match the ` valtype ` . For example:
1381+ ``` wasm
1382+ (component
1383+ (value $a bool true)
1384+ (value $b u8 1)
1385+ (value $c u16 2)
1386+ (value $d u32 3)
1387+ (value $e u64 4)
1388+ (value $f u8 5)
1389+ (value $g u16 6)
1390+ (value $h u32 7)
1391+ (value $i u64 8)
1392+ (value $j f32 9.1)
1393+ (value $k f64 9.2)
1394+ (value $l char 'a')
1395+ (value $m string "hello")
1396+ (value $n (record (field "a" bool) (field "b" u8)) (record true 1))
1397+ (value $o (variant (case "a" bool) (case "b" u8)) (variant "b" 1))
1398+ (value $p (list (result (option u8)))
1399+ (list
1400+ error
1401+ (ok (some 1))
1402+ (ok none)
1403+ error
1404+ (ok (some 2))
1405+ )
1406+ )
1407+ (value $q (tuple u8 u16 u32) (tuple 1 2 3))
1408+
1409+ (type $abc (flags "a" "b" "c"))
1410+ (value $r $abc (flags "a" "c"))
1411+
1412+ (value $s (enum "a" "b" "c") (enum "b"))
1413+
1414+ (type $complex
1415+ (tuple
1416+ (record
1417+ (field "a" (option string))
1418+ (field "b" (tuple (option u8) string))
1419+ )
1420+ (list char)
1421+ $abc
1422+ string
1423+ )
1424+ )
1425+ (value $complex1 (type $complex)
1426+ (tuple
1427+ (record
1428+ none
1429+ (tuple none "empty")
1430+ )
1431+ (list)
1432+ (flags)
1433+ ""
1434+ )
1435+ )
1436+ (value $complex2 (type $complex)
1437+ (tuple
1438+ (record
1439+ (some "example")
1440+ (tuple (some 42) "hello")
1441+ )
1442+ (list 'a' 'b' 'c')
1443+ (flags "b" "a")
1444+ "hi"
1445+ )
1446+ )
1447+ )
13601448```
1361- The ` (value <valueidx>)* ` list specifies the arguments passed to ` funcidx ` by
1362- indexing into the * value index space* . Value definitions (in the value index
1363- space) are like immutable ` global ` definitions in Core WebAssembly except that
1364- validation requires them to be consumed exactly once at instantiation-time
1365- (i.e., they are [ linear] ). The arity and types of the two value lists are
1366- validated to match the signature of ` funcidx ` .
13671449
13681450As with all definition sorts, values may be imported and exported by
13691451components. As an example value import:
@@ -1373,6 +1455,45 @@ components. As an example value import:
13731455As this example suggests, value imports can serve as generalized [ environment
13741456variables] , allowing not just ` string ` , but the full range of ` valtype ` .
13751457
1458+ Values can also be exported. For example:
1459+ ``` wasm
1460+ (component
1461+ (import "system-port" (value $port u16))
1462+ (value $url string "https://example.com")
1463+ (export "default-url" (value $url))
1464+ (export "default-port" (value $port))
1465+ )
1466+ ```
1467+ The inferred type of this component is:
1468+ ``` wasm
1469+ (component
1470+ (import "system-port" (value $port u16))
1471+ (value $url string "https://example.com")
1472+ (export "default-url" (value (eq $url)))
1473+ (export "default-port" (value (eq $port)))
1474+ )
1475+ ```
1476+ Thus, by default, the precise constant or import being exported is propagated
1477+ into the component's type and thus its public interface. In this way, value exports
1478+ can act as semantic configuration data provided by the component to the host
1479+ or other client tooling.
1480+ Components can also keep the exact value being exported abstract (so that the
1481+ precise value is not part of the type and public interface) using the "type ascription"
1482+ feature mentioned in the [ imports and exports] ( #import-and-export-definitions ) section below.
1483+
1484+ ### 🪙 Start Definitions
1485+
1486+ Like modules, components can have start functions that are called during
1487+ instantiation. Unlike modules, components can call start functions at multiple
1488+ points during instantiation with each such call having parameters and results.
1489+ Thus, ` start ` definitions in components look like function calls:
1490+ ``` ebnf
1491+ start ::= (start <funcidx> (value <valueidx>)* (result (value <id>?))*)
1492+ ```
1493+ The ` (value <valueidx>)* ` list specifies the arguments passed to ` funcidx ` by
1494+ indexing into the * value index space* . The arity and types of the two value lists are
1495+ validated to match the signature of ` funcidx ` .
1496+
13761497With this, we can define a component that imports a string and computes a new
13771498exported string at instantiation time:
13781499``` wasm
@@ -1650,6 +1771,25 @@ the standard [avoidance problem] that appears in module systems with abstract
16501771types. In particular, it ensures that a client of a component is able to
16511772externally define a type compatible with the exports of the component.
16521773
1774+ Similar to type exports, value exports may also ascribe a type to keep the precise
1775+ value from becoming part of the type and public interface.
1776+
1777+ For example:
1778+ ``` wasm
1779+ (component
1780+ (value $url string "https://example.com")
1781+ (export "default-url" (value $url) (value string))
1782+ )
1783+ ```
1784+
1785+ The inferred type of this component is:
1786+ ``` wasm
1787+ (component
1788+ (export "default-url" (value string))
1789+ )
1790+ ```
1791+
1792+ Note, that the ` url ` value definition is absent from the component type
16531793
16541794## Component Invariants
16551795
@@ -1934,6 +2074,9 @@ and will be added over the coming months to complete the MVP proposal:
19342074[ Index Space ] : https://webassembly.github.io/spec/core/syntax/modules.html#indices
19352075[ Abbreviations ] : https://webassembly.github.io/spec/core/text/conventions.html#abbreviations
19362076
2077+ [ `core:i64` ] : https://webassembly.github.io/spec/core/syntax/values.html#integers
2078+ [ `core:f64` ] : https://webassembly.github.io/spec/core/syntax/values.html#floating-point
2079+ [ `core:char` ] : https://webassembly.github.io/spec/core/syntax/values.html#syntax-name
19372080[ `core:name` ] : https://webassembly.github.io/spec/core/syntax/values.html#syntax-name
19382081[ `core:module` ] : https://webassembly.github.io/spec/core/text/modules.html#text-module
19392082[ `core:type` ] : https://webassembly.github.io/spec/core/text/modules.html#types
0 commit comments