summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/gen-s-parser.py1
-rw-r--r--src/gen-s-parser.inc9
-rw-r--r--src/parser/parsers.h5
-rw-r--r--src/passes/Print.cpp9
-rw-r--r--src/wasm-s-parser.h1
-rw-r--r--src/wasm/wasm-s-parser.cpp15
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt4
-rw-r--r--test/example/c-api-kitchen-sink.txt4
-rw-r--r--test/lit/basic/types-function-references.wast4
-rw-r--r--test/lit/multivalue.wast6
-rw-r--r--test/lit/passes/coalesce-locals-gc.wast2
-rw-r--r--test/lit/passes/gufa-refs.wast6
-rw-r--r--test/lit/passes/poppify.wast2
-rw-r--r--test/lit/passes/remove-unused-brs.wast8
-rw-r--r--test/lit/passes/roundtrip.wast2
-rw-r--r--test/lit/passes/simplify-locals-gc-nn.wast6
-rw-r--r--test/lit/passes/vacuum_all-features.wast4
-rw-r--r--test/lit/validation/bad-non-nullable-locals.wast2
-rw-r--r--test/lit/wat-kitchen-sink.wast2
-rw-r--r--test/passes/precompute_all-features.wast2
-rw-r--r--test/passes/rse_all-features.txt2
-rw-r--r--test/unit/test_features.py2
22 files changed, 68 insertions, 30 deletions
diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py
index bd29f4f10..0dfe220b5 100755
--- a/scripts/gen-s-parser.py
+++ b/scripts/gen-s-parser.py
@@ -559,6 +559,7 @@ instructions = [
# Multivalue pseudoinstructions
("tuple.make", "makeTupleMake(s)"),
("tuple.extract", "makeTupleExtract(s)"),
+ ("tuple.drop", "makeTupleDrop(s)"),
("pop", "makePop(s)"),
# Typed function references instructions
("call_ref", "makeCallRef(s, /*isReturn=*/false)"),
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index 22c7a0c90..bc0a03dd3 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -3404,6 +3404,9 @@ switch (buf[0]) {
goto parse_error;
case 'u': {
switch (buf[6]) {
+ case 'd':
+ if (op == "tuple.drop"sv) { return makeTupleDrop(s); }
+ goto parse_error;
case 'e':
if (op == "tuple.extract"sv) { return makeTupleExtract(s); }
goto parse_error;
@@ -8651,6 +8654,12 @@ switch (buf[0]) {
goto parse_error;
case 'u': {
switch (buf[6]) {
+ case 'd':
+ if (op == "tuple.drop"sv) {
+ CHECK_ERR(makeTupleDrop(ctx, pos));
+ return Ok{};
+ }
+ goto parse_error;
case 'e':
if (op == "tuple.extract"sv) {
CHECK_ERR(makeTupleExtract(ctx, pos));
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index fdcfd6d0f..281980108 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -119,6 +119,7 @@ template<typename Ctx> Result<> makeThrow(Ctx&, Index);
template<typename Ctx> Result<> makeRethrow(Ctx&, Index);
template<typename Ctx> Result<> makeTupleMake(Ctx&, Index);
template<typename Ctx> Result<> makeTupleExtract(Ctx&, Index);
+template<typename Ctx> Result<> makeTupleDrop(Ctx&, Index);
template<typename Ctx> Result<> makeCallRef(Ctx&, Index, bool isReturn);
template<typename Ctx> Result<> makeRefI31(Ctx&, Index);
template<typename Ctx> Result<> makeI31Get(Ctx&, Index, bool signed_);
@@ -1473,6 +1474,10 @@ template<typename Ctx> Result<> makeTupleExtract(Ctx& ctx, Index pos) {
return ctx.in.err("unimplemented instruction");
}
+template<typename Ctx> Result<> makeTupleDrop(Ctx& ctx, Index pos) {
+ return ctx.in.err("unimplemented instruction");
+}
+
template<typename Ctx>
Result<> makeCallRef(Ctx& ctx, Index pos, bool isReturn) {
auto type = typeidx(ctx);
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 9a0a600f9..51909c6ff 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -1910,7 +1910,14 @@ struct PrintExpressionContents
printResultType(curr->type);
}
}
- void visitDrop(Drop* curr) { printMedium(o, "drop"); }
+ void visitDrop(Drop* curr) {
+ if (curr->value->type.isTuple()) {
+ printMedium(o, "tuple.drop ");
+ o << curr->value->type.size();
+ } else {
+ printMedium(o, "drop");
+ }
+ }
void visitReturn(Return* curr) { printMedium(o, "return"); }
void visitMemorySize(MemorySize* curr) {
printMedium(o, "memory.size");
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index bbd07e3be..446f2a292 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -289,6 +289,7 @@ private:
Expression* makeRethrow(Element& s);
Expression* makeTupleMake(Element& s);
Expression* makeTupleExtract(Element& s);
+ Expression* makeTupleDrop(Element& s);
Expression* makeCallRef(Element& s, bool isReturn);
Expression* makeRefI31(Element& s);
Expression* makeI31Get(Element& s, bool signed_);
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 8e74820a9..521060749 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -1503,6 +1503,9 @@ Expression* SExpressionWasmBuilder::makeSelect(Element& s) {
Expression* SExpressionWasmBuilder::makeDrop(Element& s) {
auto ret = allocator.alloc<Drop>();
ret->value = parseExpression(s[1]);
+ if (ret->value->type.isTuple()) {
+ throw SParseException("expected tuple.drop, found drop", s, *s[0]);
+ }
ret->finalize();
return ret;
}
@@ -2879,6 +2882,18 @@ Expression* SExpressionWasmBuilder::makeTupleExtract(Element& s) {
return ret;
}
+Expression* SExpressionWasmBuilder::makeTupleDrop(Element& s) {
+ size_t arity = std::stoll(s[1]->toString());
+ auto ret = allocator.alloc<Drop>();
+ ret->value = parseExpression(s[2]);
+ if (ret->value->type != Type::unreachable &&
+ ret->value->type.size() != arity) {
+ throw SParseException("unexpected tuple.drop arity", s, *s[1]);
+ }
+ ret->finalize();
+ return ret;
+}
+
Expression* SExpressionWasmBuilder::makeCallRef(Element& s, bool isReturn) {
HeapType sigType = parseHeapType(*s[1]);
std::vector<Expression*> operands;
diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt
index 2e4eedda9..14d7850c5 100644
--- a/test/binaryen.js/kitchen-sink.js.txt
+++ b/test/binaryen.js/kitchen-sink.js.txt
@@ -2130,7 +2130,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
)
)
(atomic.fence)
- (drop
+ (tuple.drop 4
(tuple.make 4
(i32.const 13)
(i64.const 37)
@@ -4234,7 +4234,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
)
)
(atomic.fence)
- (drop
+ (tuple.drop 4
(tuple.make 4
(i32.const 13)
(i64.const 37)
diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt
index f2646eaeb..ceff020b9 100644
--- a/test/example/c-api-kitchen-sink.txt
+++ b/test/example/c-api-kitchen-sink.txt
@@ -2193,7 +2193,7 @@ BinaryenFeatureAll: 131071
)
)
(atomic.fence)
- (drop
+ (tuple.drop 4
(tuple.make 4
(i32.const 13)
(i64.const 37)
@@ -2229,7 +2229,7 @@ BinaryenFeatureAll: 131071
(drop
(pop externref)
)
- (drop
+ (tuple.drop 4
(pop i32 i64 f32 f64)
)
(drop
diff --git a/test/lit/basic/types-function-references.wast b/test/lit/basic/types-function-references.wast
index 4bff6cbb9..e4fe9b921 100644
--- a/test/lit/basic/types-function-references.wast
+++ b/test/lit/basic/types-function-references.wast
@@ -188,7 +188,7 @@
)
;; CHECK-TEXT: (func $type-only-in-tuple-block (type $void)
- ;; CHECK-TEXT-NEXT: (drop
+ ;; CHECK-TEXT-NEXT: (tuple.drop 3
;; CHECK-TEXT-NEXT: (block $block (type $3) (result i32 (ref null $mixed_results) f64)
;; CHECK-TEXT-NEXT: (unreachable)
;; CHECK-TEXT-NEXT: )
@@ -230,7 +230,7 @@
;; CHECK-BIN-NEXT: )
;; CHECK-BIN-NEXT: )
(func $type-only-in-tuple-block
- (drop
+ (tuple.drop 3
(block $block (result i32 (ref null $mixed_results) f64)
(unreachable)
)
diff --git a/test/lit/multivalue.wast b/test/lit/multivalue.wast
index a71c222cc..e1fd0f71e 100644
--- a/test/lit/multivalue.wast
+++ b/test/lit/multivalue.wast
@@ -288,7 +288,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $drop-call
- (drop
+ (tuple.drop 2
(call $pair)
)
)
@@ -308,7 +308,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $drop-tuple-make
- (drop
+ (tuple.drop 2
(tuple.make 2
(i32.const 42)
(i64.const 42)
@@ -344,7 +344,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $drop-block
- (drop
+ (tuple.drop 2
(block $block (result i32 i64)
(tuple.make 2
(i32.const 42)
diff --git a/test/lit/passes/coalesce-locals-gc.wast b/test/lit/passes/coalesce-locals-gc.wast
index 320cebb84..09270fb6c 100644
--- a/test/lit/passes/coalesce-locals-gc.wast
+++ b/test/lit/passes/coalesce-locals-gc.wast
@@ -285,7 +285,7 @@
;; CHECK: (func $test (type $10) (param $0 (ref any)) (result (ref any) i32)
;; CHECK-NEXT: (local $1 (anyref i32))
- ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (tuple.drop 2
;; CHECK-NEXT: (tuple.make 2
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: (i32.const 0)
diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast
index 18490fa91..2687de049 100644
--- a/test/lit/passes/gufa-refs.wast
+++ b/test/lit/passes/gufa-refs.wast
@@ -2150,7 +2150,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result nullref)
- ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (tuple.drop 2
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null none)
@@ -4205,7 +4205,7 @@
)
;; CHECK: (func $tuples (type $0)
- ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (tuple.drop 2
;; CHECK-NEXT: (tuple.make 2
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: (i32.const 2)
@@ -4213,7 +4213,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $tuples
- (drop
+ (tuple.drop 2
(tuple.make 2
(i32.const 1)
(i32.const 2)
diff --git a/test/lit/passes/poppify.wast b/test/lit/passes/poppify.wast
index 6cd11092c..5ca28f494 100644
--- a/test/lit/passes/poppify.wast
+++ b/test/lit/passes/poppify.wast
@@ -384,7 +384,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $drop-tuple
- (drop
+ (tuple.drop 2
(tuple.make 2
(i32.const 0)
(i64.const 1)
diff --git a/test/lit/passes/remove-unused-brs.wast b/test/lit/passes/remove-unused-brs.wast
index 1027fafdd..6907547c3 100644
--- a/test/lit/passes/remove-unused-brs.wast
+++ b/test/lit/passes/remove-unused-brs.wast
@@ -326,9 +326,9 @@
)
;; CHECK: (func $restructure-select-no-multivalue (type $1)
- ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (tuple.drop 2
;; CHECK-NEXT: (block $block (type $2) (result i32 i32)
- ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (tuple.drop 2
;; CHECK-NEXT: (br_if $block
;; CHECK-NEXT: (tuple.make 2
;; CHECK-NEXT: (i32.const 1)
@@ -347,9 +347,9 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $restructure-select-no-multivalue
- (drop
+ (tuple.drop 2
(block $block (result i32 i32)
- (drop
+ (tuple.drop 2
(br_if $block
(tuple.make 2
(i32.const 1)
diff --git a/test/lit/passes/roundtrip.wast b/test/lit/passes/roundtrip.wast
index 34cfa72b7..729581161 100644
--- a/test/lit/passes/roundtrip.wast
+++ b/test/lit/passes/roundtrip.wast
@@ -32,7 +32,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $foo
- (drop
+ (tuple.drop 2
;; a tuple type with a non-nullable element, that must be carefully handled
(block $block (result funcref (ref $none))
(tuple.make 2
diff --git a/test/lit/passes/simplify-locals-gc-nn.wast b/test/lit/passes/simplify-locals-gc-nn.wast
index 793a40f65..4b3eb0c6e 100644
--- a/test/lit/passes/simplify-locals-gc-nn.wast
+++ b/test/lit/passes/simplify-locals-gc-nn.wast
@@ -65,7 +65,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch_all
- ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (tuple.drop 3
;; CHECK-NEXT: (tuple.make 3
;; CHECK-NEXT: (tuple.extract 0
;; CHECK-NEXT: (local.get $nn)
@@ -97,12 +97,12 @@
)
(try
(do
- (drop
+ (tuple.drop 3
(local.get $nn)
)
)
(catch_all
- (drop
+ (tuple.drop 3
(local.get $nn)
)
)
diff --git a/test/lit/passes/vacuum_all-features.wast b/test/lit/passes/vacuum_all-features.wast
index f85d21692..9b06624cf 100644
--- a/test/lit/passes/vacuum_all-features.wast
+++ b/test/lit/passes/vacuum_all-features.wast
@@ -1286,14 +1286,14 @@
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $1
- (drop
+ (tuple.drop 2
(block $block (result funcref i32)
;; we can vaccum out all parts of this block: the br_if is not taken, there
;; is a nop, and the tuple at the end goes to a dropped block anyhow. this
;; test specifically verifies handling of tuples containing non-nullable
;; types, for which we try to create a zero in an intermediate step along
;; the way.
- (drop
+ (tuple.drop 2
(br_if $block
(tuple.make 2
(ref.func $1)
diff --git a/test/lit/validation/bad-non-nullable-locals.wast b/test/lit/validation/bad-non-nullable-locals.wast
index 9268e9b3a..e34970fde 100644
--- a/test/lit/validation/bad-non-nullable-locals.wast
+++ b/test/lit/validation/bad-non-nullable-locals.wast
@@ -65,7 +65,7 @@
;; Since this tuple local has a non-nullable element, it is subject to the
;; non-nullability rules.
(local $x (i32 (ref any) i64))
- (drop
+ (tuple.drop 3
(local.get $x)
)
)
diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast
index 165fa618b..6c4e33a18 100644
--- a/test/lit/wat-kitchen-sink.wast
+++ b/test/lit/wat-kitchen-sink.wast
@@ -840,7 +840,7 @@
;; CHECK: (func $block-folded (type $void)
;; CHECK-NEXT: (nop)
- ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (tuple.drop 2
;; CHECK-NEXT: (block $l (type $ret2) (result i32 i32)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (nop)
diff --git a/test/passes/precompute_all-features.wast b/test/passes/precompute_all-features.wast
index fad213a17..ca4aa1cbb 100644
--- a/test/passes/precompute_all-features.wast
+++ b/test/passes/precompute_all-features.wast
@@ -48,7 +48,7 @@
(i32.const 1)
)
)
- (drop
+ (tuple.drop 2
(tuple.make 2
(tuple.extract 0
(tuple.make 2
diff --git a/test/passes/rse_all-features.txt b/test/passes/rse_all-features.txt
index ce047df81..33032d47b 100644
--- a/test/passes/rse_all-features.txt
+++ b/test/passes/rse_all-features.txt
@@ -56,7 +56,7 @@
(i64.const 42)
)
)
- (drop
+ (tuple.drop 2
(tuple.make 2
(i32.const 42)
(i64.const 42)
diff --git a/test/unit/test_features.py b/test/unit/test_features.py
index 8e38a04f8..2c596a542 100644
--- a/test/unit/test_features.py
+++ b/test/unit/test_features.py
@@ -235,7 +235,7 @@ class FeatureValidationTest(utils.BinaryenTestCase):
module = '''
(module
(func $foo
- (drop
+ (tuple.drop 2
(block (result i32 i64)
(tuple.make 2
(i32.const 42)