@@ -31,6 +31,7 @@ being specified here.
31
31
* [ Flat Lowering] ( #flat-lowering )
32
32
* [ Lifting and Lowering Values] ( #lifting-and-lowering-values )
33
33
* [ Canonical definitions] ( #canonical-definitions )
34
+ * [ ` canonopt ` Validation] ( #canonopt-validation )
34
35
* [ ` canon lift ` ] ( #canon-lift )
35
36
* [ ` canon lower ` ] ( #canon-lower )
36
37
* [ ` canon resource.new ` ] ( #canon-resourcenew )
@@ -2705,19 +2706,51 @@ Using the above supporting definitions, we can describe the static and dynamic
2705
2706
semantics of component-level [ ` canon ` ] definitions. The following subsections
2706
2707
cover each of these ` canon ` cases.
2707
2708
2709
+ ### ` canonopt ` Validation
2710
+
2711
+ Canonical options, often referred to as ` $opts ` in the definitions below,
2712
+ can be specified at most once in any particular list of options. For example
2713
+ specifying ` string-encoding=utf8 ` twice is an error. Each individual option, if
2714
+ present, is validated as such:
2715
+
2716
+ * ` string-encoding=N ` - can be passed at most once, regardless of ` N ` .
2717
+ * ` memory ` - this is a subtype of ` (memory 1) `
2718
+ * ` realloc ` - the function has type ` (func (param i32 i32 i32 i32) (result i32)) `
2719
+ * if ` realloc ` is present, then ` memory ` must be present
2720
+ * ` post-return ` - only allowed on [ ` canon lift ` ] ( #canon-lift ) , which has rules
2721
+ for validation
2722
+ * 🔀 ` async ` - cannot be present with ` post-return `
2723
+ * 🔀 ` callback ` - the function has type `(func (param i32 i32 i32 i32) (result
2724
+ i32))` and cannot be present without ` async` and is only allowed with [ ` canon
2725
+ lift`] ( #canon-lift )
2726
+
2727
+ Additionally some options are required depending on lift/lower operations
2728
+ performed for a component. These are defined as:
2729
+
2730
+ * ` lower(T) `
2731
+ * requires ` memory ` if ` T ` contains a ` list ` or ` string `
2732
+
2733
+ * ` lift(T) `
2734
+ * requires ` realloc ` if ` T ` contains a ` list ` or ` string `
2735
+
2736
+
2708
2737
### ` canon lift `
2709
2738
2710
2739
For a canonical definition:
2711
2740
``` wat
2712
2741
(canon lift $callee:<funcidx> $opts:<canonopt>* (func $f (type $ft)))
2713
2742
```
2714
- validation specifies:
2743
+
2744
+ In addition to [ general validation of ` $opts ` ] ( #canonopt-validation ) the additional
2745
+ validation is performed:
2746
+
2715
2747
* ` $callee ` must have type ` flatten_functype($opts, $ft, 'lift') `
2716
2748
* ` $f ` is given type ` $ft `
2717
- * a ` memory ` is present if required by lifting and is a subtype of ` (memory 1) `
2718
- * a ` realloc ` is present if required by lifting and has type ` (func (param i32 i32 i32 i32) (result i32)) `
2719
- * if ` async ` is set, a ` post-return ` function may not be set
2720
2749
* if a ` post-return ` is present, it has type ` (func (param flatten_functype({}, $ft, 'lift').results)) `
2750
+ * requires options based on [ ` lift(param) ` ] ( #canonopt-validation ) for all parameters in ` ft `
2751
+ * requires options based on [ ` lower(result) ` ] ( #canonopt-validation ) if ` ft ` has a result
2752
+ * if ` len(flatten_types(ft.param_types())) > MAX_FLAT_PARAMS ` , ` realloc ` is required
2753
+ * if ` len(flatten_types(ft.result_types())) > MAX_FLAT_RESULTS ` , ` memory ` is required
2721
2754
2722
2755
When instantiating component instance ` $inst ` :
2723
2756
* Define ` $f ` to be the partially-bound closure ` canon_lift($opts, $inst, $ft, $callee) `
@@ -2874,12 +2907,16 @@ For a canonical definition:
2874
2907
``` wat
2875
2908
(canon lower $callee:<funcidx> $opts:<canonopt>* (core func $f))
2876
2909
```
2877
- where ` $callee ` has type ` $ft ` , validation specifies:
2910
+
2911
+ In addition to [ general validation of ` $opts ` ] ( #canonopt-validation ) the additional
2912
+ validation is performed where ` $callee ` has type ` $ft ` :
2913
+
2878
2914
* ` $f ` is given type ` flatten_functype($opts, $ft, 'lower') `
2879
- * a ` memory ` is present if required by lifting and is a subtype of ` (memory 1) `
2880
- * a ` realloc ` is present if required by lifting and has type ` (func (param i32 i32 i32 i32) (result i32)) `
2881
- * there is no ` post-return ` in ` $opts `
2882
- * if ` contains_async_value($ft) ` , then ` $opts.async ` must be set
2915
+ * requires options [ based on ` lower(param) ` ] ( #canonopt-validation ) for all parameters in ` ft `
2916
+ * requires options [ based on ` lift(result) ` ] ( #canonopt-validation ) if ` ft ` has a result
2917
+ * if ` len(flatten_types(ft.param_types())) > max_flat_params ` , ` memory ` is required
2918
+ * if ` len(flatten_types(ft.result_types())) > max_flat_results ` , ` realloc ` is required
2919
+ * 🔀 if ` async ` is specified, ` memory ` must be present
2883
2920
2884
2921
When instantiating component instance ` $inst ` :
2885
2922
* Define ` $f ` to be the partially-bound closure: ` canon_lower($opts, $ft, $callee) `
@@ -3189,9 +3226,13 @@ For a canonical definition:
3189
3226
``` wat
3190
3227
(canon task.return (result $t)? $opts (core func $f))
3191
3228
```
3192
- validation specifies:
3229
+
3230
+ In addition to [ general validation of ` $opts ` ] ( #canonopt-validation ) validation
3231
+ specifies:
3232
+
3193
3233
* ` $f ` is given type ` flatten_functype($opts, (func (param $t)?), 'lower') `
3194
3234
* ` $opts ` may only contain ` memory ` and ` string-encoding `
3235
+ * [ ` lift($f.result) ` above] ( #canonopt-validation ) defines required options
3195
3236
3196
3237
Calling ` $f ` invokes the following function which uses ` Task.return_ ` to lift
3197
3238
and pass the results to the caller:
@@ -3450,8 +3491,12 @@ For canonical definitions:
3450
3491
(canon stream.read $t $opts (core func $f))
3451
3492
(canon stream.write $t $opts (core func $f))
3452
3493
```
3453
- validation specifies:
3494
+ In addition to [ general validation of ` $opts ` ] ( #canonopt-validation ) validation
3495
+ specifies:
3454
3496
* ` $f ` is given type ` (func (param i32 i32 i32) (result i32)) `
3497
+ * [ ` lower($t) ` above] ( #canonopt-validation ) defines required options for ` stream.write `
3498
+ * [ ` lift($t) ` above] ( #canonopt-validation ) defines required options for ` stream.read `
3499
+ * ` memory ` is required to be present
3455
3500
3456
3501
For canonical definitions:
3457
3502
``` wat
@@ -3460,6 +3505,9 @@ For canonical definitions:
3460
3505
```
3461
3506
validation specifies:
3462
3507
* ` $f ` is given type ` (func (param i32 i32) (result i32)) `
3508
+ * [ ` lower($t) ` above] ( #canonopt-validation ) defines required options for ` future.write `
3509
+ * [ ` lift($t) ` above] ( #canonopt-validation ) defines required options for ` future.read `
3510
+ * ` memory ` is required to be present
3463
3511
3464
3512
The implementation of these four built-ins all funnel down to a single
3465
3513
parameterized ` copy ` function:
@@ -3693,6 +3741,8 @@ For a canonical definition:
3693
3741
```
3694
3742
validation specifies:
3695
3743
* ` $f ` is given type ` (func (param i32 i32) (result i32)) `
3744
+ * ` async ` is not present
3745
+ * ` memory ` must be present
3696
3746
3697
3747
Calling ` $f ` calls the following function which uses the ` $opts ` immediate to
3698
3748
(non-deterministically) lift the debug message, create a new ` ErrorContext `
@@ -3732,6 +3782,9 @@ For a canonical definition:
3732
3782
```
3733
3783
validation specifies:
3734
3784
* ` $f ` is given type ` (func (param i32 i32)) `
3785
+ * ` async ` is not present
3786
+ * ` memory ` must be present
3787
+ * ` realloc ` must be present
3735
3788
3736
3789
Calling ` $f ` calls the following function which uses the ` $opts ` immediate to
3737
3790
lowers the ` ErrorContext ` 's debug message. While * producing* an ` error-context `
0 commit comments