summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2024-01-03 14:04:26 -0800
committerGitHub <noreply@github.com>2024-01-03 14:04:26 -0800
commit328bd7a7d6cce32e893c5839b95574f8a3d8bd9a (patch)
treebbf0cd57bb1940d7102dedc371b21df88d62ebc4
parentc923521a61205dd2358201e311b009886e095381 (diff)
downloadbinaryen-328bd7a7d6cce32e893c5839b95574f8a3d8bd9a.tar.gz
binaryen-328bd7a7d6cce32e893c5839b95574f8a3d8bd9a.tar.bz2
binaryen-328bd7a7d6cce32e893c5839b95574f8a3d8bd9a.zip
[Parser] Parse br_on_cast{_fail} input annotations (#6198)
And validate in IRBuilder both that the input annotation is valid and that the input matches it.
-rw-r--r--src/parser/contexts.h12
-rw-r--r--src/parser/parsers.h8
-rw-r--r--src/wasm-ir-builder.h2
-rw-r--r--src/wasm/wasm-ir-builder.cpp12
-rw-r--r--test/lit/wat-kitchen-sink.wast4
5 files changed, 26 insertions, 12 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h
index 2565a4817..1cefb288d 100644
--- a/src/parser/contexts.h
+++ b/src/parser/contexts.h
@@ -443,7 +443,8 @@ struct NullInstrParserCtx {
Result<> makeBrOn(Index, LabelIdxT, BrOnOp) { return Ok{}; }
- template<typename TypeT> Result<> makeBrOn(Index, LabelIdxT, BrOnOp, TypeT) {
+ template<typename TypeT>
+ Result<> makeBrOn(Index, LabelIdxT, BrOnOp, TypeT, TypeT) {
return Ok{};
}
@@ -1690,9 +1691,12 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
return withLoc(pos, irBuilder.makeRefCast(type));
}
- Result<>
- makeBrOn(Index pos, Index label, BrOnOp op, Type castType = Type::none) {
- return withLoc(pos, irBuilder.makeBrOn(label, op, castType));
+ Result<> makeBrOn(Index pos,
+ Index label,
+ BrOnOp op,
+ Type in = Type::none,
+ Type out = Type::none) {
+ return withLoc(pos, irBuilder.makeBrOn(label, op, in, out));
}
Result<> makeStructNew(Index pos, HeapType type) {
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index 9302f4fc9..1d786f363 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -1594,9 +1594,11 @@ template<typename Ctx> Result<> makeBrOnNull(Ctx& ctx, Index pos, bool onFail) {
template<typename Ctx> Result<> makeBrOnCast(Ctx& ctx, Index pos, bool onFail) {
auto label = labelidx(ctx);
CHECK_ERR(label);
- auto type = reftype(ctx);
- CHECK_ERR(type);
- return ctx.makeBrOn(pos, *label, onFail ? BrOnCastFail : BrOnCast, *type);
+ auto in = reftype(ctx);
+ CHECK_ERR(in);
+ auto out = reftype(ctx);
+ CHECK_ERR(out);
+ return ctx.makeBrOn(pos, *label, onFail ? BrOnCastFail : BrOnCast, *in, *out);
}
template<typename Ctx>
diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h
index dcb25efa7..5add042a6 100644
--- a/src/wasm-ir-builder.h
+++ b/src/wasm-ir-builder.h
@@ -168,7 +168,7 @@ public:
[[nodiscard]] Result<> makeRefTest(Type type);
[[nodiscard]] Result<> makeRefCast(Type type);
[[nodiscard]] Result<>
- makeBrOn(Index label, BrOnOp op, Type castType = Type::none);
+ makeBrOn(Index label, BrOnOp op, Type in = Type::none, Type out = Type::none);
[[nodiscard]] Result<> makeStructNew(HeapType type);
[[nodiscard]] Result<> makeStructNewDefault(HeapType type);
[[nodiscard]] Result<>
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp
index 3cfe0ea30..43a989c6e 100644
--- a/src/wasm/wasm-ir-builder.cpp
+++ b/src/wasm/wasm-ir-builder.cpp
@@ -1420,12 +1420,20 @@ Result<> IRBuilder::makeRefCast(Type type) {
return Ok{};
}
-Result<> IRBuilder::makeBrOn(Index label, BrOnOp op, Type castType) {
+Result<> IRBuilder::makeBrOn(Index label, BrOnOp op, Type in, Type out) {
BrOn curr;
CHECK_ERR(visitBrOn(&curr));
+ if (out != Type::none) {
+ if (!Type::isSubType(out, in)) {
+ return Err{"output type is not a subtype of the input type"};
+ }
+ if (!Type::isSubType(curr.ref->type, in)) {
+ return Err{"expected input to match input type annotation"};
+ }
+ }
auto name = getLabelName(label);
CHECK_ERR(name);
- push(builder.makeBrOn(op, *name, curr.ref, castType));
+ push(builder.makeBrOn(op, *name, curr.ref, out));
return Ok{};
}
diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast
index 303cfc53b..775a0a139 100644
--- a/test/lit/wat-kitchen-sink.wast
+++ b/test/lit/wat-kitchen-sink.wast
@@ -3549,7 +3549,7 @@
block (result i31ref)
block (result (ref any))
local.get 0
- br_on_cast 1 i31ref
+ br_on_cast 1 anyref i31ref
end
unreachable
end
@@ -3574,7 +3574,7 @@
block (result (ref any))
block (result i31ref)
local.get 0
- br_on_cast_fail 1 i31ref
+ br_on_cast_fail 1 anyref i31ref
end
unreachable
end