Skip to content

Commit d6ed94a

Browse files
authored
Merge pull request #129 from WebAssembly/add-resource-types
Add resource, own and borrow types
2 parents c9e383d + e2cfe7b commit d6ed94a

File tree

7 files changed

+1229
-109
lines changed

7 files changed

+1229
-109
lines changed

design/mvp/Binary.md

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,12 @@ sort ::= 0x00 cs:<core:sort> => co
8080
| 0x05 => instance
8181
inlineexport ::= n:<name> si:<sortidx> => (export n si)
8282
name ::= len:<u32> n:<name-chars> => n (if len = |n|)
83-
name-chars ::= w:<word> => w
84-
| n:<name> 0x2d w:<word> => n-w
83+
name-chars ::= l:<label> => l
84+
| '[constructor]' r:<label> => [constructor]r
85+
| '[method]' r:<label> '.' m:<label> => [method]r.m
86+
| '[static]' r:<label> '.' s:<label> => [static]r.s
87+
label ::= w:<word> => w
88+
| l:<label> '-' w:<word> => l-w
8589
word ::= w:[0x61-0x7a] x*:[0x30-0x39,0x61-0x7a]* => char(w)char(x)*
8690
| W:[0x41-0x5a] X*:[0x30-0x39,0x41-0x5a]* => char(W)char(X)*
8791
```
@@ -99,8 +103,21 @@ Notes:
99103
sort, but would be extended to accept other sorts as core wasm is extended.
100104
* Validation of `instantiate` requires that `name` is present in an
101105
`externname` of `c` (with a matching type).
106+
* When validating `instantiate`, after each individual type-import is supplied
107+
via `with`, the actual type supplied is immediately substituted for all uses
108+
of the import, so that subsequent imports and all exports are now specialized
109+
to the actual type.
102110
* The indices in `sortidx` are validated according to their `sort`'s index
103111
spaces, which are built incrementally as each definition is validated.
112+
* Validation requires that all annotated `name`s only occur on `func` `export`s
113+
and that the `r` `label` matches the `name` of a preceding `resource` export.
114+
* Validation of `[constructor]` names requires that the `func` returns a
115+
`(result (own $R))`, where `$R` is the resource labeled `r`.
116+
* Validation of `[method]` names requires the first parameter of the function
117+
to be `(param "self" (borrow $R))`, where `$R` is the resource labeled `r`.
118+
* Validation of `[method]` and `[static]` names ensures that all field names
119+
are disjoint.
120+
104121

105122
## Alias Definitions
106123

@@ -120,7 +137,8 @@ Notes:
120137
index in the `sort` index space of the `i`th enclosing component (counting
121138
outward, starting with `0` referring to the current component).
122139
* For `outer` aliases, validation restricts the `sort` to one
123-
of `type`, `module` or `component`.
140+
of `type`, `module` or `component` and additionally requires that the
141+
outer-aliased type is not a `resource` type (which is generative).
124142

125143

126144
## Type Definitions
@@ -174,25 +192,28 @@ primvaltype ::= 0x7f => bool
174192
| 0x74 => char
175193
| 0x73 => string
176194
defvaltype ::= pvt:<primvaltype> => pvt
177-
| 0x72 nt*:vec(<namedvaltype>) => (record (field nt)*)
195+
| 0x72 lt*:vec(<labelvaltype>) => (record (field lt)*)
178196
| 0x71 case*:vec(<case>) => (variant case*)
179197
| 0x70 t:<valtype> => (list t)
180198
| 0x6f t*:vec(<valtype>) => (tuple t*)
181-
| 0x6e n*:vec(<name>) => (flags n*)
182-
| 0x6d n*:vec(<name>) => (enum n*)
199+
| 0x6e l*:vec(<label>) => (flags l*)
200+
| 0x6d l*:vec(<label>) => (enum l*)
183201
| 0x6c t*:vec(<valtype>) => (union t*)
184202
| 0x6b t:<valtype> => (option t)
185203
| 0x6a t?:<valtype>? u?:<valtype>? => (result t? (error u)?)
186-
namedvaltype ::= n:<name> t:<valtype> => n t
187-
case ::= n:<name> t?:<valtype>? r?:<u32>? => (case n t? (refines case-label[r])?)
204+
| 0x69 i:<typeidx> => (own i)
205+
| 0x68 i:<typeidx> => (borrow i)
206+
labelvaltype ::= l:<label> t:<valtype> => l t
207+
case ::= l:<label> t?:<valtype>? r?:<u32>? => (case l t? (refines case-label[r])?)
188208
<T>? ::= 0x00 =>
189209
| 0x01 t:<T> => t
190210
valtype ::= i:<typeidx> => i
191211
| pvt:<primvaltype> => pvt
212+
resourcetype ::= 0x3f 0x7f f?:<funcidx>? => (resource (rep i32) (dtor f)?)
192213
functype ::= 0x40 ps:<paramlist> rs:<resultlist> => (func ps rs)
193-
paramlist ::= nt*:vec(<namedvaltype>) => (param nt)*
214+
paramlist ::= lt*:vec(<labelvaltype>) => (param lt)*
194215
resultlist ::= 0x00 t:<valtype> => (result t)
195-
| 0x01 nt*:vec(<namedvaltype>) => (result nt)*
216+
| 0x01 lt*:vec(<labelvaltype>) => (result lt)*
196217
componenttype ::= 0x41 cd*:vec(<componentdecl>) => (component cd*)
197218
instancetype ::= 0x42 id*:vec(<instancedecl>) => (instance id*)
198219
componentdecl ::= 0x03 id:<importdecl> => id
@@ -210,17 +231,37 @@ externdesc ::= 0x00 0x11 i:<core:typeidx> => (core module (type
210231
| 0x04 i:<typeidx> => (instance (type i))
211232
| 0x05 i:<typeidx> => (component (type i))
212233
typebound ::= 0x00 i:<typeidx> => (eq i)
234+
| 0x01 => (sub resource)
213235
```
214236
Notes:
215237
* The type opcodes follow the same negative-SLEB128 scheme as Core WebAssembly,
216238
with type opcodes starting at SLEB128(-1) (`0x7f`) and going down,
217239
reserving the nonnegative SLEB128s for type indices.
218240
* Validation of `valtype` requires the `typeidx` to refer to a `defvaltype`.
219-
* Validation of `instancedecl` (currently) only allows `outer` `type` `alias`
220-
declarators.
241+
* Validation of `own` and `borrow` requires the `typeidx` to refer to a
242+
resource type.
243+
* Validation only allows `borrow` to be used inside the `param` of a `functype`.
244+
(This is likely to change in a future PR, converting `functype` into a
245+
compound type constructor analogous to `moduletype` and `componenttype` and
246+
using scoping to enforce this constraint instead.)
247+
* Validation of `resourcetype` requires the destructor (if present) to have
248+
type `[i32] -> []`.
249+
* Validation of `instancedecl` (currently) only allows the `type` and
250+
`instance` sorts in `alias` declarators.
221251
* As described in the explainer, each component and instance type is validated
222252
with an initially-empty type index space. Outer aliases can be used to pull
223253
in type definitions from containing components.
254+
* `exportdecl` introduces a new type index that can be used by subsequent type
255+
definitions. In the `(eq i)` case, the new type index is effectively an alias
256+
to type `i`. In the `(sub resource)` case, the new type index refers to a
257+
*fresh* abstract type unequal to every existing type in all existing type
258+
index spaces. (Note: *subsequent* aliases can introduce new type indices
259+
equivalent to this fresh type.)
260+
* Validation rejects `resourcetype` type definitions inside `componenttype` and
261+
`instancettype`. Thus, handle types inside a `componenttype` can only refer
262+
to resource types that are imported or exported.
263+
* Validation requires that all resource types transitively used in the type of an
264+
export are introduced by a preceding `exportdecl`.
224265
* The uniqueness validation rules for `externname` described below are also
225266
applied at the instance- and component-type level.
226267
* Validation of `externdesc` requires the various `typeidx` type constructors
@@ -239,6 +280,9 @@ Notes:
239280
```
240281
canon ::= 0x00 0x00 f:<core:funcidx> opts:<opts> ft:<typeidx> => (canon lift f opts type-index-space[ft])
241282
| 0x01 0x00 f:<funcidx> opts:<opts> => (canon lower f opts (core func))
283+
| 0x02 t:<typeidx> => (canon resource.new t (core func))
284+
| 0x03 t:<valtype> => (canon resource.drop t (core func))
285+
| 0x04 t:<typeidx> => (canon resource.rep t (core func))
242286
opts ::= opt*:vec(<canonopt>) => opt*
243287
canonopt ::= 0x00 => string-encoding=utf8
244288
| 0x01 => string-encoding=utf16
@@ -251,20 +295,8 @@ Notes:
251295
* The second `0x00` byte in `canon` stands for the `func` sort and thus the
252296
`0x00 <u32>` pair standards for a `func` `sortidx` or `core:sortidx`.
253297
* Validation prevents duplicate or conflicting `canonopt`.
254-
* Validation of `canon lift` requires `f` to have type `flatten(ft)` (defined
255-
by the [Canonical ABI](CanonicalABI.md#flattening)). The function being
256-
defined is given type `ft`.
257-
* Validation of `canon lower` requires `f` to be a component function. The
258-
function being defined is given core function type `flatten(ft)` where `ft`
259-
is the `functype` of `f`.
260-
* If the lifting/lowering operations implied by `lift` or `lower` require
261-
access to `memory` or `realloc`, then validation requires these options to be
262-
present. If present, `realloc` must have core type
263-
`(func (param i32 i32 i32 i32) (result i32))`.
264-
* The `post-return` option is only valid for `canon lift` and it is always
265-
optional; if present, it must have core type `(func (param ...))` where the
266-
number and types of the parameters must match the results of the core function
267-
being lifted and itself have no result values.
298+
* Validation of the individual canonical definitions is described in
299+
[`CanonicalABI.md`](CanonicalABI.md#canonical-definitions).
268300

269301

270302
## Start Definitions
@@ -300,6 +332,10 @@ externname ::= n:<name> u?:<URL>? => n u?
300332
URL ::= b*:vec(byte) => char(b)*, if char(b)* parses as a URL
301333
```
302334
Notes:
335+
* All exports (of all `sort`s) introduce a new index that aliases the exported
336+
definition and can be used by all subsequent definitions just like an alias.
337+
* Validation requires that all resource types transitively used in the type of an
338+
export are introduced by a preceding `exportdecl`.
303339
* The "parses as a URL" condition is defined by executing the [basic URL
304340
parser] with `char(b)*` as *input*, no optional parameters and non-fatal
305341
validation errors (which coincides with definition of `URL` in JS and `rust-url`).

0 commit comments

Comments
 (0)