Skip to content

Commit c7b41ce

Browse files
committed
[Parser] Parse br_on_cast{_fail} input annotations
And validate in IRBuilder both that the input annotation is valid and that the input matches it.
1 parent c923521 commit c7b41ce

File tree

5 files changed

+26
-12
lines changed

5 files changed

+26
-12
lines changed

src/parser/contexts.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,8 @@ struct NullInstrParserCtx {
443443

444444
Result<> makeBrOn(Index, LabelIdxT, BrOnOp) { return Ok{}; }
445445

446-
template<typename TypeT> Result<> makeBrOn(Index, LabelIdxT, BrOnOp, TypeT) {
446+
template<typename TypeT>
447+
Result<> makeBrOn(Index, LabelIdxT, BrOnOp, TypeT, TypeT) {
447448
return Ok{};
448449
}
449450

@@ -1690,9 +1691,12 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
16901691
return withLoc(pos, irBuilder.makeRefCast(type));
16911692
}
16921693

1693-
Result<>
1694-
makeBrOn(Index pos, Index label, BrOnOp op, Type castType = Type::none) {
1695-
return withLoc(pos, irBuilder.makeBrOn(label, op, castType));
1694+
Result<> makeBrOn(Index pos,
1695+
Index label,
1696+
BrOnOp op,
1697+
Type in = Type::none,
1698+
Type out = Type::none) {
1699+
return withLoc(pos, irBuilder.makeBrOn(label, op, in, out));
16961700
}
16971701

16981702
Result<> makeStructNew(Index pos, HeapType type) {

src/parser/parsers.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,9 +1594,11 @@ template<typename Ctx> Result<> makeBrOnNull(Ctx& ctx, Index pos, bool onFail) {
15941594
template<typename Ctx> Result<> makeBrOnCast(Ctx& ctx, Index pos, bool onFail) {
15951595
auto label = labelidx(ctx);
15961596
CHECK_ERR(label);
1597-
auto type = reftype(ctx);
1598-
CHECK_ERR(type);
1599-
return ctx.makeBrOn(pos, *label, onFail ? BrOnCastFail : BrOnCast, *type);
1597+
auto in = reftype(ctx);
1598+
CHECK_ERR(in);
1599+
auto out = reftype(ctx);
1600+
CHECK_ERR(out);
1601+
return ctx.makeBrOn(pos, *label, onFail ? BrOnCastFail : BrOnCast, *in, *out);
16001602
}
16011603

16021604
template<typename Ctx>

src/wasm-ir-builder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
168168
[[nodiscard]] Result<> makeRefTest(Type type);
169169
[[nodiscard]] Result<> makeRefCast(Type type);
170170
[[nodiscard]] Result<>
171-
makeBrOn(Index label, BrOnOp op, Type castType = Type::none);
171+
makeBrOn(Index label, BrOnOp op, Type in = Type::none, Type out = Type::none);
172172
[[nodiscard]] Result<> makeStructNew(HeapType type);
173173
[[nodiscard]] Result<> makeStructNewDefault(HeapType type);
174174
[[nodiscard]] Result<>

src/wasm/wasm-ir-builder.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,12 +1420,20 @@ Result<> IRBuilder::makeRefCast(Type type) {
14201420
return Ok{};
14211421
}
14221422

1423-
Result<> IRBuilder::makeBrOn(Index label, BrOnOp op, Type castType) {
1423+
Result<> IRBuilder::makeBrOn(Index label, BrOnOp op, Type in, Type out) {
14241424
BrOn curr;
14251425
CHECK_ERR(visitBrOn(&curr));
1426+
if (out != Type::none) {
1427+
if (!Type::isSubType(out, in)) {
1428+
return Err{"output type is not a subtype of the input type"};
1429+
}
1430+
if (!Type::isSubType(curr.ref->type, in)) {
1431+
return Err{"expected input to match input type annotation"};
1432+
}
1433+
}
14261434
auto name = getLabelName(label);
14271435
CHECK_ERR(name);
1428-
push(builder.makeBrOn(op, *name, curr.ref, castType));
1436+
push(builder.makeBrOn(op, *name, curr.ref, out));
14291437
return Ok{};
14301438
}
14311439

test/lit/wat-kitchen-sink.wast

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3549,7 +3549,7 @@
35493549
block (result i31ref)
35503550
block (result (ref any))
35513551
local.get 0
3552-
br_on_cast 1 i31ref
3552+
br_on_cast 1 anyref i31ref
35533553
end
35543554
unreachable
35553555
end
@@ -3574,7 +3574,7 @@
35743574
block (result (ref any))
35753575
block (result i31ref)
35763576
local.get 0
3577-
br_on_cast_fail 1 i31ref
3577+
br_on_cast_fail 1 anyref i31ref
35783578
end
35793579
unreachable
35803580
end

0 commit comments

Comments
 (0)