Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit 1a58101

Browse files
authored
Add nullref (#295)
1 parent fbfd373 commit 1a58101

File tree

11 files changed

+62
-22
lines changed

11 files changed

+62
-22
lines changed

interpreter/binary/decode.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ let heap_type s =
178178
| -0x18 -> RttHeapType (var_type s)
179179
| -0x19 -> DataHeapType
180180
| -0x1a -> ArrayHeapType
181+
| -0x1b -> NoneHeapType
181182
| _ -> error s pos "malformed heap type"
182183
)
183184
| _ ->
@@ -197,6 +198,7 @@ let ref_type s =
197198
| -0x18 -> (NonNullable, RttHeapType (var_type s))
198199
| -0x19 -> (Nullable, DataHeapType)
199200
| -0x1a -> (Nullable, ArrayHeapType)
201+
| -0x1b -> (Nullable, NoneHeapType)
200202
| _ -> error s pos "malformed reference type"
201203

202204
let value_type s =

interpreter/binary/encode.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ struct
110110
| V128Type -> vs7 (-0x05)
111111

112112
let heap_type = function
113+
| NoneHeapType -> vs7 (-0x1b)
113114
| AnyHeapType -> vs7 (-0x11)
114115
| EqHeapType -> vs7 (-0x13)
115116
| I31HeapType -> vs7 (-0x16)
@@ -118,9 +119,9 @@ struct
118119
| FuncHeapType -> vs7 (-0x10)
119120
| DefHeapType x -> var_type vs33 x
120121
| RttHeapType x -> vs7 (-0x18); var_type vu32 x
121-
| BotHeapType -> assert false
122122

123123
let ref_type = function
124+
| (Nullable, NoneHeapType) -> vs7 (-0x1b)
124125
| (Nullable, AnyHeapType) -> vs7 (-0x11)
125126
| (Nullable, EqHeapType) -> vs7 (-0x13)
126127
| (Nullable, I31HeapType) -> vs7 (-0x16)

