summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm/wat-parser.cpp40
-rw-r--r--test/lit/wat-kitchen-sink.wast88
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: )