diff options
author | Thomas Lively <tlively@google.com> | 2022-11-14 13:44:24 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-14 21:44:24 +0000 |
commit | 7df80050b6e5f3aa449da95b28a1d3e7eb778cb3 (patch) | |
tree | 5a15339466c4e6d3eb56bce7a0acf37db38202ec | |
parent | 127a8929149f3cbf1e472a04e582983b93ba9aab (diff) | |
download | binaryen-7df80050b6e5f3aa449da95b28a1d3e7eb778cb3.tar.gz binaryen-7df80050b6e5f3aa449da95b28a1d3e7eb778cb3.tar.bz2 binaryen-7df80050b6e5f3aa449da95b28a1d3e7eb778cb3.zip |
[Parser] Parse `ref.is*`, `ref.eq`, `i31.new`, and `i31.get*` (#5247)
-rw-r--r-- | src/wasm/wat-parser.cpp | 40 | ||||
-rw-r--r-- | test/lit/wat-kitchen-sink.wast | 88 |
2 files changed, 124 insertions, 4 deletions
diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp index 7705c9e5c..fe8b7a2cb 100644 --- a/src/wasm/wat-parser.cpp +++ b/src/wasm/wat-parser.cpp @@ -729,6 +729,12 @@ struct NullInstrParserCtx { template<typename HeapTypeT> InstrT makeRefNull(Index, HeapTypeT) { return {}; } + InstrT makeRefIs(Index, RefIsOp) { return Ok{}; } + + InstrT makeRefEq(Index) { return Ok{}; } + + InstrT makeI31New(Index) { return Ok{}; } + InstrT makeI31Get(Index, bool) { return Ok{}; } }; // Phase 1: Parse definition spans for top-level module elements and determine @@ -1764,6 +1770,32 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { Result<> makeRefNull(Index pos, HeapType type) { return push(pos, builder.makeRefNull(type)); } + + Result<> makeRefIs(Index pos, RefIsOp op) { + auto ref = pop(pos); + CHECK_ERR(ref); + return push(pos, builder.makeRefIs(op, *ref)); + } + + Result<> makeRefEq(Index pos) { + auto rhs = pop(pos); + CHECK_ERR(rhs); + auto lhs = pop(pos); + CHECK_ERR(lhs); + return push(pos, builder.makeRefEq(*lhs, *rhs)); + } + + Result<> makeI31New(Index pos) { + auto val = pop(pos); + CHECK_ERR(val); + return push(pos, builder.makeI31New(*val)); + } + + Result<> makeI31Get(Index pos, bool signed_) { + auto val = pop(pos); + CHECK_ERR(val); + return push(pos, builder.makeI31Get(*val, signed_)); + } }; // ================ @@ -2757,7 +2789,7 @@ Result<typename Ctx::InstrT> makeRefNull(Ctx& ctx, Index pos) { template<typename Ctx> Result<typename Ctx::InstrT> makeRefIs(Ctx& ctx, Index pos, RefIsOp op) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeRefIs(pos, op); } template<typename Ctx> @@ -2767,7 +2799,7 @@ Result<typename Ctx::InstrT> makeRefFunc(Ctx& ctx, Index pos) { template<typename Ctx> Result<typename Ctx::InstrT> makeRefEq(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeRefEq(pos); } template<typename Ctx> @@ -2828,12 +2860,12 @@ Result<typename Ctx::InstrT> makeCallRef(Ctx& ctx, Index pos, bool isReturn) { template<typename Ctx> Result<typename Ctx::InstrT> makeI31New(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeI31New(pos); } template<typename Ctx> Result<typename Ctx::InstrT> makeI31Get(Ctx& ctx, Index pos, bool signed_) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeI31Get(pos, signed_); } template<typename Ctx> diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 4c643f6a1..4c1df94f2 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -49,6 +49,14 @@ ;; CHECK: (type $none_=>_i32_i64 (func_subtype (result i32 i64) func)) + ;; CHECK: (type $anyref_=>_none (func_subtype (param anyref) func)) + + ;; CHECK: (type $eqref_eqref_=>_i32 (func_subtype (param eqref eqref) (result i32) func)) + + ;; CHECK: (type $i32_=>_i31ref (func_subtype (param i32) (result i31ref) func)) + + ;; CHECK: (type $i31ref_=>_none (func_subtype (param i31ref) func)) + ;; CHECK: (rec ;; CHECK-NEXT: (type $s0 (struct_subtype data)) (type $s0 (sub (struct))) @@ -1180,6 +1188,86 @@ return ) + ;; CHECK: (func $ref-is (type $anyref_=>_none) (param $0 anyref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.is_null + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.is_func + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.is_data + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.is_i31 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-is (param anyref) + local.get 0 + ref.is_null + drop + local.get 0 + ref.is_func + drop + local.get 0 + ref.is_data + drop + local.get 0 + ref.is_i31 + drop + ) + + ;; CHECK: (func $ref-eq (type $eqref_eqref_=>_i32) (param $0 eqref) (param $1 eqref) (result i32) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-eq (param eqref eqref) (result i32) + local.get 0 + local.get 1 + ref.eq + ) + + ;; CHECK: (func $i31-new (type $i32_=>_i31ref) (param $0 i32) (result i31ref) + ;; CHECK-NEXT: (i31.new + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $i31-new (param i32) (result i31ref) + local.get 0 + i31.new + ) + + ;; CHECK: (func $i31-get (type $i31ref_=>_none) (param $0 i31ref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i31.get_s + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i31.get_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $i31-get (param i31ref) + local.get 0 + i31.get_s + drop + local.get 0 + i31.get_u + drop + ) + ;; CHECK: (func $use-types (type $ref|$s0|_ref|$s1|_ref|$s2|_ref|$s3|_ref|$s4|_ref|$s5|_ref|$s6|_ref|$s7|_ref|$s8|_ref|$a0|_ref|$a1|_ref|$a2|_ref|$a3|_ref|$subvoid|_ref|$submany|_=>_none) (param $0 (ref $s0)) (param $1 (ref $s1)) (param $2 (ref $s2)) (param $3 (ref $s3)) (param $4 (ref $s4)) (param $5 (ref $s5)) (param $6 (ref $s6)) (param $7 (ref $s7)) (param $8 (ref $s8)) (param $9 (ref $a0)) (param $10 (ref $a1)) (param $11 (ref $a2)) (param $12 (ref $a3)) (param $13 (ref $subvoid)) (param $14 (ref $submany)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) |