Skip to content

Commit a58ae86

Browse files
authored
Merge pull request #160 from WebAssembly/future-proof-binary-format
Prepare binary/text format of imports/exports for future additions
2 parents 8bc065a + 7b3d5ad commit a58ae86

File tree

2 files changed

+35
-33
lines changed

2 files changed

+35
-33
lines changed

design/mvp/Binary.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,12 @@ flags are set.
324324
(See [Import and Export Definitions](Explainer.md#import-and-export-definitions)
325325
in the explainer.)
326326
```
327-
import ::= en:<externname> ed:<externdesc> => (import en ed)
328-
export ::= en:<externname> si:<sortidx> ed?:<externdesc>? => (export en si ed?)
329-
externname ::= n:<name> u?:<URL>? => n u?
330-
URL ::= b*:vec(byte) => char(b)*, if char(b)* parses as a URL
327+
import ::= en:<externname> ed:<externdesc> => (import en ed)
328+
export ::= en:<externname> si:<sortidx> ed?:<externdesc>? => (export en si ed?)
329+
externname ::= n:<name> ea:<externattrs> => n ea
330+
externattrs ::= 0x00 => ϵ
331+
| 0x01 url:<URL> => (id url)
332+
URL ::= b*:vec(byte) => char(b)*, if char(b)* parses as a URL
331333
```
332334
Notes:
333335
* All exports (of all `sort`s) introduce a new index that aliases the exported

design/mvp/Explainer.md

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,7 @@ Using canonical function definitions, we can finally write a non-trivial
11251125
component that takes a string, does some logging, then returns a string.
11261126
```wasm
11271127
(component
1128-
(import "wasi:logging" (instance $logging
1128+
(import "logging" (id "wasi:logging") (instance $logging
11291129
(export "log" (func (param string)))
11301130
))
11311131
(import "libc" (core module $Libc
@@ -1300,7 +1300,7 @@ Lastly, imports and exports are defined as:
13001300
```
13011301
import ::= (import <externname> bind-id(<externdesc>))
13021302
export ::= (export <id>? <externname> <sortidx> <externdesc>?)
1303-
externname ::= <name> <URL>?
1303+
externname ::= <name> (id <URL>)?
13041304
```
13051305
Both import and export definitions append a new element to the index space of
13061306
the imported/exported `sort` which can be optionally bound to an identifier in
@@ -1341,12 +1341,12 @@ externally define a type compatible with the exports of the component.
13411341

13421342
Components split the single externally-visible name of imports and exports into
13431343
two sub-fields: a kebab-case `name` (as defined [above](#instance-definitions))
1344-
and a `URL` (defined by the [URL Standard], noting that, in this URL Standard,
1345-
the term "URL" subsumes what has historically been called a [URI], including
1346-
URLs that "identify" as opposed to "locate"). This subdivision of external
1347-
names allows component producers to represent a variety of intentions for how a
1348-
component is to be instantiated and executed so that a variety of hosts can
1349-
portably execute the component.
1344+
and an `id` field that contains a URL (as defined by the [URL Standard], noting
1345+
that, in this URL Standard, the term "URL" subsumes what has historically been
1346+
called a [URI], including URLs that "identify" as opposed to "locate"). This
1347+
subdivision of external names allows component producers to represent a variety
1348+
of intentions for how a component is to be instantiated and executed so that a
1349+
variety of hosts can portably execute the component.
13501350

13511351
The `name` field of `externname` is required to be unique. Thus, a single
13521352
`name` has been used in the preceding definitions of `with` and `alias` to
@@ -1383,7 +1383,7 @@ and accessing its exports. For example, the [JS API]'s
13831383
[`WebAssembly.instantiate()`] would use import `name`s in the [*read the
13841384
imports*] step and use export `name`s in the [*create an exports object*] step.
13851385

1386-
The optional `URL` field of `externname` allows a component author to refer to
1386+
The optional `id` field of `externname` allows a component author to refer to
13871387
an *externally-defined* specification of what an import "wants" or what an
13881388
export has "implemented". One example is a URL naming a standard interface such
13891389
as `wasi:filesystem` (assuming that WASI registered the `wasi:` URI scheme with
@@ -1396,48 +1396,48 @@ components, the Component Model doesn't specify how URLs are to be interpreted,
13961396
just that they are grammatically URLs. Even `https:` URLs may or may not be
13971397
literally fetched by the host (c.f. [import maps]).
13981398

1399-
When present, `URL`s must *also* be unique (*in addition* the abovementioned
1400-
uniqueness of `name`s). Thus, a `URL` can *also* be used to uniquely identify
1401-
the subset of imports or exports that have `URL`s.
1399+
The URLs of present `id` fields must *also* be unique (*in addition* the
1400+
abovementioned uniqueness of `name`s). Thus, a URL can *also* be used to
1401+
uniquely identify the subset of imports or exports that have URLs.
14021402

1403-
While the `name` field is meant for source-code bindings generators, the `URL`
1403+
While the `name` field is meant for source-code bindings generators, the `id`
14041404
field is meant for automated interpretation by hosts and toolchains. In
14051405
particular, hosts are expected to identify their host-implemented imports and
1406-
host-called exports by `URL`, not `name`. This allows hosts to implement a
1406+
host-called exports by URL, not `name`. This allows hosts to implement a
14071407
wide collection of independently-developed interfaces where `name`s are chosen
14081408
for developer ergonomics (and name collisions are handled independently in
1409-
the binding generators, which is needed in any case) and `URL`s serve as
1409+
the binding generators, which is needed in any case) and URLs to serve as
14101410
the invariant identifier that concretely links the guest to host. If there was
14111411
only a `name`, interface authors would be forced to implicitly coordinate
14121412
across the ecosystem to avoid collisions (which in general, isn't possible)
1413-
while if there was only a `URL`, the developer-friendly identifiers would have
1413+
while if there was only a URL, the developer-friendly identifiers would have
14141414
to be specified manually by every developer or derived in an ad hoc fashion
1415-
from the `URL`, whose contents may vary widely. This dual-name scheme is thus
1415+
from the URL, whose contents may vary widely. This dual-name scheme is thus
14161416
proposed to resolve these competing requirements.
14171417

14181418
Inside the component model, this dual-name scheme shows up in [subtyping](#Subtyping.md),
1419-
where the component subtyping simply ignores the `name` field when the `URL`
1419+
where the component subtyping simply ignores the `name` field when the `id`
14201420
field is present. For example, the component:
14211421
```
14221422
(component
1423-
(import "fs" "wasi:filesystem" ...)
1423+
(import "fs" (id "wasi:filesystem") ...)
14241424
)
14251425
```
14261426
can be supplied for the `x` import of the component:
14271427
```
14281428
(component
14291429
(import "x" (component
1430-
(import "filesystem" "wasi:filesystem" ...)
1430+
(import "filesystem" (id "wasi:filesystem") ...)
14311431
))
14321432
)
14331433
```
1434-
because the `name`s are ignored and the `URL`s match. This subtyping is
1434+
because the `name`s are ignored and the `id`s match. This subtyping is
14351435
symmetric to what was described above for hosts, allowing components to
14361436
serve as the "host" of other components, enabling [virtualization](examples/LinkTimeVirtualization.md).
14371437

14381438
Since the concrete artifacts defining the host/guest interface is a collection
14391439
of [Wit files](WIT.md), Wit must naturally allow interface authors to specify
1440-
both the `name` and `URL` of component imports and exports. While the syntax is
1440+
both the `name` and `id` of component imports and exports. While the syntax is
14411441
still very much [in flux](https://github.com/WebAssembly/component-model/pull/83),
14421442
a hypothetical simplified interface between a guest and host might look like:
14431443
```
@@ -1453,9 +1453,9 @@ defined interfaces that map to instance types. This "World" definition then
14531453
maps to the following component type:
14541454
```
14551455
(component $Command
1456-
(import "fs" "wasi:filesystem" (instance ... filesystem function exports ...))
1457-
(import "console" "wasi:cli/console" (instance ... log function exports ...))
1458-
(export "main" "wasi:cli/main" (instance (export "main" (func ...))))
1456+
(import "fs" (id "wasi:filesystem") (instance ... filesystem function exports ...))
1457+
(import "console" (id "wasi:cli/console") (instance ... log function exports ...))
1458+
(export "main" (id "wasi:cli/main") (instance (export "main" (func ...))))
14591459
)
14601460
```
14611461
A component *targeting* `wasi:cli/Command` would thus need to be a *subtype* of
@@ -1467,10 +1467,10 @@ to call a subset of these exports).
14671467
Importantly, this `wasi:cli/Command` World has been able to define the short
14681468
developer-facing names like `fs` and `console` without worrying if there are
14691469
any other Worlds that conflict with these names. If a host wants to implement
1470-
`wasi:cli/Command` and some other World that also happens to pick `fs`, either
1471-
the `URL` fields are the same, and so the two imports can be unified, or the
1472-
`URL` fields are different, and the host supplies two distinct imports,
1473-
identified by `URL`.
1470+
`wasi:cli/command` and some other World that also happens to pick `fs`, either
1471+
the `id` fields are the same, and so the two imports can be unified, or the
1472+
`id` fields are different, and the host supplies two distinct imports,
1473+
identified by URL.
14741474

14751475

14761476
## Component Invariants

0 commit comments

Comments
 (0)