Skip to content

Commit f8299a8

Browse files
committed
Define and require names to be 'strongly-unique'
1 parent a96ef45 commit f8299a8

File tree

2 files changed

+54
-24
lines changed

2 files changed

+54
-24
lines changed

design/mvp/Binary.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,7 @@ Notes:
270270
* All parameter labels, result labels, record field labels, variant case
271271
labels, flag labels, enum case labels, component import names, component
272272
export names, instance import names and instance export names must be
273-
unique in their containing scope, considering two labels that differ only in
274-
case to be equal and thus rejected.
273+
[strongly-unique] in their containing scope.
275274
* Validation of `externdesc` requires the various `typeidx` type constructors
276275
to match the preceding `sort`.
277276
* (The `0x00` immediate of `case` may be reinterpreted in the future as the
@@ -386,8 +385,8 @@ Notes:
386385
of the inferred `externdesc` of the `sortidx`.
387386
* `<importname>` and `<exportname>` refer to the productions defined in the
388387
[text format](Explainer.md#import-and-export-definitions).
389-
* The `<importname>`s of a component must be unique and the `<exportname>`s of
390-
a component must be unique as well (defined in terms of raw string equality).
388+
* The `<importname>`s of a component must all be [strongly-unique]. Separately,
389+
the `<exportname>`s of a component must also all be [strongly-unique].
391390
* Validation requires that annotated `plainname`s only occur on `func` imports
392391
or exports and that the first label of a `[constructor]`, `[method]` or
393392
`[static]` matches the `plainname` of a preceding `resource` import or
@@ -397,8 +396,6 @@ Notes:
397396
`(result (own $R))`, where `$R` is the resource labeled `r`.
398397
* Validation of `[method]` names requires the first parameter of the function
399398
to be `(param "self" (borrow $R))`, where `$R` is the resource labeled `r`.
400-
* Validation of `[method]` and `[static]` names ensures that all field names
401-
are disjoint.
402399
* `<valid semver>` is as defined by [https://semver.org](https://semver.org/)
403400
* `<integrity-metadata>` is as defined by the
404401
[SRI](https://www.w3.org/TR/SRI/#dfn-integrity-metadata) spec.
@@ -517,6 +514,8 @@ named once.
517514
[`core:functype`]: https://webassembly.github.io/spec/core/binary/types.html#binary-functype
518515
[`core:rectype]: https://webassembly.github.io/gc/core/binary/types.html#recursive-types
519516

517+
[Strongly-unique]: Explainer.md#name-uniqueness
518+
520519
[type-imports]: https://github.com/WebAssembly/proposal-type-imports/blob/master/proposals/type-imports/Overview.md
521520
[module-linking]: https://github.com/WebAssembly/module-linking/blob/main/proposals/module-linking/Explainer.md
522521

design/mvp/Explainer.md

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ more user-focused explanation, take a look at the
3232
* [Value definitions](#-value-definitions)
3333
* [Start definitions](#-start-definitions)
3434
* [Import and export definitions](#import-and-export-definitions)
35+
* [Name uniqueness](#name-uniqueness)
3536
* [Component invariants](#component-invariants)
3637
* [JavaScript embedding](#JavaScript-embedding)
3738
* [JS API](#JS-API)
@@ -782,8 +783,8 @@ The remaining 4 type constructors in `deftype` use `valtype` to describe
782783
shared-nothing functions, resources, components, and component instances:
783784

784785
The `func` type constructor describes a component-level function definition
785-
that takes a list of uniquely-named `valtype` parameters and optionally returns
786-
a `valtype`.
786+
that takes a list of `valtype` parameters with [strongly-unique] names and
787+
optionally returns a `valtype`.
787788

788789
The `resource` type constructor creates a fresh type for each instance of the
789790
containing component (with "freshness" and its interaction with general
@@ -2191,16 +2192,17 @@ new identifier `$x`).
21912192
import ::= (import "<importname>" bind-id(<externdesc>))
21922193
export ::= (export <id>? "<exportname>" <sortidx> <externdesc>?)
21932194
```
2194-
All import names are required to be unique and all export names are required to
2195-
be unique. The rest of the grammar for imports and exports defines a structured
2196-
syntax for the contents of import and export names. Syntactically, these names
2197-
appear inside quoted string literals. The grammar thus restricts the contents
2198-
of these string literals to provide more structured information that can be
2199-
mechanically interpreted by toolchains and runtimes to support idiomatic
2200-
developer workflows and source-language bindings. The rules defining this
2201-
structured name syntax below are to be interpreted as a *lexical* grammar
2202-
defining a single token and thus whitespace is not automatically inserted, all
2203-
terminals are single-quoted, and everything unquoted is a meta-character.
2195+
All import names are required to be [strongly-unique]. Separately, all export
2196+
names are also required to be [strongly-unique]. The rest of the grammar for
2197+
imports and exports defines a structured syntax for the contents of import and
2198+
export names. Syntactically, these names appear inside quoted string literals.
2199+
The grammar thus restricts the contents of these string literals to provide
2200+
more structured information that can be mechanically interpreted by toolchains
2201+
and runtimes to support idiomatic developer workflows and source-language
2202+
bindings. The rules defining this structured name syntax below are to be
2203+
interpreted as a *lexical* grammar defining a single token and thus whitespace
2204+
is not automatically inserted, all terminals are single-quoted, and everything
2205+
unquoted is a meta-character.
22042206
```ebnf
22052207
exportname ::= <plainname>
22062208
| <interfacename>
@@ -2358,12 +2360,6 @@ mapped to `isXML`, `IsXml`, `is_XML` or `is_xml`, depending on the target
23582360
language/convention. The highly-restricted character set ensures that
23592361
capitalization is trivial and does not require consulting Unicode tables.
23602362

2361-
Because some casing schemes (such as all-lowercase) would lead to clashes if
2362-
two `label`s differed only in case, in all cases where "uniqueness" is required
2363-
between a set of names (viz., import/export names, record field labels, variant
2364-
case labels, and function parameter/result names), two `label`s that differ
2365-
only in case are considered equal and thus rejected.
2366-
23672363
Components provide two options for naming exports, symmetric to the first two
23682364
options for naming imports:
23692365
* a **plain name** that leaves it up to the developer to "read the docs"
@@ -2455,6 +2451,39 @@ The inferred type of this component is:
24552451

24562452
Note, that the `url` value definition is absent from the component type
24572453

2454+
### Name Uniqueness
2455+
2456+
The goal of the `label`, `exportname` and `importname` productions defined and
2457+
used above is to allow automated bindings generators to map these names into
2458+
something more idiomatic to the language. For example, the `plainname`
2459+
`[method]my-resource.my-method` might get mapped to a method named `myMethod`
2460+
nested inside a class `MyResource`. To unburden bindings generators from having
2461+
to consider pathological cases where two unique-in-the-component names get
2462+
mapped to the same source-language identifier, Component Model validation
2463+
imposes a stronger form of uniquness than simple string equality on all the
2464+
names that appear within the same scope.
2465+
2466+
To determine whether two names (defined as sequences of [Unicode Scalar
2467+
Values]) are **strongly-unique**:
2468+
* If one name is `l` and the other name is `[constructor]l` (for the same
2469+
`label` `l`), they are strongly-unique.
2470+
* Otherwise:
2471+
* Lowercase all the `acronym`s (uppercase letters) in both names.
2472+
* Strip any `[...]` annotation prefix from both names.
2473+
* The names are strongly-unique if the resulting strings are unequal.
2474+
2475+
Thus, the following names are strongly-unique:
2476+
* `foo`, `foo-bar`, `[constructor]foo`, `[method]foo.bar`, `[method]foo.baz`
2477+
2478+
but attempting to add *any* of the following names would be a validation error:
2479+
* `foo`, `foo-BAR`, `[constructor]foo-BAR`, `[async]foo`, `[method]foo.BAR`
2480+
2481+
Note that additional validation rules involving types apply to names with
2482+
annotations. For example, the validation rules for `[constructor]foo` require
2483+
`foo` to be a resource type. See [Binary.md](Binary.md#import-and-export-definitions)
2484+
for details.
2485+
2486+
24582487
## Component Invariants
24592488

24602489
As a consequence of the shared-nothing design described above, all calls into
@@ -2812,6 +2841,8 @@ For some use-case-focused, worked examples, see:
28122841
[WASI Preview 2]: https://github.com/WebAssembly/WASI/tree/main/wasip2#readme
28132842
[reference types]: https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md
28142843

2844+
[Strongly-unique]: #name-uniqueness
2845+
28152846
[Adapter Functions]: FutureFeatures.md#custom-abis-via-adapter-functions
28162847
[Canonical ABI explainer]: CanonicalABI.md
28172848
[`canon_context_get`]: CanonicalABI.md#-canon-contextget

0 commit comments

Comments
 (0)