Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

Commit

Permalink
Simplify heaptype syntax (WebAssembly#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
rossberg authored Jul 23, 2020
1 parent a125cbb commit f83fc6c
Show file tree
Hide file tree
Showing 13 changed files with 37 additions and 42 deletions.
2 changes: 1 addition & 1 deletion interpreter/syntax/types.ml
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ and string_of_num_type = function
and string_of_heap_type = function
| FuncHeapType -> "func"
| ExternHeapType -> "extern"
| DefHeapType x -> "(type " ^ string_of_var x ^ ")"
| DefHeapType x -> string_of_var x
| BotHeapType -> "unreachable"

and string_of_ref_type = function
Expand Down
4 changes: 1 addition & 3 deletions interpreter/text/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,10 @@ null_opt :
heap_type :
| FUNC { fun c -> FuncHeapType }
| EXTERN { fun c -> ExternHeapType }
| LPAR TYPE var RPAR { fun c -> DefHeapType (SynVar ($3 c type_).it) }
| var { fun c -> DefHeapType (SynVar ($1 c type_).it) }

ref_type :
| LPAR REF null_opt heap_type RPAR { fun c -> ($3, $4 c) }
| LPAR REF null_opt var RPAR /* Sugar */
{ fun c -> ($3, DefHeapType (SynVar ($4 c type_).it)) }
| FUNCREF { fun c -> (Nullable, FuncHeapType) } /* Sugar */
| EXTERNREF { fun c -> (Nullable, ExternHeapType) } /* Sugar */

Expand Down
17 changes: 8 additions & 9 deletions proposals/function-references/Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ Based on [reference types proposal](https://github.com/WebAssembly/reference-typ

A *heap type* denotes a user-defined or pre-defined data type that is not a primitive scalar:

* `heaptype ::= (type <typeidx>) | func | extern`
- `(type $t) ok` iff `$t` is defined in the context
* `heaptype ::= <typeidx> | func | extern`
- `$t ok` iff `$t` is defined in the context
- `func ok` and `extern ok`, always

* In the binary encoding,
Expand All @@ -144,7 +144,6 @@ A *reference type* denotes the type of a reference to some data. It may either i
* Reference types now *all* take the form `ref null? <heaptype>`
- `funcref` and `externref` are reinterpreted as abbreviations (in both binary and text format) for `(ref null func)` and `(ref null extern)`, respectively
- Note: this refactoring allows using `func` and `extern` as heap types, which is relevant for future extensions such as [type imports](https://github.com/WebAssembly/proposal-type-imports/proposals/type-imports/Overview.md)
- `(ref null? (type $t))` can be abbreviated to `(ref null? $t)` in the text format

* In the binary encoding,
- null and non-null variant are distinguished by two new (negative) type opcodes
Expand Down Expand Up @@ -172,7 +171,7 @@ The following rules, now defined in terms of heap types, replace and extend the
##### Constructed Types

* Any function type is a subtype of `func`
- `(type $t) <: func`
- `$t <: func`
- iff `$t = <functype>`

* Note: Function types themselves are invariant for now. This may be relaxed in future extensions.
Expand Down Expand Up @@ -286,7 +285,7 @@ The opcode for heap types is encoded as an `s33`.

| Opcode | Type | Parameters |
| ------ | --------------- | ---------- |
| i >= 0 | `(type i)` | |
| i >= 0 | i | |
| -0x10 | `func` | |
| -0x11 | `extern` | |

Expand Down Expand Up @@ -368,17 +367,17 @@ The latter are sometimes called _exact_ types.
Exact types might come in handy in a few other circumstances,
so we could distinguish the two forms in a generic manner by enriching heap types with a flag as follows:

* `heaptype ::= (type exact? <typeidx>) | func | extern`
* `heaptype ::= exact? <typeidx> | func | extern`

Exact types are themselves subtypes of corresponding non-exact types,
but the crucial difference is that they do not have further subtypes themselves.
That is, the following subtype rules would be defined on heap types:

* `(type exact? $t) <: (type $t')`
* `exact? $t <: $t'`
- iff `$t = <functype>` and `$t' = <functype'>`
- and `<functype> <: <functype'>`

* `(type exact $t) <: (type exact $t')`
* `exact $t <: exact $t'`
- iff `$t = <functype>` and `$t' = <functype'>`
- and `<functype> == <functype'>`

Expand Down Expand Up @@ -483,7 +482,7 @@ It's a slightly different question what to do for the text format, however.
To maintain full backwards compatibility, the flag would likewise need to be inverted:
instead of an optional `exact` flag we'd have an optional `sub` flag with the opposite meaning:

* `heaptype ::= (type sub? <typeidx>) | func | extern`
* `heaptype ::= sub? <typeidx> | func | extern`

In the binary format it doesn't really matter which way both alternatives are encoded.
But for the text format, this inversion will be rather annoying:
Expand Down
8 changes: 4 additions & 4 deletions test/core/br_on_null.wast
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
(elem func $f)
(func $f (result i32) (i32.const 7))

(func (export "nullable-null") (result i32) (call $n (ref.null (type $t))))
(func (export "nullable-null") (result i32) (call $n (ref.null $t)))
(func (export "nonnullable-f") (result i32) (call $nn (ref.func $f)))
(func (export "nullable-f") (result i32) (call $n (ref.func $f)))

Expand All @@ -39,7 +39,7 @@
(module
(type $t (func (result i32)))
(func $g (param $r (ref $t)) (drop (br_on_null 0 (local.get $r))))
(func (call $g (ref.null (type $t))))
(func (call $g (ref.null $t)))
)
"type mismatch"
)
Expand All @@ -57,14 +57,14 @@
(elem func $f)
(func $f (param i32) (result i32) (i32.mul (local.get 0) (local.get 0)))

(func $a (param $n i32) (param $r (ref null (type $t))) (result i32)
(func $a (param $n i32) (param $r (ref null $t)) (result i32)
(block $l (result i32)
(return (call_ref (br_on_null $l (local.get $n) (local.get $r))))
)
)

(func (export "args-null") (param $n i32) (result i32)
(call $a (local.get $n) (ref.null (type $t)))
(call $a (local.get $n) (ref.null $t))
)
(func (export "args-f") (param $n i32) (result i32)
(call $a (local.get $n) (ref.func $f))
Expand Down
2 changes: 1 addition & 1 deletion test/core/br_table.wast
Original file line number Diff line number Diff line change
Expand Up @@ -1286,7 +1286,7 @@
(func (export "meet-nullref") (param i32) (result (ref null func))
(block $l1 (result (ref null func))
(block $l2 (result (ref null $t))
(br_table $l1 $l2 $l1 (ref.null (type $t)) (local.get 0))
(br_table $l1 $l2 $l1 (ref.null $t) (local.get 0))
)
)
)
Expand Down
2 changes: 1 addition & 1 deletion test/core/call_ref.wast
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
)

(func (export "null") (result i32)
(call_ref (i32.const 1) (ref.null (type $ii)))
(call_ref (i32.const 1) (ref.null $ii))
)

;; Recursion
Expand Down
18 changes: 9 additions & 9 deletions test/core/func_bind.wast
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
(func.bind (type $unop) (local.get $i) (ref.func $add))
)

(global $f (mut (ref null $unop)) (ref.null (type $unop)))
(global $f (mut (ref null $unop)) (ref.null $unop))

(func (export "make") (param $i i32)
(global.set $f (call $mk-adder (local.get $i)))
Expand All @@ -29,7 +29,7 @@
)

(func (export "null") (result i32)
(func.bind (type $unop) (i32.const 1) (ref.null (type $unop)))
(func.bind (type $unop) (i32.const 1) (ref.null $unop))
(drop)
)
)
Expand Down Expand Up @@ -350,10 +350,10 @@
(i32.add
(call_ref (i32.const 2)
(call_indirect $t (type $fl) (i32.const 0) (ref.null (type $fl)) (i32.const 0))
(call_indirect $t (type $fl) (i32.const 0) (ref.null $fl) (i32.const 0))
)
(call_ref (i32.const 3)
(call_indirect $t (type $fl') (ref.null (type $fl')) (i32.const 1))
(call_indirect $t (type $fl') (ref.null $fl') (i32.const 1))
)
)
)
Expand Down Expand Up @@ -399,7 +399,7 @@
(module
(type $t (func))
(func (export "null") (result (ref $t))
(ref.null (type $t))
(ref.null $t)
(func.bind)
)
)
Expand All @@ -408,7 +408,7 @@
(module
(type $t (func (param f32)))
(func (export "null") (result (ref $t))
(ref.null (type $t))
(ref.null $t)
(func.bind (type $t))
)
)
Expand All @@ -419,7 +419,7 @@
(type $t1 (func (param i64)))
(func (export "null") (result (ref $t0))
(i64.const 0)
(ref.null (type $t1))
(ref.null $t1)
(func.bind)
)
)
Expand All @@ -430,7 +430,7 @@
(type $t1 (func (param i64)))
(func (export "null") (result (ref $t0))
(i64.const 0)
(ref.null (type $t1))
(ref.null $t1)
(func.bind (type $t0))
)
)
Expand All @@ -440,7 +440,7 @@
(module
(type $t (func (result f32)))
(func (export "null") (result i32)
(ref.null (type $t))
(ref.null $t)
(func.bind)
)
)
Expand Down
4 changes: 2 additions & 2 deletions test/core/linking.wast
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,12 @@
(func $f) (elem declare func $f)
(global (export "g-const-funcnull") (ref null func) (ref.null func))
(global (export "g-const-func") (ref func) (ref.func $f))
(global (export "g-const-refnull") (ref null $t) (ref.null (type $t)))
(global (export "g-const-refnull") (ref null $t) (ref.null $t))
(global (export "g-const-ref") (ref $t) (ref.func $f))
(global (export "g-const-extern") externref (ref.null extern))
(global (export "g-var-funcnull") (mut (ref null func)) (ref.null func))
(global (export "g-var-func") (mut (ref func)) (ref.func $f))
(global (export "g-var-refnull") (mut (ref null $t)) (ref.null (type $t)))
(global (export "g-var-refnull") (mut (ref null $t)) (ref.null $t))
(global (export "g-var-ref") (mut (ref $t)) (ref.func $f))
(global (export "g-var-extern") (mut externref) (ref.null extern))
)
Expand Down
8 changes: 3 additions & 5 deletions test/core/ref.wast
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@
externref
(ref func)
(ref extern)
(ref (type 0))
(ref (type $t))
(ref 0)
(ref $t)
(ref 0)
(ref $t)
(ref null func)
(ref null extern)
(ref null (type 0))
(ref null (type $t))
(ref null 0)
(ref null $t)
)
Expand All @@ -36,7 +34,7 @@
)