interpreter/script/js.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ let assert_return ress ts at =
382382
| RefResult (RefTypePat t) ->
383383
let is_ref =
384384
match t with
385+
| NoneHeapType -> Const (I32 0l @@ at)
385386
| AnyHeapType -> Const (I32 1l @@ at)
386387
| EqHeapType -> Call (is_eqref_idx @@ at)
387388
| I31HeapType -> RefTest I31Op
@@ -390,7 +391,6 @@ let assert_return ress ts at =
390391
| FuncHeapType -> RefTest FuncOp
391392
| DefHeapType _ -> Const (I32 1l @@ at) (* TODO *)
392393
| RttHeapType _ -> Const (I32 1l @@ at) (* TODO *)
393-
| BotHeapType -> assert false
394394
in
395395
[ is_ref @@ at;
396396
Test (I32 I32Op.Eqz) @@ at;

interpreter/syntax/free.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ let vec_type = function
7373
| V128Type -> empty
7474

7575
let heap_type = function
76-
| AnyHeapType | EqHeapType | I31HeapType | DataHeapType | ArrayHeapType
77-
| FuncHeapType | BotHeapType -> empty
76+
| NoneHeapType | AnyHeapType | EqHeapType
77+
| I31HeapType | DataHeapType | ArrayHeapType | FuncHeapType -> empty
7878
| DefHeapType x | RttHeapType x -> var_type x
7979

8080
let ref_type = function

interpreter/syntax/types.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ and num_type = I32Type | I64Type | F32Type | F64Type
1515
and vec_type = V128Type
1616
and ref_type = nullability * heap_type
1717
and heap_type =
18+
| NoneHeapType
1819
| AnyHeapType
1920
| EqHeapType
2021
| I31HeapType
@@ -23,7 +24,6 @@ and heap_type =
2324
| FuncHeapType
2425
| DefHeapType of var
2526
| RttHeapType of var
26-
| BotHeapType
2727
and value_type =
2828
NumType of num_type | VecType of vec_type | RefType of ref_type | BotType
2929

@@ -196,6 +196,7 @@ let subst_num_type s t = t
196196
let subst_vec_type s t = t
197197

198198
let subst_heap_type s = function
199+
| NoneHeapType -> NoneHeapType
199200
| AnyHeapType -> AnyHeapType
200201
| EqHeapType -> EqHeapType
201202
| I31HeapType -> I31HeapType
@@ -204,7 +205,6 @@ let subst_heap_type s = function
204205
| FuncHeapType -> FuncHeapType
205206
| DefHeapType x -> DefHeapType (s x)
206207
| RttHeapType x -> RttHeapType (s x)
207-
| BotHeapType -> BotHeapType
208208

209209
let subst_ref_type s = function
210210
| (nul, t) -> (nul, subst_heap_type s t)
@@ -381,6 +381,7 @@ and string_of_vec_type = function
381381
| V128Type -> "v128"
382382

383383
and string_of_heap_type = function
384+
| NoneHeapType -> "none"
384385
| AnyHeapType -> "any"
385386
| EqHeapType -> "eq"
386387
| I31HeapType -> "i31"
@@ -389,7 +390,6 @@ and string_of_heap_type = function
389390
| FuncHeapType -> "func"
390391
| DefHeapType x -> string_of_var x
391392
| RttHeapType x -> "(rtt " ^ string_of_var x ^ ")"
392-
| BotHeapType -> "something"
393393

394394
and string_of_ref_type = function
395395
| (nul, t) ->

interpreter/text/lexer.mll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ rule token = parse
220220
| "ref" { REF }
221221
| "rtt" { RTT }
222222
| "null" { NULL }
223+
| "none" { NONE }
224+
| "nullref" { NULLREF }
223225
| "any" { ANY }
224226
| "anyref" { ANYREF }
225227
| "eq" { EQ }

interpreter/text/parser.mly

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,8 @@ let inline_func_type_explicit (c : context) x ft at =
256256
%token LPAR RPAR
257257
%token NAT INT FLOAT STRING VAR
258258
%token NUM_TYPE PACKED_TYPE VEC_TYPE VEC_SHAPE
259-
%token ANYREF EQREF I31REF DATAREF ARRAYREF FUNCREF EXTERNREF
260-
%token ANY EQ I31 DATA REF RTT EXTERN NULL
259+
%token NULLREF ANYREF EQREF I31REF DATAREF ARRAYREF FUNCREF EXTERNREF
260+
%token NONE ANY EQ I31 DATA REF RTT EXTERN NULL
261261
%token MUT FIELD STRUCT ARRAY SUB REC
262262
%token UNREACHABLE NOP DROP SELECT
263263
%token BLOCK END IF THEN ELSE LOOP LET
@@ -359,6 +359,7 @@ null_opt :
359359
| NULL { Nullable }
360360

361361
heap_type :
362+
| NONE { fun c -> NoneHeapType }
362363
| ANY { fun c -> AnyHeapType }
363364
| EQ { fun c -> EqHeapType }
364365
| I31 { fun c -> I31HeapType }
@@ -371,6 +372,7 @@ heap_type :
371372

372373
ref_type :
373374
| LPAR REF null_opt heap_type RPAR { fun c -> ($3, $4 c) }
375+
| NULLREF { fun c -> (Nullable, NoneHeapType) } /* Sugar */
374376
| ANYREF { fun c -> (Nullable, AnyHeapType) } /* Sugar */
375377
| EQREF { fun c -> (Nullable, EqHeapType) } /* Sugar */
376378
| I31REF { fun c -> (Nullable, I31HeapType) } /* Sugar */

interpreter/valid/match.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ and match_vec_type c t1 t2 =
154154

155155
and match_heap_type c t1 t2 =
156156
match t1, t2 with
157+
| NoneHeapType, _ -> true
157158
| _, AnyHeapType -> true
158159
| I31HeapType, EqHeapType -> true
159160
| DataHeapType, EqHeapType -> true
@@ -181,7 +182,6 @@ and match_heap_type c t1 t2 =
181182
| _ -> false
182183
)
183184
| DefHeapType x1, DefHeapType x2 -> match_var_type c x1 x2
184-
| BotHeapType, _ -> true
185185
| _, _ -> eq_heap_type c t1 t2
186186

187187
and match_ref_type c t1 t2 =

interpreter/valid/valid.ml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ let check_vec_type (c : context) (t : vec_type) at =
9393

9494
let check_heap_type (c : context) (t : heap_type) at =
9595
match t with
96-
| AnyHeapType | EqHeapType | I31HeapType | DataHeapType | ArrayHeapType
97-
| FuncHeapType -> ()
96+
| NoneHeapType | AnyHeapType | EqHeapType
97+
| I31HeapType | DataHeapType | ArrayHeapType | FuncHeapType -> ()
9898
| DefHeapType (SynVar x) -> ignore (type_ c (x @@ at))
9999
| RttHeapType (SynVar x) -> ignore (type_ c (x @@ at))
100-
| DefHeapType _ | RttHeapType _ | BotHeapType -> assert false
100+
| DefHeapType _ | RttHeapType _ -> assert false
101101

