summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/Print.cpp2
-rw-r--r--src/wasm-builder.h4
-rw-r--r--src/wasm-delegations-fields.h1
-rw-r--r--src/wasm.h3
-rw-r--r--src/wasm/wasm-binary.cpp2
-rw-r--r--src/wasm/wasm-s-parser.cpp15
-rw-r--r--src/wasm/wasm-validator.cpp15
-rw-r--r--src/wasm/wasm.cpp2
-rw-r--r--test/heap-types.wast4
-rw-r--r--test/heap-types.wast.from-wast8
-rw-r--r--test/heap-types.wast.fromBinary10
-rw-r--r--test/heap-types.wast.fromBinary.noDebugInfo10
-rw-r--r--test/passes/Oz_fuzz-exec_all-features.wast6
13 files changed, 41 insertions, 41 deletions
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 23590ebd5..371d83962 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -1786,8 +1786,6 @@ struct PrintExpressionContents
void visitBrOnCast(BrOnCast* curr) {
printMedium(o, "br_on_cast ");
printName(curr->name, o);
- o << " ";
- printHeapTypeName(o, curr->getCastType().getHeapType());
}
void visitRttCanon(RttCanon* curr) {
printMedium(o, "rtt.canon ");
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 6716bca20..516d1cc15 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -709,11 +709,9 @@ public:
ret->finalize();
return ret;
}
- BrOnCast*
- makeBrOnCast(Name name, HeapType heapType, Expression* ref, Expression* rtt) {
+ BrOnCast* makeBrOnCast(Name name, Expression* ref, Expression* rtt) {
auto* ret = wasm.allocator.alloc<BrOnCast>();
ret->name = name;
- ret->castType = Type(heapType, Nullable);
ret->ref = ref;
ret->rtt = rtt;
ret->finalize();
diff --git a/src/wasm-delegations-fields.h b/src/wasm-delegations-fields.h
index a39a8b7af..b0be5844c 100644
--- a/src/wasm-delegations-fields.h
+++ b/src/wasm-delegations-fields.h
@@ -591,7 +591,6 @@ switch (DELEGATE_ID) {
case Expression::Id::BrOnCastId: {
DELEGATE_START(BrOnCast);
DELEGATE_FIELD_SCOPE_NAME_USE(BrOnCast, name);
- DELEGATE_FIELD_TYPE(BrOnCast, castType);
DELEGATE_FIELD_CHILD(BrOnCast, rtt);
DELEGATE_FIELD_CHILD(BrOnCast, ref);
DELEGATE_END(BrOnCast);
diff --git a/src/wasm.h b/src/wasm.h
index 094233b5c..041f7b49b 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -1386,9 +1386,6 @@ public:
BrOnCast(MixedArena& allocator) {}
Name name;
- // The cast type cannot be inferred from rtt if rtt is unreachable, so we must
- // store it explicitly.
- Type castType;
Expression* ref;
Expression* rtt;
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 398ef9cb5..4a82c84a9 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -5835,7 +5835,7 @@ bool WasmBinaryBuilder::maybeVisitBrOnCast(Expression*& out, uint32_t code) {
throwError("bad rtt for br_on_cast");
}
auto* ref = popNonVoidExpression();
- out = Builder(wasm).makeBrOnCast(name, rtt->type.getHeapType(), ref, rtt);
+ out = Builder(wasm).makeBrOnCast(name, ref, rtt);
return true;
}
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 5dec22eb3..9cf2f3be9 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -2132,11 +2132,16 @@ Expression* SExpressionWasmBuilder::makeRefCast(Element& s) {
Expression* SExpressionWasmBuilder::makeBrOnCast(Element& s) {
auto name = getLabel(*s[1]);
- auto heapType = parseHeapType(*s[2]);
- auto* ref = parseExpression(*s[3]);
- auto* rtt = parseExpression(*s[4]);
- validateHeapTypeUsingChild(rtt, heapType, s);
- return Builder(wasm).makeBrOnCast(name, heapType, ref, rtt);
+ auto* ref = parseExpression(*s[2]);
+ auto* rtt = parseExpression(*s[3]);
+ Builder builder(wasm);
+ if (rtt->type == Type::unreachable) {
+ // An unreachable rtt is not supported: the text format does not provide the
+ // type, so if it's unreachable we should not even create a br_on_cast in
+ // such a case, as we'd have no idea what it casts to.
+ return builder.makeSequence(builder.makeDrop(ref), rtt);
+ }
+ return builder.makeBrOnCast(name, ref, rtt);
}
Expression* SExpressionWasmBuilder::makeRttCanon(Element& s) {
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 8def0e529..c6d0d9fe7 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -2215,15 +2215,12 @@ void FunctionValidator::visitBrOnCast(BrOnCast* curr) {
shouldBeTrue(
curr->ref->type.isRef(), curr, "br_on_cast ref must have ref type");
}
- if (curr->rtt->type != Type::unreachable) {
- shouldBeTrue(
- curr->rtt->type.isRtt(), curr, "br_on_cast rtt must have rtt type");
- shouldBeEqual(curr->rtt->type.getHeapType(),
- curr->castType.getHeapType(),
- curr,
- "br_on_cast rtt must have the proper heap type");
- noteBreak(curr->name, curr->castType, curr);
- }
+ // Note that an unreachable rtt is not supported: the text and binary formats
+ // do not provide the type, so if it's unreachable we should not even create
+ // a br_on_cast in such a case, as we'd have no idea what it casts to.
+ shouldBeTrue(
+ curr->rtt->type.isRtt(), curr, "br_on_cast rtt must have rtt type");
+ noteBreak(curr->name, curr->getCastType(), curr);
}
void FunctionValidator::visitRttCanon(RttCanon* curr) {
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index 690c96f67..1e4ff6e3e 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -939,7 +939,7 @@ void BrOnCast::finalize() {
}
}
-Type BrOnCast::getCastType() { return castType; }
+Type BrOnCast::getCastType() { return Type(rtt->type.getHeapType(), Nullable); }
void RttCanon::finalize() {
// Nothing to do - the type must have been set already during construction.
diff --git a/test/heap-types.wast b/test/heap-types.wast
index a36f12daf..26283da7a 100644
--- a/test/heap-types.wast
+++ b/test/heap-types.wast
@@ -173,11 +173,11 @@
;; set the value to a local with type $struct.A, showing that the value
;; flowing out has the right type
(local.set $temp.A
- (br_on_cast $out $struct.B (ref.null $struct.A) (rtt.canon $struct.B))
+ (br_on_cast $out (ref.null $struct.A) (rtt.canon $struct.B))
)
;; an untaken br_on_cast, with unreachable rtt - so we cannot use the
;; RTT in binaryen IR to find the cast type.
- (br_on_cast $out $struct.B (ref.null $struct.A) (unreachable))
+ (br_on_cast $out (ref.null $struct.A) (unreachable))
(unreachable)
)
)
diff --git a/test/heap-types.wast.from-wast b/test/heap-types.wast.from-wast
index 4ff3bceec..c498e8fd5 100644
--- a/test/heap-types.wast.from-wast
+++ b/test/heap-types.wast.from-wast
@@ -184,13 +184,15 @@
(drop
(block $out (result (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))
(local.set $temp.A
- (br_on_cast $out ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}
+ (br_on_cast $out
(ref.null ${i32_f32_f64})
(rtt.canon ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|})
)
)
- (br_on_cast $out ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}
- (ref.null ${i32_f32_f64})
+ (block
+ (drop
+ (ref.null ${i32_f32_f64})
+ )
(unreachable)
)
(unreachable)
diff --git a/test/heap-types.wast.fromBinary b/test/heap-types.wast.fromBinary
index 9f0220c53..d1003a685 100644
--- a/test/heap-types.wast.fromBinary
+++ b/test/heap-types.wast.fromBinary
@@ -184,15 +184,17 @@
(drop
(block $label$1 (result (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))
(local.set $temp.A
- (br_on_cast $label$1 ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}
+ (br_on_cast $label$1
(ref.null ${i32_f32_f64})
(rtt.canon ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|})
)
)
- (drop
- (ref.null ${i32_f32_f64})
+ (block $label$2
+ (drop
+ (ref.null ${i32_f32_f64})
+ )
+ (unreachable)
)
- (unreachable)
)
)
)
diff --git a/test/heap-types.wast.fromBinary.noDebugInfo b/test/heap-types.wast.fromBinary.noDebugInfo
index 864d66abb..61fffe7a3 100644
--- a/test/heap-types.wast.fromBinary.noDebugInfo
+++ b/test/heap-types.wast.fromBinary.noDebugInfo
@@ -184,15 +184,17 @@
(drop
(block $label$1 (result (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))
(local.set $0
- (br_on_cast $label$1 ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}
+ (br_on_cast $label$1
(ref.null ${i32_f32_f64})
(rtt.canon ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|})
)
)
- (drop
- (ref.null ${i32_f32_f64})
+ (block $label$2
+ (drop
+ (ref.null ${i32_f32_f64})
+ )
+ (unreachable)
)
- (unreachable)
)
)
)
diff --git a/test/passes/Oz_fuzz-exec_all-features.wast b/test/passes/Oz_fuzz-exec_all-features.wast
index d521ad377..fb3be9691 100644
--- a/test/passes/Oz_fuzz-exec_all-features.wast
+++ b/test/passes/Oz_fuzz-exec_all-features.wast
@@ -147,9 +147,9 @@
(block $extendedblock (result (ref $extendedstruct))
(drop
;; second, try to cast our simple $struct to what it is, which will work
- (br_on_cast $block $struct
+ (br_on_cast $block
;; first, try to cast our simple $struct to an extended, which will fail
- (br_on_cast $extendedblock $extendedstruct
+ (br_on_cast $extendedblock
(local.get $any) (rtt.canon $extendedstruct)
)
(rtt.canon $struct)
@@ -168,7 +168,7 @@
(block $never (result (ref $extendedstruct))
;; an untaken br_on_cast, with unreachable rtt - so we cannot use the
;; RTT in binaryen IR to find the cast type.
- (br_on_cast $never $extendedstruct (ref.null $struct) (unreachable))
+ (br_on_cast $never (ref.null $struct) (unreachable))
(unreachable)
)
)