Skip to content

Commit 08b2717

Browse files
committed
Add canonical interface name
1 parent e362068 commit 08b2717

File tree

2 files changed

+84
-21
lines changed

2 files changed

+84
-21
lines changed

design/mvp/Binary.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,13 @@ flags are set.
371371
(See [Import and Export Definitions](Explainer.md#import-and-export-definitions)
372372
in the explainer.)
373373
```ebnf
374-
import ::= in:<importname'> ed:<externdesc> => (import in ed)
375-
export ::= en:<exportname'> si:<sortidx> ed?:<externdesc>? => (export en si ed?)
376-
importname' ::= 0x00 len:<u32> in:<importname> => in (if len = |in|)
377-
exportname' ::= 0x00 len:<u32> en:<exportname> => en (if len = |en|)
374+
import ::= in:<importname'> ed:<externdesc> => (import in ed)
375+
export ::= en:<exportname'> si:<sortidx> ed?:<externdesc>? => (export en si ed?)
376+
importname' ::= 0x00 len:<u32> in:<importname> => in (if len = |in|)
377+
| 0x01 len:<u32> in:<importname> vs:<versionsuffix'> => in vs (if len = |in|)
378+
exportname' ::= 0x00 len:<u32> en:<exportname> => en (if len = |en|)
379+
| 0x01 len:<u32> en:<exportname> vs:<versionsuffix'> => in vs (if len = |in|)
380+
versionsuffix' ::= len:<u32> vs:<semversuffix> => (versionsuffix vs) (if len = |vs|)
378381
```
379382

380383
Notes:
@@ -399,7 +402,10 @@ Notes:
399402
`(result (own $R))`, where `$R` is the resource labeled `r`.
400403
* Validation of `[method]` names requires the first parameter of the function
401404
to be `(param "self" (borrow $R))`, where `$R` is the resource labeled `r`.
402-
* `<valid semver>` is as defined by [https://semver.org](https://semver.org/)
405+
* Validation requires that `versionsuffix` is preceded by an `interfaceversion`
406+
matching `canonversion` and that the concatenation of the `canonversion` and
407+
the `versionsuffix` results in a `valid semver` as defined by
408+
[https://semver.org](https://semver.org/)
403409
* `<integrity-metadata>` is as defined by the
404410
[SRI](https://www.w3.org/TR/SRI/#dfn-integrity-metadata) spec.
405411

@@ -494,7 +500,9 @@ named once.
494500

495501
* The opcodes (for types, canon built-ins, etc) should be re-sorted
496502
* The two `list` type codes should be merged into one with an optional immediate.
497-
* The `0x00` prefix byte of `importname'` and `exportname'` will be removed or repurposed.
503+
* The `0x00` variant of `importname'` and `exportname'` will be removed. Any
504+
remaining variant(s) will be renumbered or the prefix byte will be removed or
505+
repurposed.
498506

499507

500508
[`core:byte`]: https://webassembly.github.io/spec/core/binary/values.html#binary-byte

design/mvp/Explainer.md

Lines changed: 70 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ more user-focused explanation, take a look at the
3333
* [Start definitions](#-start-definitions)
3434
* [Import and export definitions](#import-and-export-definitions)
3535
* [Name uniqueness](#name-uniqueness)
36+
* [Canonical interface name](#canonical-interface-name)
3637
* [Component invariants](#component-invariants)
3738
* [JavaScript embedding](#JavaScript-embedding)
3839
* [JS API](#JS-API)
@@ -294,7 +295,7 @@ sort ::= core <core:sort>
294295
| type
295296
| component
296297
| instance
297-
inlineexport ::= (export <exportname> <sortidx>)
298+
inlineexport ::= (export "<exportname>" <versionsuffix>? <sortidx>)
298299
```
299300
Because component-level function, type and instance definitions are different
300301
than core-level function, type and instance definitions, they are put into
@@ -574,8 +575,8 @@ instancedecl ::= core-prefix(<core:type>)
574575
| <alias>
575576
| <exportdecl>
576577
| <value> 🪙
577-
importdecl ::= (import <importname> bind-id(<externdesc>))
578-
exportdecl ::= (export <exportname> bind-id(<externdesc>))
578+
importdecl ::= (import "<importname>" <versionsuffix>? bind-id(<externdesc>))
579+
exportdecl ::= (export "<exportname>" <versionsuffix>? bind-id(<externdesc>))
579580
externdesc ::= (<sort> (type <u32>) )
580581
| core-prefix(<core:moduletype>)
581582
| <functype>
@@ -2242,8 +2243,9 @@ the identifier `$x`). In the case of exports, the `<id>?` right after the
22422243
preceding definition being exported (e.g., `(export $x "x" (func $f))` binds a
22432244
new identifier `$x`).
22442245
```ebnf
2245-
import ::= (import "<importname>" bind-id(<externdesc>))
2246-
export ::= (export <id>? "<exportname>" <sortidx> <externdesc>?)
2246+
import ::= (import "<importname>" <versionsuffix>? bind-id(<externdesc>))
2247+
export ::= (export <id>? "<exportname>" <versionsuffix>? <sortidx> <externdesc>?)
2248+
versionsuffix ::= (versionsuffix "<semversuffix>")
22472249
```
22482250
All import names are required to be [strongly-unique]. Separately, all export
22492251
names are also required to be [strongly-unique]. The rest of the grammar for
@@ -2276,17 +2278,24 @@ fragment ::= <word>
22762278
| <acronym>
22772279
word ::= [a-z] [0-9a-z]*
22782280
acronym ::= [A-Z] [0-9A-Z]*
2279-
interfacename ::= <namespace> <label> <projection> <version>?
2280-
| <namespace>+ <label> <projection>+ <version>? 🪺
2281+
interfacename ::= <namespace> <label> <projection> <interfaceversion>?
2282+
| <namespace>+ <label> <projection>+ <interfaceversion>? 🪺
22812283
namespace ::= <words> ':'
22822284
words ::= <word>
22832285
| <words> '-' <word>
22842286
projection ::= '/' <label>
2285-
version ::= '@' <valid semver>
2287+
# FIXME: surrounding alignment
2288+
interfaceversion ::= '@' <valid semver>
2289+
| '@' <canonversion>
2290+
canonversion ::= [1-9] [0-9]*
2291+
| '0.' [1-9] [0-9]*
2292+
| '0.0.' [1-9] [0-9]*
2293+
semversuffix ::= [0-9A-Za-z.+-]*
22862294
depname ::= 'unlocked-dep=<' <pkgnamequery> '>'
22872295
| 'locked-dep=<' <pkgname> '>' ( ',' <hashname> )?
22882296
pkgnamequery ::= <pkgpath> <verrange>?
2289-
pkgname ::= <pkgpath> <version>?
2297+
pkgname ::= <pkgpath> <pkgversion>?
2298+
pkgversion ::= '@' <valid semver>
22902299
pkgpath ::= <namespace> <words>
22912300
| <namespace>+ <words> <projection>* 🪺
22922301
verrange ::= '@*'
@@ -2372,12 +2381,14 @@ tooling as "registries":
23722381
parameter of [`WebAssembly.instantiate()`])
23732382

23742383
The `valid semver` production is as defined by the [Semantic Versioning 2.0]
2375-
spec and is meant to be interpreted according to that specification. The
2376-
`verrange` production embeds a minimal subset of the syntax for version ranges
2377-
found in common package managers like `npm` and `cargo` and is meant to be
2378-
interpreted with the same [semantics][SemVerRange]. (Mostly this
2379-
interpretation is the usual SemVer-spec-defined ordering, but note the
2380-
particular behavior of pre-release tags.)
2384+
spec and is meant to be interpreted according to that specification. The use of
2385+
`valid semver` in `interfaceversion` is temporary for backward compatibility;
2386+
see [Canonical interface name](#canonical-interface-name) below. The `verrange`
2387+
production embeds a minimal subset of the syntax for version ranges found in
2388+
common package managers like `npm` and `cargo` and is meant to be interpreted
2389+
with the same [semantics][SemVerRange]. (Mostly this interpretation is the usual
2390+
SemVer-spec-defined ordering, but note the particular behavior of pre-release
2391+
tags.)
23812392

23822393
The `plainname` production captures several language-neutral syntactic hints
23832394
that allow bindings generators to produce more idiomatic bindings in their
@@ -2539,6 +2550,49 @@ annotations. For example, the validation rules for `[constructor]foo` require
25392550
for details.
25402551

25412552

2553+
### Canonical Interface Name
2554+
2555+
An `interfacename` (as defined above) is **canonical** iff it either:
2556+
2557+
- has no `interfaceversion`
2558+
- has an `interfaceversion` matching the `canonversion` production
2559+
2560+
The purpose of `canonversion` is to simplify the matching of compatible import
2561+
and export versions. For example, if a guest imports some interface from
2562+
`wasi:http/types@0.2.1` and a host provides the (subtype-compatible) interface
2563+
`wasi:http/types@0.2.6`, we'd like to make it easy for the host to link with the
2564+
guest. The `canonversion` for both of these interfaces would be `0.2`, so this
2565+
linking could be done by matching canonical interface names literally.
2566+
Symmetrically, if a host provides `wasi:http/types@0.2.1` and a guest imports
2567+
`wasi:http/types@0.2.6`, so long as the guest's imported `instancetype` is
2568+
subtype-compatible with the host implementation linking should be trivial.
2569+
2570+
Any `valid semver` (as used in WIT) can be canonicalized by splitting it into
2571+
two parts - the `canonversion` prefix and the remaining `semversuffix`. Using
2572+
the `<major>.<minor>.<patch>` syntax of [Semantic Versioning 2.0], the split
2573+
point is chosen as follows:
2574+
2575+
- if `major` > 0, split immediately after `major`
2576+
- `1.2.3` &rarr; `1` / `.2.3`
2577+
- otherwise if `minor` > 0, split immediately after `minor`
2578+
- `0.2.6-rc.1` &rarr; `0.2` / `.6-rc.1`
2579+
- otherwise, split immediately after `patch`
2580+
- `0.0.1-alpha` &rarr; `0.0.1` / `-alpha`
2581+
2582+
When a version is canonicalized, any `semversuffix` that was split off of the
2583+
version should be preserved in the `versionsuffix` field of any resulting
2584+
`import`s and `export`s. This gives component runtimes and other tools access to
2585+
the original version for error messages, documentation, and other development
2586+
purposes. Where a `versionsuffix` is present the preceding `interfacename` must
2587+
have a `canonversion`, and the concatenation of the `canonversion` and
2588+
`versionsuffix` must be a `valid semver`.
2589+
2590+
For compatibility with older versions of this spec, non-canonical
2591+
`interfacename`s (with `interfaceversion`s matching any `valid semver`) are
2592+
temporarily permitted. These non-canonical names may trigger warnings and will
2593+
start being rejected some time after after [WASI Preview 3] is released.
2594+
2595+
25422596
## Component Invariants
25432597

25442598
As a consequence of the shared-nothing design described above, all calls into
@@ -2894,6 +2948,7 @@ For some use-case-focused, worked examples, see:
28942948
[`rectype`]: https://webassembly.github.io/gc/core/text/types.html#text-rectype
28952949
[shared-everything-threads]: https://github.com/WebAssembly/shared-everything-threads
28962950
[WASI Preview 2]: https://github.com/WebAssembly/WASI/tree/main/wasip2#readme
2951+
[WASI Preview 3]: https://github.com/WebAssembly/WASI/tree/main/wasip2#looking-forward-to-preview-3
28972952
[reference types]: https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md
28982953

28992954
[Strongly-unique]: #name-uniqueness

0 commit comments

Comments
 (0)