102102
let check_ref_type (c : context) (t : ref_type) at =
103103
match t with
@@ -227,7 +227,7 @@ let peek i (ell, ts) =
227227
let peek_ref i (ell, ts) at =
228228
match peek i (ell, ts) with
229229
| RefType rt -> rt
230-
| BotType -> (NonNullable, BotHeapType)
230+
| BotType -> (NonNullable, NoneHeapType)
231231
| t ->
232232
error at
233233
("type mismatch: instruction requires reference type" ^
@@ -237,7 +237,7 @@ let peek_rtt i s at =
237237
let rt = peek_ref i s at in
238238
match rt with
239239
| _, RttHeapType x -> rt, DefHeapType x
240-
| _, BotHeapType -> rt, BotHeapType
240+
| _, NoneHeapType -> rt, NoneHeapType
241241
| _ ->
242242
error at
243243
("type mismatch: instruction requires RTT reference type" ^
@@ -538,7 +538,7 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type
538538
| (nul, DefHeapType (SynVar x)) ->
539539
let FuncType (ts1, ts2) = func_type c (x @@ e.at) in
540540
(ts1 @ [RefType (nul, DefHeapType (SynVar x))]) --> ts2
541-
| (_, BotHeapType) as rt ->
541+
| (_, NoneHeapType) as rt ->
542542
[RefType rt] -->... []
543543
| rt ->
544544
error e.at
@@ -563,7 +563,7 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type
563563
string_of_result_type c.results ^
564564
" but callee returns " ^ string_of_result_type ts2);
565565
(ts1 @ [RefType (nul, DefHeapType (SynVar x))]) -->... []
566-
| (_, BotHeapType) as rt ->
566+
| (_, NoneHeapType) as rt ->
567567
[RefType rt] -->... []
568568
| rt ->
569569
error e.at
@@ -583,7 +583,7 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type
583583
"type mismatch in function type";
584584
(ts11 @ [RefType (nul, DefHeapType (SynVar y))]) -->
585585
[RefType (NonNullable, DefHeapType (SynVar x.it))]
586-
| (_, BotHeapType) as rt ->
586+
| (_, NoneHeapType) as rt ->
587587
[RefType rt] -->.. [RefType (NonNullable, DefHeapType (SynVar x.it))]
588588
| rt ->
589589
error e.at

proposals/gc/MVP.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ Both proposals are prerequisites.
4949
- `heaptype ::= ... | rtt <typeidx>`
5050
- `rtt t ok` iff `t ok`
5151

52+
* `none` is a new heap type
53+
- `heaptype ::= ... | none`
54+
- the common subtype of all referenceable types (a.k.a. the bottom heap type)
55+
5256
* `extern` is renamed back to `any`
5357
- the common supertype of all referenceable types
5458
- the name `extern` is kept as an alias in the text format for backwards compatibility
@@ -79,6 +83,9 @@ New abbreviations are introduced for reference types in binary and text format,
7983
* `rtt <typeidx>` is a new reference type
8084
- `(rtt $t) == (ref (rtt $t))`
8185

86+
* `nullref` is a new reference type
87+
- `nullref == (ref null none)`
88+
8289
* `externref` is renamed to `anyref`
8390
- `anyref == (ref null any)`
8491
- the name `externref` is kept as an alias in the text format for backwards compatibility
@@ -304,6 +311,9 @@ In addition to the [existing rules](https://github.com/WebAssembly/function-refe
304311
* every type is a subtype of `any`
305312
- `t <: any`
306313

314+
* every type is a supertype of `none`
315+
- `none <: t`
316+
307317
* `dataref` is a subtype of `eqref`
308318
- `data <: eq`
309319
- TODO: provide a way to make data types non-eq, especially immutable ones?
@@ -339,7 +349,8 @@ i31 data
339349
array
340350
```
341351
All *concrete* heap types (of the form `(type $t)`) are situated below either `data` or `func`.
342-
RTTs are below `eq`.
352+
Not shown in the graph are RTTs, which are below `eq`,
353+
and `none` which is below every other "leaf" type.
343354

344355
In addition, a host environment may introduce additional inhabitants of type `any`
345356
that are are in neither of the above three leaf type categories.
@@ -716,6 +727,7 @@ This extends the [encodings](https://github.com/WebAssembly/function-references/
716727
| -0x18 | `(rtt $t)` | `$t : typeidx` | shorthand |
717728
| -0x19 | `dataref` | | shorthand |
718729
| -0x1a | `arrayref` | | shorthand |
730+
| -0x1b | `nullref` | | shorthand |
719731

720732
#### Heap Types
721733

@@ -731,6 +743,7 @@ The opcode for heap types is encoded as an `s33`.
731743
| -0x18 | `(rtt $t)` | `$t : typeidx` | |
732744
| -0x19 | `data` | | |
733745
| -0x1a | `array` | | |
746+
| -0x1b | `none` | | |
734747

735748
#### Structured Types
736749

0 commit comments

Comments
 (0)