From 37e44c9c437d6560bb02cf17371ed0adcd0a4fcf Mon Sep 17 00:00:00 2001 From: Ben Smith Date: Wed, 13 May 2020 13:19:01 -0700 Subject: [PATCH] Update `ref.null` encoding after subtyping change (#149) Issue https://github.com/WebAssembly/reference-types/issues/69 requires that `ref.null` instructions include a reference type immediate. This concept isn't present in the bulk-memory proposal, but the encoding is (in element segment expressions). This change updates the binary and text format, but not the syntax. This is OK for now, since the only reference type allowed here is `funcref`. --- document/core/binary/modules.rst | 2 +- document/core/text/modules.rst | 2 +- interpreter/binary/decode.ml | 5 ++++- interpreter/binary/encode.ml | 2 +- interpreter/text/arrange.ml | 2 +- interpreter/text/parser.mly | 2 +- test/core/binary.wast | 4 ++-- test/core/bulk.wast | 2 +- test/core/elem.wast | 18 +++++++++--------- 9 files changed, 21 insertions(+), 18 deletions(-) diff --git a/document/core/binary/modules.rst b/document/core/binary/modules.rst index 7ba296f2..05cff771 100644 --- a/document/core/binary/modules.rst +++ b/document/core/binary/modules.rst @@ -343,7 +343,7 @@ It decodes into a vector of :ref:`element segments ` that represent \production{element kind} & \Belemkind &::=& \hex{00} &\Rightarrow& \FUNCREF \\ \production{element expression} & \Belemexpr &::=& - \hex{D0}~\hex{0B} &\Rightarrow& \REFNULL~\END \\ &&|& + \hex{D0}~\hex{70}~\hex{0B} &\Rightarrow& \REFNULL~\END \\ &&|& \hex{D2}~x{:}\Bfuncidx~\hex{0B} &\Rightarrow& (\REFFUNC~x)~\END \\ \end{array} diff --git a/document/core/text/modules.rst b/document/core/text/modules.rst index 06941d15..9c920165 100644 --- a/document/core/text/modules.rst +++ b/document/core/text/modules.rst @@ -503,7 +503,7 @@ Element segments allow for an optional :ref:`table index ` to ide \production{element list} & \Telemlist &::=& et{:}\Telemtype~~y^\ast{:}\Tvec(\Telemexpr_I) \qquad\Rightarrow\quad ( \ETYPE~et, \EINIT~y^\ast ) \\ \production{element expression} & \Telemexpr &::=& - \text{(}~\text{ref.null}~\text{)} \\ &&|& + \text{(}~\text{ref.null}~~\text{func}~\text{)} \\ &&|& \text{(}~\text{ref.func}~~\Tfuncidx_I~\text{)} \\ \production{table use} & \Ttableuse_I &::=& \text{(}~\text{table}~~x{:}\Ttableidx_I ~\text{)} diff --git a/interpreter/binary/decode.ml b/interpreter/binary/decode.ml index 5974e99e..5fb92ef9 100644 --- a/interpreter/binary/decode.ml +++ b/interpreter/binary/decode.ml @@ -636,7 +636,10 @@ let elem_kind s = let elem_expr s = match u8 s with - | 0xd0 -> end_ s; ref_null + | 0xd0 -> + expect 0x70 s "funcref expected"; + end_ s; + ref_null | 0xd2 -> let x = at var s in end_ s; diff --git a/interpreter/binary/encode.ml b/interpreter/binary/encode.ml index 1be8b07f..54908ea3 100644 --- a/interpreter/binary/encode.ml +++ b/interpreter/binary/encode.ml @@ -482,7 +482,7 @@ let encode m = let elem_expr e = match e.it with - | RefNull -> u8 0xd0; end_ () + | RefNull -> u8 0xd0; u8 0x70; end_ () | RefFunc x -> u8 0xd2; var x; end_ () let elem_index e = diff --git a/interpreter/text/arrange.ml b/interpreter/text/arrange.ml index 25368b11..00c608d8 100644 --- a/interpreter/text/arrange.ml +++ b/interpreter/text/arrange.ml @@ -307,7 +307,7 @@ let elem_index el = let elem_expr el = match el.it with - | RefNull -> Node ("ref.null", []) + | RefNull -> Node ("ref.null", [atom elem_kind FuncRefType]) | RefFunc x -> Node ("ref.func", [atom var x]) let segment_mode category mode = diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index 16ccdb86..95432091 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -591,7 +591,7 @@ elem_kind : | FUNC { FuncRefType } elem_expr : - | LPAR REF_NULL RPAR { let at = at () in fun c -> ref_null @@ at } + | LPAR REF_NULL elem_kind RPAR { let at = at () in fun c -> ref_null @@ at } | LPAR REF_FUNC var RPAR { let at = at () in fun c -> ref_func ($3 c func) @@ at } elem_expr_list : diff --git a/test/core/binary.wast b/test/core/binary.wast index 83858263..82190795 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast @@ -809,10 +809,10 @@ "\05\03\01\00\00" ;; Memory section - "\09\06\01" ;; Element section with one segment + "\09\07\01" ;; Element section with one segment "\05\70" ;; Passive, funcref "\01" ;; 1 element - "\d0\0b" ;; ref.null, end + "\d0\70\0b" ;; ref.null, end "\0a\04\01" ;; Code section diff --git a/test/core/bulk.wast b/test/core/bulk.wast index 6fb1f0de..3bb79481 100644 --- a/test/core/bulk.wast +++ b/test/core/bulk.wast @@ -5,7 +5,7 @@ (module (table 3 funcref) - (elem funcref (ref.func 0) (ref.null) (ref.func 1)) + (elem funcref (ref.func 0) (ref.null func) (ref.func 1)) (func) (func)) diff --git a/test/core/elem.wast b/test/core/elem.wast index bb622ee6..a50a1a2b 100644 --- a/test/core/elem.wast +++ b/test/core/elem.wast @@ -8,18 +8,18 @@ ;; Passive (elem funcref) - (elem funcref (ref.func $f) (ref.func $f) (ref.null) (ref.func $g)) + (elem funcref (ref.func $f) (ref.func $f) (ref.null func) (ref.func $g)) (elem func) (elem func $f $f $g $g) (elem $p1 funcref) - (elem $p2 funcref (ref.func $f) (ref.func $f) (ref.null) (ref.func $g)) + (elem $p2 funcref (ref.func $f) (ref.func $f) (ref.null func) (ref.func $g)) (elem $p3 func) (elem $p4 func $f $f $g $g) ;; Active (elem (table $t) (i32.const 0) funcref) - (elem (table $t) (i32.const 0) funcref (ref.func $f) (ref.null)) + (elem (table $t) (i32.const 0) funcref (ref.func $f) (ref.null func)) (elem (table $t) (i32.const 0) func) (elem (table $t) (i32.const 0) func $f $g) (elem (table $t) (offset (i32.const 0)) funcref) @@ -33,16 +33,16 @@ (elem (table $t) (offset (i32.const 0)) func) (elem (table $t) (offset (i32.const 0)) func $f $f) (elem (offset (i32.const 0))) - (elem (offset (i32.const 0)) funcref (ref.func $f) (ref.null)) + (elem (offset (i32.const 0)) funcref (ref.func $f) (ref.null func)) (elem (offset (i32.const 0)) func $f $f) (elem (offset (i32.const 0)) $f $f) (elem (i32.const 0)) - (elem (i32.const 0) funcref (ref.func $f) (ref.null)) + (elem (i32.const 0) funcref (ref.func $f) (ref.null func)) (elem (i32.const 0) func $f $f) (elem (i32.const 0) $f $f) (elem $a1 (table $t) (i32.const 0) funcref) - (elem $a2 (table $t) (i32.const 0) funcref (ref.func $f) (ref.null)) + (elem $a2 (table $t) (i32.const 0) funcref (ref.func $f) (ref.null func)) (elem $a3 (table $t) (i32.const 0) func) (elem $a4 (table $t) (i32.const 0) func $f $g) (elem $a9 (table $t) (offset (i32.const 0)) funcref) @@ -56,11 +56,11 @@ (elem $a17 (table $t) (offset (i32.const 0)) func) (elem $a18 (table $t) (offset (i32.const 0)) func $f $f) (elem $a19 (offset (i32.const 0))) - (elem $a20 (offset (i32.const 0)) funcref (ref.func $f) (ref.null)) + (elem $a20 (offset (i32.const 0)) funcref (ref.func $f) (ref.null func)) (elem $a21 (offset (i32.const 0)) func $f $f) (elem $a22 (offset (i32.const 0)) $f $f) (elem $a23 (i32.const 0)) - (elem $a24 (i32.const 0) funcref (ref.func $f) (ref.null)) + (elem $a24 (i32.const 0) funcref (ref.func $f) (ref.null func)) (elem $a25 (i32.const 0) func $f $f) (elem $a26 (i32.const 0) $f $f) ) @@ -69,7 +69,7 @@ (func $f) (func $g) - (table $t funcref (elem (ref.func $f) (ref.null) (ref.func $g))) + (table $t funcref (elem (ref.func $f) (ref.null func) (ref.func $g))) ) ;; Basic use