@@ -23,7 +23,8 @@ JavaScript runtimes. For a more user-focused explanation, take a look at the
23
23
* [ Canonical definitions] ( #canonical-definitions )
24
24
* [ Canonical ABI] ( #canonical-built-ins )
25
25
* [ Canonical built-ins] ( #canonical-built-ins )
26
- * [ Start definitions] ( #-start-definitions )
26
+ * [ Value definitions] ( #value-definitions )
27
+ * [ Start definitions] ( #start-definitions )
27
28
* [ Import and export definitions] ( #import-and-export-definitions )
28
29
* [ Component invariants] ( #component-invariants )
29
30
* [ JavaScript embedding] ( #JavaScript-embedding )
@@ -87,6 +88,7 @@ definition ::= core-prefix(<core:module>)
87
88
| <start> 🪺
88
89
| <import>
89
90
| <export>
91
+ | <value> 🪙
90
92
91
93
where core-prefix(X) parses '(' 'core' Y ')' when X parses '(' Y ')'
92
94
```
@@ -296,7 +298,7 @@ contain any valid UTF-8 string).
296
298
297
299
🪙 The ` value ` sort refers to a value that is provided and consumed during
298
300
instantiation. How this works is described in the
299
- [ start definitions] ( #start -definitions ) section.
301
+ [ value definitions] ( #value -definitions ) section.
300
302
301
303
To see a non-trivial example of component instantiation, we'll first need to
302
304
introduce a few other definitions below that allow components to import, define
@@ -568,10 +570,12 @@ externdesc ::= (<sort> (type <u32>) )
568
570
| <functype>
569
571
| <componenttype>
570
572
| <instancetype>
571
- | (value <valtype >) 🪙
573
+ | (value <valuebound >) 🪙
572
574
| (type <typebound>)
573
575
typebound ::= (eq <typeidx>)
574
576
| (sub resource)
577
+ valuebound ::= (eq <valueidx>) 🪙
578
+ | <valtype> 🪙
575
579
576
580
where bind-id(X) parses '(' sort <id>? Y ')' when X parses '(' sort Y ')'
577
581
```
@@ -737,7 +741,7 @@ definitions.
737
741
738
742
🪙 The ` value ` case of ` externdesc ` describes a runtime value that is imported or
739
743
exported at instantiation time as described in the
740
- [ start definitions] ( #start -definitions ) section below.
744
+ [ value definitions] ( #value -definitions ) section below.
741
745
742
746
The ` type ` case of ` externdesc ` describes an imported or exported type along
743
747
with its "bound":
@@ -1355,22 +1359,100 @@ number of threads that can be expected to execute concurrently.
1355
1359
See the [ CanonicalABI.md] ( CanonicalABI.md#canonical-definitions ) for detailed
1356
1360
definitions of each of these built-ins and their interactions.
1357
1361
1362
+ ### 🪙 Value Definitions
1358
1363
1359
- ### 🪙 Start Definitions
1364
+ Value definitions (in the value index space) are like immutable ` global ` definitions
1365
+ in Core WebAssembly except that validation requires them to be consumed exactly
1366
+ once at instantiation-time (i.e., they are [ linear] ).
1367
+
1368
+ Components may define values in the value index space using following syntax:
1360
1369
1361
- Like modules, components can have start functions that are called during
1362
- instantiation. Unlike modules, components can call start functions at multiple
1363
- points during instantiation with each such call having parameters and results.
1364
- Thus, ` start ` definitions in components look like function calls:
1365
1370
``` ebnf
1366
- start ::= (start <funcidx> (value <valueidx>)* (result (value <id>?))*)
1371
+ value ::= (value <id>? <valtype> <val>)
1372
+ val ::= false | true
1373
+ | <core:i64>
1374
+ | <core:f64> | NaN
1375
+ | '<core:char>'
1376
+ | <core:name>
1377
+ | (record <val>+)
1378
+ | (variant "<label>" <val>?)
1379
+ | (list <val>*)
1380
+ | (tuple <val>+)
1381
+ | (flags "<label>"*)
1382
+ | (enum "<label>")
1383
+ | none | (some <val>)
1384
+ | ok | (ok <val>) | error | (error <val>)
1385
+ ```
1386
+
1387
+ The validation rules for ` value ` require the ` val ` to match the ` valtype ` . For example:
1388
+ ``` wasm
1389
+ (component
1390
+ (value $a bool true)
1391
+ (value $b u8 1)
1392
+ (value $c u16 2)
1393
+ (value $d u32 3)
1394
+ (value $e u64 4)
1395
+ (value $f u8 5)
1396
+ (value $g u16 6)
1397
+ (value $h u32 7)
1398
+ (value $i u64 8)
1399
+ (value $j f32 9.1)
1400
+ (value $k f64 9.2)
1401
+ (value $l char 'a')
1402
+ (value $m string "hello")
1403
+ (value $n (record (field "a" bool) (field "b" u8)) (record true 1))
1404
+ (value $o (variant (case "a" bool) (case "b" u8)) (variant "b" 1))
1405
+ (value $p (list (result (option u8)))
1406
+ (list
1407
+ error
1408
+ (ok (some 1))
1409
+ (ok none)
1410
+ error
1411
+ (ok (some 2))
1412
+ )
1413
+ )
1414
+ (value $q (tuple u8 u16 u32) (tuple 1 2 3))
1415
+
1416
+ (type $abc (flags "a" "b" "c"))
1417
+ (value $r $abc (flags "a" "c"))
1418
+
1419
+ (value $s (enum "a" "b" "c") (enum "b"))
1420
+
1421
+ (type $complex
1422
+ (tuple
1423
+ (record
1424
+ (field "a" (option string))
1425
+ (field "b" (tuple (option u8) string))
1426
+ )
1427
+ (list char)
1428
+ $abc
1429
+ string
1430
+ )
1431
+ )
1432
+ (value $complex1 (type $complex)
1433
+ (tuple
1434
+ (record
1435
+ none
1436
+ (tuple none "empty")
1437
+ )
1438
+ (list)
1439
+ (flags)
1440
+ ""
1441
+ )
1442
+ )
1443
+ (value $complex2 (type $complex)
1444
+ (tuple
1445
+ (record
1446
+ (some "example")
1447
+ (tuple (some 42) "hello")
1448
+ )
1449
+ (list 'a' 'b' 'c')
1450
+ (flags "b" "a")
1451
+ "hi"
1452
+ )
1453
+ )
1454
+ )
1367
1455
```
1368
- The ` (value <valueidx>)* ` list specifies the arguments passed to ` funcidx ` by
1369
- indexing into the * value index space* . Value definitions (in the value index
1370
- space) are like immutable ` global ` definitions in Core WebAssembly except that
1371
- validation requires them to be consumed exactly once at instantiation-time
1372
- (i.e., they are [ linear] ). The arity and types of the two value lists are
1373
- validated to match the signature of ` funcidx ` .
1374
1456
1375
1457
As with all definition sorts, values may be imported and exported by
1376
1458
components. As an example value import:
@@ -1380,6 +1462,45 @@ components. As an example value import:
1380
1462
As this example suggests, value imports can serve as generalized [ environment
1381
1463
variables] , allowing not just ` string ` , but the full range of ` valtype ` .
1382
1464
1465
+ Values can also be exported. For example:
1466
+ ``` wasm
1467
+ (component
1468
+ (import "system-port" (value $port u16))
1469
+ (value $url string "https://example.com")
1470
+ (export "default-url" (value $url))
1471
+ (export "default-port" (value $port))
1472
+ )
1473
+ ```
1474
+ The inferred type of this component is:
1475
+ ``` wasm
1476
+ (component
1477
+ (import "system-port" (value $port u16))
1478
+ (value $url string "https://example.com")
1479
+ (export "default-url" (value (eq $url)))
1480
+ (export "default-port" (value (eq $port)))
1481
+ )
1482
+ ```
1483
+ Thus, by default, the precise constant or import being exported is propagated
1484
+ into the component's type and thus its public interface. In this way, value exports
1485
+ can act as semantic configuration data provided by the component to the host
1486
+ or other client tooling.
1487
+ Components can also keep the exact value being exported abstract (so that the
1488
+ precise value is not part of the type and public interface) using the "type ascription"
1489
+ feature mentioned in the [ imports and exports] ( #import-and-export-definitions ) section below.
1490
+
1491
+ ### 🪙 Start Definitions
1492
+
1493
+ Like modules, components can have start functions that are called during
1494
+ instantiation. Unlike modules, components can call start functions at multiple
1495
+ points during instantiation with each such call having parameters and results.
1496
+ Thus, ` start ` definitions in components look like function calls:
1497
+ ``` ebnf
1498
+ start ::= (start <funcidx> (value <valueidx>)* (result (value <id>?))*)
1499
+ ```
1500
+ The ` (value <valueidx>)* ` list specifies the arguments passed to ` funcidx ` by
1501
+ indexing into the * value index space* . The arity and types of the two value lists are
1502
+ validated to match the signature of ` funcidx ` .
1503
+
1383
1504
With this, we can define a component that imports a string and computes a new
1384
1505
exported string at instantiation time:
1385
1506
``` wasm
@@ -1657,6 +1778,25 @@ the standard [avoidance problem] that appears in module systems with abstract
1657
1778
types. In particular, it ensures that a client of a component is able to
1658
1779
externally define a type compatible with the exports of the component.
1659
1780
1781
+ Similar to type exports, value exports may also ascribe a type to keep the precise
1782
+ value from becoming part of the type and public interface.
1783
+
1784
+ For example:
1785
+ ``` wasm
1786
+ (component
1787
+ (value $url string "https://example.com")
1788
+ (export "default-url" (value $url) (value string))
1789
+ )
1790
+ ```
1791
+
1792
+ The inferred type of this component is:
1793
+ ``` wasm
1794
+ (component
1795
+ (export "default-url" (value string))
1796
+ )
1797
+ ```
1798
+
1799
+ Note, that the ` url ` value definition is absent from the component type
1660
1800
1661
1801
## Component Invariants
1662
1802
@@ -1941,6 +2081,9 @@ and will be added over the coming months to complete the MVP proposal:
1941
2081
[ Index Space ] : https://webassembly.github.io/spec/core/syntax/modules.html#indices
1942
2082
[ Abbreviations ] : https://webassembly.github.io/spec/core/text/conventions.html#abbreviations
1943
2083
2084
+ [ `core:i64` ] : https://webassembly.github.io/spec/core/syntax/values.html#integers
2085
+ [ `core:f64` ] : https://webassembly.github.io/spec/core/syntax/values.html#floating-point
2086
+ [ `core:char` ] : https://webassembly.github.io/spec/core/syntax/values.html#syntax-name
1944
2087
[ `core:name` ] : https://webassembly.github.io/spec/core/syntax/values.html#syntax-name
1945
2088
[ `core:module` ] : https://webassembly.github.io/spec/core/text/modules.html#text-module
1946
2089
[ `core:type` ] : https://webassembly.github.io/spec/core/text/modules.html#types
0 commit comments