diff --git a/interpreter/syntax/types.ml b/interpreter/syntax/types.ml index d37ddbead5..23d139c5a6 100644 --- a/interpreter/syntax/types.ml +++ b/interpreter/syntax/types.ml @@ -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 diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index 91b824b257..51db494319 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -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 */ diff --git a/proposals/function-references/Overview.md b/proposals/function-references/Overview.md index 534cfefb8e..7264309436 100644 --- a/proposals/function-references/Overview.md +++ b/proposals/function-references/Overview.md @@ -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 ) | func | extern` - - `(type $t) ok` iff `$t` is defined in the context +* `heaptype ::= | func | extern` + - `$t ok` iff `$t` is defined in the context - `func ok` and `extern ok`, always * In the binary encoding, @@ -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? ` - `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 @@ -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 = ` * Note: Function types themselves are invariant for now. This may be relaxed in future extensions. @@ -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` | | @@ -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? ) | func | extern` +* `heaptype ::= exact? | 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 = ` and `$t' = ` - and ` <: ` -* `(type exact $t) <: (type exact $t')` +* `exact $t <: exact $t'` - iff `$t = ` and `$t' = ` - and ` == ` @@ -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? ) | func | extern` +* `heaptype ::= sub? | 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: diff --git a/test/core/br_on_null.wast b/test/core/br_on_null.wast index 7750ae24a5..3bae85000f 100644 --- a/test/core/br_on_null.wast +++ b/test/core/br_on_null.wast @@ -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))) @@ -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" ) @@ -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)) diff --git a/test/core/br_table.wast b/test/core/br_table.wast index d67165637e..66cdf41d9d 100644 --- a/test/core/br_table.wast +++ b/test/core/br_table.wast @@ -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)) ) ) ) diff --git a/test/core/call_ref.wast b/test/core/call_ref.wast index ad778b56ea..89322ca0f1 100644 --- a/test/core/call_ref.wast +++ b/test/core/call_ref.wast @@ -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 diff --git a/test/core/func_bind.wast b/test/core/func_bind.wast index 713e5c7575..c496705d38 100644 --- a/test/core/func_bind.wast +++ b/test/core/func_bind.wast @@ -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))) @@ -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) ) ) @@ -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)) ) ) ) @@ -399,7 +399,7 @@ (module (type $t (func)) (func (export "null") (result (ref $t)) - (ref.null (type $t)) + (ref.null $t) (func.bind) ) ) @@ -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)) ) ) @@ -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) ) ) @@ -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)) ) ) @@ -440,7 +440,7 @@ (module (type $t (func (result f32))) (func (export "null") (result i32) - (ref.null (type $t)) + (ref.null $t) (func.bind) ) ) diff --git a/test/core/linking.wast b/test/core/linking.wast index 267eeaa840..b0e56dc7f5 100644 --- a/test/core/linking.wast +++ b/test/core/linking.wast @@ -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)) ) diff --git a/test/core/ref.wast b/test/core/ref.wast index 85b2975af3..aef1b392ca 100644 --- a/test/core/ref.wast +++ b/test/core/ref.wast @@ -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) ) @@ -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" ) diff --git a/test/core/ref_as_non_null.wast b/test/core/ref_as_non_null.wast index c679db451d..ba5c454701 100644 --- a/test/core/ref_as_non_null.wast +++ b/test/core/ref_as_non_null.wast @@ -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))) @@ -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" ) diff --git a/test/core/ref_is_null.wast b/test/core/ref_is_null.wast index 43c34d3af7..730170df45 100644 --- a/test/core/ref_is_null.wast +++ b/test/core/ref_is_null.wast @@ -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) @@ -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) diff --git a/test/core/ref_null.wast b/test/core/ref_null.wast index 35df994cf8..ab3a8b4ea0 100644 --- a/test/core/ref_null.wast +++ b/test/core/ref_null.wast @@ -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)) diff --git a/test/core/return_call_ref.wast b/test/core/return_call_ref.wast index 5896229570..1c0f7097d9 100644 --- a/test/core/return_call_ref.wast +++ b/test/core/return_call_ref.wast @@ -100,7 +100,7 @@ ;; Null (func (export "null") - (return_call_ref (ref.null (type $proc))) + (return_call_ref (ref.null $proc)) ) ;; Recursion