(assert_invalid
(module (global $global-invalid (ref null 1) (ref.null (type 1))))
(module (global $global-invalid (ref null 1) (ref.null 1)))
"unknown type"
)

Expand Down
4 changes: 2 additions & 2 deletions test/core/ref_as_non_null.wast
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
(elem func $f)
(func $f (result i32) (i32.const 7))

(func (export "nullable-null") (result i32) (call $n (ref.null (type $t))))
(func (export "nullable-null") (result i32) (call $n (ref.null $t)))
(func (export "nonnullable-f") (result i32) (call $nn (ref.func $f)))
(func (export "nullable-f") (result i32) (call $n (ref.func $f)))

Expand All @@ -32,7 +32,7 @@
(module
(type $t (func (result i32)))
(func $g (param $r (ref $t)) (drop (ref.as_non_null (local.get $r))))
(func (call $g (ref.null (type $t))))
(func (call $g (ref.null $t)))
)
"type mismatch"
)
Expand Down
4 changes: 2 additions & 2 deletions test/core/ref_is_null.wast
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
(ref.is_null (local.get $x))
)
(func $f3' (export "ref-null") (result i32)
(call $f3 (ref.null (type $t)))
(call $f3 (ref.null $t))
)

(table $t1 2 funcref)
Expand All @@ -27,7 +27,7 @@
(func (export "deinit")
(table.set $t1 (i32.const 1) (ref.null func))
(table.set $t2 (i32.const 1) (ref.null extern))
(table.set $t3 (i32.const 1) (ref.null (type $t)))
(table.set $t3 (i32.const 1) (ref.null $t))
)

(func (export "funcref-elem") (param $x i32) (result i32)
Expand Down
4 changes: 2 additions & 2 deletions test/core/ref_null.wast
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
(type $t (func))
(func (export "externref") (result externref) (ref.null extern))
(func (export "funcref") (result funcref) (ref.null func))
(func (export "ref") (result (ref null $t)) (ref.null (type $t)))
(func (export "ref") (result (ref null $t)) (ref.null $t))

(global externref (ref.null extern))
(global funcref (ref.null func))
(global (ref null $t) (ref.null (type $t)))
(global (ref null $t) (ref.null $t))
)

(assert_return (invoke "externref") (ref.null extern))
Expand Down
2 changes: 1 addition & 1 deletion test/core/return_call_ref.wast
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
;; Null

(func (export "null")
(return_call_ref (ref.null (type $proc)))
(return_call_ref (ref.null $proc))
)

;; Recursion
Expand Down

0 comments on commit f83fc6c

Please sign in to comment.