diff options
-rw-r--r-- | src/passes/Print.cpp | 2 | ||||
-rw-r--r-- | src/wasm-builder.h | 4 | ||||
-rw-r--r-- | src/wasm-delegations-fields.h | 1 | ||||
-rw-r--r-- | src/wasm.h | 3 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 2 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 15 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 15 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 2 | ||||
-rw-r--r-- | test/heap-types.wast | 4 | ||||
-rw-r--r-- | test/heap-types.wast.from-wast | 8 | ||||
-rw-r--r-- | test/heap-types.wast.fromBinary | 10 | ||||
-rw-r--r-- | test/heap-types.wast.fromBinary.noDebugInfo | 10 | ||||
-rw-r--r-- | test/passes/Oz_fuzz-exec_all-features.wast | 6 |
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) ) ) |