diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 8a1c72999ee..d4adeaa4636 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -321,7 +321,8 @@ struct PrintSExpression : public UnifiedExpressionVisitor { void printUnreachableReplacement(Expression* curr); bool maybePrintUnreachableReplacement(Expression* curr, Type type); void visitRefCast(RefCast* curr) { - if (!maybePrintUnreachableReplacement(curr, curr->type)) { + if ((curr->desc && curr->desc->type != Type::unreachable) || + !maybePrintUnreachableReplacement(curr, curr->type)) { visitExpression(curr); } } @@ -2224,7 +2225,20 @@ struct PrintExpressionContents } else { printMedium(o, "ref.cast "); } - printType(curr->type); + if (curr->type != Type::unreachable) { + printType(curr->type); + } else { + // We can still recover a valid result type from the type of the + // descriptor. + auto described = curr->desc->type.getHeapType().getDescribedType(); + if (described) { + printType( + Type(*described, NonNullable, curr->desc->type.getExactness())); + } else { + // Invalid, so it doesn't matter what we print. + printType(Type::unreachable); + } + } } void visitRefGetDesc(RefGetDesc* curr) { printMedium(o, "ref.get_desc "); diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 9ed4027df94..576cc476934 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2944,6 +2944,18 @@ void FunctionValidator::visitRefTest(RefTest* curr) { void FunctionValidator::visitRefCast(RefCast* curr) { shouldBeTrue( getModule()->features.hasGC(), curr, "ref.cast requires gc [--enable-gc]"); + + // Require descriptors to be valid even if the ref is unreachable. + if (curr->desc && curr->desc->type != Type::unreachable) { + auto descType = curr->desc->type; + bool isNull = descType.isNull(); + bool isDescriptor = + descType.isRef() && descType.getHeapType().getDescribedType(); + shouldBeTrue(isNull || isDescriptor, + curr, + "ref.cast_desc descriptor must be a descriptor reference"); + } + if (curr->type == Type::unreachable) { return; } @@ -3006,11 +3018,7 @@ void FunctionValidator::visitRefCast(RefCast* curr) { } auto described = descriptor.getDescribedType(); - if (!shouldBeTrue(bool(described), - curr, - "ref.cast_desc descriptor should have a described type")) { - return; - } + assert(described && "already checked descriptor"); shouldBeEqual(*described, curr->type.getHeapType(), curr, diff --git a/test/gtest/validator.cpp b/test/gtest/validator.cpp index 99d5878ae19..ec7caa295d1 100644 --- a/test/gtest/validator.cpp +++ b/test/gtest/validator.cpp @@ -22,6 +22,7 @@ #include "support/string.h" #include "wasm-binary.h" #include "wasm-builder.h" +#include "wasm-features.h" #include "wasm-validator.h" #include "gtest/gtest.h" @@ -65,3 +66,27 @@ TEST(ValidatorTest, ReturnUnreachable) { WasmValidator::FlagValues::Globally | WasmValidator::FlagValues::Quiet; EXPECT_FALSE(WasmValidator{}.validate(func.get(), module, flags)); } + +TEST(ValidatorTest, UnreachableCastDesc) { + // The parser will error trying to parse a ref.cast_desc with a non-matching + // descriptor type, so we must construct the IR directly to test the + // validator. + Module module; + module.features = FeatureSet::All; + Builder builder(module); + + auto func = builder.makeFunction( + "func", + {}, + Signature(Type::none, Type::none), + {}, + builder.makeDrop(builder.makeRefCast(builder.makeUnreachable(), + builder.makeStructNew(Struct{}, {}), + Type::unreachable))); + + ASSERT_EQ(func->body->type, Type(Type::unreachable)); + + auto flags = + WasmValidator::FlagValues::Globally | WasmValidator::FlagValues::Quiet; + EXPECT_FALSE(WasmValidator{}.validate(func.get(), module, flags)); +} diff --git a/test/lit/basic/custom-descriptors.wast b/test/lit/basic/custom-descriptors.wast index f1d302dbad5..8e0892f2d40 100644 --- a/test/lit/basic/custom-descriptors.wast +++ b/test/lit/basic/custom-descriptors.wast @@ -41,23 +41,39 @@ (rec - ;; CHECK-TEXT: (type $6 (func (param anyref (ref null $describing)))) + ;; CHECK-TEXT: (type $6 (func)) - ;; CHECK-TEXT: (type $7 (func (result anyref))) + ;; CHECK-TEXT: (type $7 (func (param anyref (ref null $describing)))) - ;; CHECK-TEXT: (type $8 (func (param anyref (ref null (exact $middle))) (result (ref null (exact $described))))) + ;; CHECK-TEXT: (type $8 (func (param (ref null $describing)))) - ;; CHECK-TEXT: (type $9 (func (result (ref (exact $pair))))) + ;; CHECK-TEXT: (type $9 (func (result anyref))) + + ;; CHECK-TEXT: (type $10 (func (param (ref null $middle)) (result anyref))) + + ;; CHECK-TEXT: (type $11 (func (param (ref null (exact $middle))) (result anyref))) + + ;; CHECK-TEXT: (type $12 (func (param anyref (ref null (exact $middle))) (result (ref null (exact $described))))) + + ;; CHECK-TEXT: (type $13 (func (result (ref (exact $pair))))) ;; CHECK-TEXT: (rec ;; CHECK-TEXT-NEXT: (type $shared-described (shared (descriptor $shared-describing (struct)))) - ;; CHECK-BIN: (type $6 (func (param anyref (ref null $describing)))) + ;; CHECK-BIN: (type $6 (func)) + + ;; CHECK-BIN: (type $7 (func (param anyref (ref null $describing)))) + + ;; CHECK-BIN: (type $8 (func (param (ref null $describing)))) - ;; CHECK-BIN: (type $7 (func (result anyref))) + ;; CHECK-BIN: (type $9 (func (result anyref))) - ;; CHECK-BIN: (type $8 (func (param anyref (ref null (exact $middle))) (result (ref null (exact $described))))) + ;; CHECK-BIN: (type $10 (func (param (ref null $middle)) (result anyref))) - ;; CHECK-BIN: (type $9 (func (result (ref (exact $pair))))) + ;; CHECK-BIN: (type $11 (func (param (ref null (exact $middle))) (result anyref))) + + ;; CHECK-BIN: (type $12 (func (param anyref (ref null (exact $middle))) (result (ref null (exact $described))))) + + ;; CHECK-BIN: (type $13 (func (result (ref (exact $pair))))) ;; CHECK-BIN: (rec ;; CHECK-BIN-NEXT: (type $shared-described (shared (descriptor $shared-describing (struct)))) @@ -69,18 +85,14 @@ - ;; CHECK-TEXT: (type $12 (func (param (ref null $described) (ref null (exact $middle))))) - - ;; CHECK-TEXT: (type $13 (func)) + ;; CHECK-TEXT: (type $16 (func (param (ref null $described) (ref null (exact $middle))))) - ;; CHECK-TEXT: (type $14 (func (param (ref any) (ref null $middle)) (result (ref null $described)))) + ;; CHECK-TEXT: (type $17 (func (param (ref any) (ref null $middle)) (result (ref null $described)))) ;; CHECK-TEXT: (global $g (ref null $described) (ref.null none)) - ;; CHECK-BIN: (type $12 (func (param (ref null $described) (ref null (exact $middle))))) + ;; CHECK-BIN: (type $16 (func (param (ref null $described) (ref null (exact $middle))))) - ;; CHECK-BIN: (type $13 (func)) - - ;; CHECK-BIN: (type $14 (func (param (ref any) (ref null $middle)) (result (ref null $described)))) + ;; CHECK-BIN: (type $17 (func (param (ref any) (ref null $middle)) (result (ref null $described)))) ;; CHECK-BIN: (global $g (ref null $described) (ref.null none)) (global $g (ref null $described) (ref.null none)) @@ -88,7 +100,7 @@ ;; CHECK-BIN: (global $shared (ref null $shared-describing) (ref.null (shared none))) (global $shared (ref null $shared-describing) (ref.null (shared none))) - ;; CHECK-TEXT: (func $ref-get-desc (type $12) (param $described (ref null $described)) (param $middle-exact (ref null (exact $middle))) + ;; CHECK-TEXT: (func $ref-get-desc (type $16) (param $described (ref null $described)) (param $middle-exact (ref null (exact $middle))) ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (block $l1 (result (ref $middle)) ;; CHECK-TEXT-NEXT: (ref.get_desc $described @@ -104,7 +116,7 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $ref-get-desc (type $12) (param $described (ref null $described)) (param $middle-exact (ref null (exact $middle))) + ;; CHECK-BIN: (func $ref-get-desc (type $16) (param $described (ref null $described)) (param $middle-exact (ref null (exact $middle))) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (block (result (ref $middle)) ;; CHECK-BIN-NEXT: (ref.get_desc $described @@ -137,7 +149,7 @@ ) ) - ;; CHECK-TEXT: (func $ref-get-desc-null (type $13) + ;; CHECK-TEXT: (func $ref-get-desc-null (type $6) ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (block ;; (replaces unreachable RefGetDesc we can't emit) ;; CHECK-TEXT-NEXT: (drop @@ -147,7 +159,7 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $ref-get-desc-null (type $13) + ;; CHECK-BIN: (func $ref-get-desc-null (type $6) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (ref.null none) ;; CHECK-BIN-NEXT: ) @@ -163,7 +175,7 @@ ) ) - ;; CHECK-TEXT: (func $br-on-cast-desc (type $6) (param $any anyref) (param $descriptor (ref null $describing)) + ;; CHECK-TEXT: (func $br-on-cast-desc (type $7) (param $any anyref) (param $descriptor (ref null $describing)) ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (block $l (result (ref null $middle)) ;; CHECK-TEXT-NEXT: (drop @@ -176,7 +188,7 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $br-on-cast-desc (type $6) (param $any anyref) (param $descriptor (ref null $describing)) + ;; CHECK-BIN: (func $br-on-cast-desc (type $7) (param $any anyref) (param $descriptor (ref null $describing)) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (block $block (result (ref null $middle)) ;; CHECK-BIN-NEXT: (drop @@ -201,7 +213,7 @@ ) ) - ;; CHECK-TEXT: (func $br-on-cast-desc-fail (type $6) (param $any anyref) (param $descriptor (ref null $describing)) + ;; CHECK-TEXT: (func $br-on-cast-desc-fail (type $7) (param $any anyref) (param $descriptor (ref null $describing)) ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (block $l (result anyref) ;; CHECK-TEXT-NEXT: (br_on_cast_desc_fail $l anyref (ref null $middle) @@ -211,7 +223,7 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $br-on-cast-desc-fail (type $6) (param $any anyref) (param $descriptor (ref null $describing)) + ;; CHECK-BIN: (func $br-on-cast-desc-fail (type $7) (param $any anyref) (param $descriptor (ref null $describing)) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (block $block (result anyref) ;; CHECK-BIN-NEXT: (br_on_cast_desc_fail $block anyref (ref null $middle) @@ -232,6 +244,134 @@ ) ) + ;; CHECK-TEXT: (func $br-on-cast-desc-unreachable (type $6) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $l (result (ref null $middle)) + ;; CHECK-TEXT-NEXT: (block ;; (replaces unreachable BrOn we can't emit) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $br-on-cast-desc-unreachable (type $6) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block (result (ref null $middle)) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $br-on-cast-desc-unreachable + (drop + (block $l (result (ref null $middle)) + (br_on_cast_desc $l anyref (ref null $middle) + (unreachable) + ) + (unreachable) + ) + ) + ) + + ;; CHECK-TEXT: (func $br-on-cast-desc-fail-unreachable (type $6) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $l (result (ref null $middle)) + ;; CHECK-TEXT-NEXT: (block ;; (replaces unreachable BrOn we can't emit) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $br-on-cast-desc-fail-unreachable (type $6) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block (result (ref null $middle)) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $br-on-cast-desc-fail-unreachable + (drop + (block $l (result (ref null $middle)) + (br_on_cast_desc_fail $l anyref (ref null $middle) + (unreachable) + ) + (unreachable) + ) + ) + ) + + ;; CHECK-TEXT: (func $br-on-cast-desc-unreachable-desc (type $8) (param $descriptor (ref null $describing)) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $l (result (ref null $middle)) + ;; CHECK-TEXT-NEXT: (br_on_cast_desc $l (ref null $middle) (ref null $middle) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (local.get $descriptor) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $br-on-cast-desc-unreachable-desc (type $8) (param $descriptor (ref null $describing)) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block (result (ref null $middle)) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $br-on-cast-desc-unreachable-desc (param $descriptor (ref null $describing)) + (drop + (block $l (result (ref null $middle)) + (br_on_cast_desc $l anyref (ref null $middle) + (unreachable) + (local.get $descriptor) + ) + (unreachable) + ) + ) + ) + + ;; CHECK-TEXT: (func $br-on-cast-desc-fail-unreachable-desc (type $8) (param $descriptor (ref null $describing)) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $l (result (ref null $middle)) + ;; CHECK-TEXT-NEXT: (br_on_cast_desc_fail $l (ref null $middle) (ref null $middle) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (local.get $descriptor) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $br-on-cast-desc-fail-unreachable-desc (type $8) (param $descriptor (ref null $describing)) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block (result (ref null $middle)) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $br-on-cast-desc-fail-unreachable-desc (param $descriptor (ref null $describing)) + (drop + (block $l (result (ref null $middle)) + (br_on_cast_desc_fail $l anyref (ref null $middle) + (unreachable) + (local.get $descriptor) + ) + (unreachable) + ) + ) + ) + ;; CHECK-TEXT: (func $br-on-cast-desc-null (type $3) (param $0 anyref) (result anyref) ;; CHECK-TEXT-NEXT: (block $label (result anyref) ;; CHECK-TEXT-NEXT: (block ;; (replaces unreachable BrOn we can't emit) @@ -290,7 +430,7 @@ ) ) - ;; CHECK-TEXT: (func $ref-cast-desc-null-unreachable (type $7) (result anyref) + ;; CHECK-TEXT: (func $ref-cast-desc-null-unreachable (type $9) (result anyref) ;; CHECK-TEXT-NEXT: (block ;; (replaces unreachable RefCast we can't emit) ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (unreachable) @@ -301,7 +441,7 @@ ;; CHECK-TEXT-NEXT: (unreachable) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $ref-cast-desc-null-unreachable (type $7) (result anyref) + ;; CHECK-BIN: (func $ref-cast-desc-null-unreachable (type $9) (result anyref) ;; CHECK-BIN-NEXT: (unreachable) ;; CHECK-BIN-NEXT: ) (func $ref-cast-desc-null-unreachable (result anyref) @@ -309,6 +449,70 @@ (ref.cast_desc (ref null $described)) ) + ;; CHECK-TEXT: (func $ref-cast-desc-null-unreachable-ref (type $10) (param $descriptor (ref null $middle)) (result anyref) + ;; CHECK-TEXT-NEXT: (ref.cast_desc (ref $described) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (local.get $descriptor) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $ref-cast-desc-null-unreachable-ref (type $10) (param $descriptor (ref null $middle)) (result anyref) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + (func $ref-cast-desc-null-unreachable-ref (param $descriptor (ref null $middle)) (result anyref) + (ref.cast_desc (ref null $described) + (unreachable) + (local.get $descriptor) + ) + ) + + ;; CHECK-TEXT: (func $ref-cast-desc-unreachable-ref (type $10) (param $descriptor (ref null $middle)) (result anyref) + ;; CHECK-TEXT-NEXT: (ref.cast_desc (ref $described) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (local.get $descriptor) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $ref-cast-desc-unreachable-ref (type $10) (param $descriptor (ref null $middle)) (result anyref) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + (func $ref-cast-desc-unreachable-ref (param $descriptor (ref null $middle)) (result anyref) + (ref.cast_desc (ref $described) + (unreachable) + (local.get $descriptor) + ) + ) + + ;; CHECK-TEXT: (func $ref-cast-desc-exact-null-unreachable-ref (type $11) (param $descriptor (ref null (exact $middle))) (result anyref) + ;; CHECK-TEXT-NEXT: (ref.cast_desc (ref (exact $described)) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (local.get $descriptor) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $ref-cast-desc-exact-null-unreachable-ref (type $11) (param $descriptor (ref null (exact $middle))) (result anyref) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + (func $ref-cast-desc-exact-null-unreachable-ref (param $descriptor (ref null (exact $middle))) (result anyref) + (ref.cast_desc (ref null (exact $described)) + (unreachable) + (local.get $descriptor) + ) + ) + + ;; CHECK-TEXT: (func $ref-cast-desc-exact-unreachable-ref (type $11) (param $descriptor (ref null (exact $middle))) (result anyref) + ;; CHECK-TEXT-NEXT: (ref.cast_desc (ref (exact $described)) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (local.get $descriptor) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $ref-cast-desc-exact-unreachable-ref (type $11) (param $descriptor (ref null (exact $middle))) (result anyref) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + (func $ref-cast-desc-exact-unreachable-ref (param $descriptor (ref null (exact $middle))) (result anyref) + (ref.cast_desc (ref (exact $described)) + (unreachable) + (local.get $descriptor) + ) + ) + ;; CHECK-TEXT: (func $ref-cast-desc-null-null (type $3) (param $0 anyref) (result anyref) ;; CHECK-TEXT-NEXT: (block ;; (replaces unreachable RefCast we can't emit) ;; CHECK-TEXT-NEXT: (drop @@ -336,13 +540,13 @@ ) ) - ;; CHECK-TEXT: (func $ref-cast-desc-null-exact (type $8) (param $any anyref) (param $middle (ref null (exact $middle))) (result (ref null (exact $described))) + ;; CHECK-TEXT: (func $ref-cast-desc-null-exact (type $12) (param $any anyref) (param $middle (ref null (exact $middle))) (result (ref null (exact $described))) ;; CHECK-TEXT-NEXT: (ref.cast_desc (ref null (exact $described)) ;; CHECK-TEXT-NEXT: (local.get $any) ;; CHECK-TEXT-NEXT: (local.get $middle) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $ref-cast-desc-null-exact (type $8) (param $any anyref) (param $middle (ref null (exact $middle))) (result (ref null (exact $described))) + ;; CHECK-BIN: (func $ref-cast-desc-null-exact (type $12) (param $any anyref) (param $middle (ref null (exact $middle))) (result (ref null (exact $described))) ;; CHECK-BIN-NEXT: (ref.cast_desc (ref null (exact $described)) ;; CHECK-BIN-NEXT: (local.get $any) ;; CHECK-BIN-NEXT: (local.get $middle) @@ -356,7 +560,7 @@ ) ) - ;; CHECK-TEXT: (func $ref-cast-desc-nn-unreachable (type $7) (result anyref) + ;; CHECK-TEXT: (func $ref-cast-desc-nn-unreachable (type $9) (result anyref) ;; CHECK-TEXT-NEXT: (block ;; (replaces unreachable RefCast we can't emit) ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (unreachable) @@ -367,7 +571,7 @@ ;; CHECK-TEXT-NEXT: (unreachable) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $ref-cast-desc-nn-unreachable (type $7) (result anyref) + ;; CHECK-BIN: (func $ref-cast-desc-nn-unreachable (type $9) (result anyref) ;; CHECK-BIN-NEXT: (unreachable) ;; CHECK-BIN-NEXT: ) (func $ref-cast-desc-nn-unreachable (result anyref) @@ -402,13 +606,13 @@ ) ) - ;; CHECK-TEXT: (func $ref-cast-desc-nn-exact (type $8) (param $any anyref) (param $middle (ref null (exact $middle))) (result (ref null (exact $described))) + ;; CHECK-TEXT: (func $ref-cast-desc-nn-exact (type $12) (param $any anyref) (param $middle (ref null (exact $middle))) (result (ref null (exact $described))) ;; CHECK-TEXT-NEXT: (ref.cast_desc (ref (exact $described)) ;; CHECK-TEXT-NEXT: (local.get $any) ;; CHECK-TEXT-NEXT: (local.get $middle) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $ref-cast-desc-nn-exact (type $8) (param $any anyref) (param $middle (ref null (exact $middle))) (result (ref null (exact $described))) + ;; CHECK-BIN: (func $ref-cast-desc-nn-exact (type $12) (param $any anyref) (param $middle (ref null (exact $middle))) (result (ref null (exact $described))) ;; CHECK-BIN-NEXT: (ref.cast_desc (ref (exact $described)) ;; CHECK-BIN-NEXT: (local.get $any) ;; CHECK-BIN-NEXT: (local.get $middle) @@ -422,13 +626,13 @@ ) ) - ;; CHECK-TEXT: (func $ref-cast-desc-nn-to-null (type $14) (param $any-nn (ref any)) (param $middle (ref null $middle)) (result (ref null $described)) + ;; CHECK-TEXT: (func $ref-cast-desc-nn-to-null (type $17) (param $any-nn (ref any)) (param $middle (ref null $middle)) (result (ref null $described)) ;; CHECK-TEXT-NEXT: (ref.cast_desc (ref $described) ;; CHECK-TEXT-NEXT: (local.get $any-nn) ;; CHECK-TEXT-NEXT: (local.get $middle) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $ref-cast-desc-nn-to-null (type $14) (param $any-nn (ref any)) (param $middle (ref null $middle)) (result (ref null $described)) + ;; CHECK-BIN: (func $ref-cast-desc-nn-to-null (type $17) (param $any-nn (ref any)) (param $middle (ref null $middle)) (result (ref null $described)) ;; CHECK-BIN-NEXT: (ref.cast_desc (ref $described) ;; CHECK-BIN-NEXT: (local.get $any-nn) ;; CHECK-BIN-NEXT: (local.get $middle) @@ -441,14 +645,14 @@ ) ) - ;; CHECK-TEXT: (func $struct-new (type $9) (result (ref (exact $pair))) + ;; CHECK-TEXT: (func $struct-new (type $13) (result (ref (exact $pair))) ;; CHECK-TEXT-NEXT: (struct.new $pair ;; CHECK-TEXT-NEXT: (i32.const 0) ;; CHECK-TEXT-NEXT: (i64.const 1) ;; CHECK-TEXT-NEXT: (struct.new_default $pair.desc) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $struct-new (type $9) (result (ref (exact $pair))) + ;; CHECK-BIN: (func $struct-new (type $13) (result (ref (exact $pair))) ;; CHECK-BIN-NEXT: (struct.new $pair ;; CHECK-BIN-NEXT: (i32.const 0) ;; CHECK-BIN-NEXT: (i64.const 1) @@ -463,12 +667,12 @@ ) ) - ;; CHECK-TEXT: (func $struct-new-default (type $9) (result (ref (exact $pair))) + ;; CHECK-TEXT: (func $struct-new-default (type $13) (result (ref (exact $pair))) ;; CHECK-TEXT-NEXT: (struct.new_default $pair ;; CHECK-TEXT-NEXT: (struct.new_default $pair.desc) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $struct-new-default (type $9) (result (ref (exact $pair))) + ;; CHECK-BIN: (func $struct-new-default (type $13) (result (ref (exact $pair))) ;; CHECK-BIN-NEXT: (struct.new_default $pair ;; CHECK-BIN-NEXT: (struct.new_default $pair.desc) ;; CHECK-BIN-NEXT: ) @@ -494,30 +698,36 @@ ;; CHECK-BIN-NODEBUG: (type $5 (describes $4 (struct))) -;; CHECK-BIN-NODEBUG: (type $6 (func (param anyref (ref null $2)))) +;; CHECK-BIN-NODEBUG: (type $6 (func)) -;; CHECK-BIN-NODEBUG: (type $7 (func (result anyref))) +;; CHECK-BIN-NODEBUG: (type $7 (func (param anyref (ref null $2)))) -;; CHECK-BIN-NODEBUG: (type $8 (func (param anyref (ref null (exact $1))) (result (ref null (exact $0))))) +;; CHECK-BIN-NODEBUG: (type $8 (func (param (ref null $2)))) -;; CHECK-BIN-NODEBUG: (type $9 (func (result (ref (exact $4))))) +;; CHECK-BIN-NODEBUG: (type $9 (func (result anyref))) -;; CHECK-BIN-NODEBUG: (rec -;; CHECK-BIN-NODEBUG-NEXT: (type $10 (shared (descriptor $11 (struct)))) +;; CHECK-BIN-NODEBUG: (type $10 (func (param (ref null $1)) (result anyref))) + +;; CHECK-BIN-NODEBUG: (type $11 (func (param (ref null (exact $1))) (result anyref))) -;; CHECK-BIN-NODEBUG: (type $11 (shared (describes $10 (struct)))) +;; CHECK-BIN-NODEBUG: (type $12 (func (param anyref (ref null (exact $1))) (result (ref null (exact $0))))) + +;; CHECK-BIN-NODEBUG: (type $13 (func (result (ref (exact $4))))) + +;; CHECK-BIN-NODEBUG: (rec +;; CHECK-BIN-NODEBUG-NEXT: (type $14 (shared (descriptor $15 (struct)))) -;; CHECK-BIN-NODEBUG: (type $12 (func (param (ref null $0) (ref null (exact $1))))) +;; CHECK-BIN-NODEBUG: (type $15 (shared (describes $14 (struct)))) -;; CHECK-BIN-NODEBUG: (type $13 (func)) +;; CHECK-BIN-NODEBUG: (type $16 (func (param (ref null $0) (ref null (exact $1))))) -;; CHECK-BIN-NODEBUG: (type $14 (func (param (ref any) (ref null $1)) (result (ref null $0)))) +;; CHECK-BIN-NODEBUG: (type $17 (func (param (ref any) (ref null $1)) (result (ref null $0)))) ;; CHECK-BIN-NODEBUG: (global $global$0 (ref null $0) (ref.null none)) -;; CHECK-BIN-NODEBUG: (global $global$1 (ref null $11) (ref.null (shared none))) +;; CHECK-BIN-NODEBUG: (global $global$1 (ref null $15) (ref.null (shared none))) -;; CHECK-BIN-NODEBUG: (func $0 (type $12) (param $0 (ref null $0)) (param $1 (ref null (exact $1))) +;; CHECK-BIN-NODEBUG: (func $0 (type $16) (param $0 (ref null $0)) (param $1 (ref null (exact $1))) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (block (result (ref $1)) ;; CHECK-BIN-NODEBUG-NEXT: (ref.get_desc $0 @@ -534,7 +744,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $1 (type $13) +;; CHECK-BIN-NODEBUG: (func $1 (type $6) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -543,7 +753,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $2 (type $6) (param $0 anyref) (param $1 (ref null $2)) +;; CHECK-BIN-NODEBUG: (func $2 (type $7) (param $0 anyref) (param $1 (ref null $2)) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (block $block (result (ref null $1)) ;; CHECK-BIN-NODEBUG-NEXT: (drop @@ -557,7 +767,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $3 (type $6) (param $0 anyref) (param $1 (ref null $2)) +;; CHECK-BIN-NODEBUG: (func $3 (type $7) (param $0 anyref) (param $1 (ref null $2)) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (block $block (result anyref) ;; CHECK-BIN-NODEBUG-NEXT: (br_on_cast_desc_fail $block anyref (ref null $1) @@ -568,7 +778,39 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $4 (type $3) (param $0 anyref) (result anyref) +;; CHECK-BIN-NODEBUG: (func $4 (type $6) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block (result (ref null $1)) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $6) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block (result (ref null $1)) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $8) (param $0 (ref null $2)) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block (result (ref null $1)) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $8) (param $0 (ref null $2)) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block (result (ref null $1)) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $8 (type $3) (param $0 anyref) (result anyref) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -578,7 +820,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: (unreachable) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $5 (type $3) (param $0 anyref) (result anyref) +;; CHECK-BIN-NODEBUG: (func $9 (type $3) (param $0 anyref) (result anyref) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -588,11 +830,27 @@ ;; CHECK-BIN-NODEBUG-NEXT: (unreachable) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $6 (type $7) (result anyref) +;; CHECK-BIN-NODEBUG: (func $10 (type $9) (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $11 (type $10) (param $0 (ref null $1)) (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $12 (type $10) (param $0 (ref null $1)) (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $13 (type $11) (param $0 (ref null (exact $1))) (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $14 (type $11) (param $0 (ref null (exact $1))) (result anyref) ;; CHECK-BIN-NODEBUG-NEXT: (unreachable) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $7 (type $3) (param $0 anyref) (result anyref) +;; CHECK-BIN-NODEBUG: (func $15 (type $3) (param $0 anyref) (result anyref) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -602,18 +860,18 @@ ;; CHECK-BIN-NODEBUG-NEXT: (unreachable) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $8 (type $8) (param $0 anyref) (param $1 (ref null (exact $1))) (result (ref null (exact $0))) +;; CHECK-BIN-NODEBUG: (func $16 (type $12) (param $0 anyref) (param $1 (ref null (exact $1))) (result (ref null (exact $0))) ;; CHECK-BIN-NODEBUG-NEXT: (ref.cast_desc (ref null (exact $0)) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $9 (type $7) (result anyref) +;; CHECK-BIN-NODEBUG: (func $17 (type $9) (result anyref) ;; CHECK-BIN-NODEBUG-NEXT: (unreachable) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $10 (type $3) (param $0 anyref) (result anyref) +;; CHECK-BIN-NODEBUG: (func $18 (type $3) (param $0 anyref) (result anyref) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -623,21 +881,21 @@ ;; CHECK-BIN-NODEBUG-NEXT: (unreachable) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $11 (type $8) (param $0 anyref) (param $1 (ref null (exact $1))) (result (ref null (exact $0))) +;; CHECK-BIN-NODEBUG: (func $19 (type $12) (param $0 anyref) (param $1 (ref null (exact $1))) (result (ref null (exact $0))) ;; CHECK-BIN-NODEBUG-NEXT: (ref.cast_desc (ref (exact $0)) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $12 (type $14) (param $0 (ref any)) (param $1 (ref null $1)) (result (ref null $0)) +;; CHECK-BIN-NODEBUG: (func $20 (type $17) (param $0 (ref any)) (param $1 (ref null $1)) (result (ref null $0)) ;; CHECK-BIN-NODEBUG-NEXT: (ref.cast_desc (ref $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $13 (type $9) (result (ref (exact $4))) +;; CHECK-BIN-NODEBUG: (func $21 (type $13) (result (ref (exact $4))) ;; CHECK-BIN-NODEBUG-NEXT: (struct.new $4 ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) ;; CHECK-BIN-NODEBUG-NEXT: (i64.const 1) @@ -645,7 +903,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $14 (type $9) (result (ref (exact $4))) +;; CHECK-BIN-NODEBUG: (func $22 (type $13) (result (ref (exact $4))) ;; CHECK-BIN-NODEBUG-NEXT: (struct.new_default $4 ;; CHECK-BIN-NODEBUG-NEXT: (struct.new_default $5) ;; CHECK-BIN-NODEBUG-NEXT: )