diff options
24 files changed, 179 insertions, 108 deletions
diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp index 7e202a5da..d3ca1c192 100644 --- a/src/ir/module-utils.cpp +++ b/src/ir/module-utils.cpp @@ -91,7 +91,6 @@ struct CodeScanner counts.note(cast->castType); } else if (auto* cast = curr->dynCast<BrOn>()) { if (cast->op == BrOnCast || cast->op == BrOnCastFail) { - counts.note(cast->ref->type); counts.note(cast->castType); } } else if (auto* get = curr->dynCast<StructGet>()) { diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 4bcc042a1..0d74d43f1 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2172,9 +2172,10 @@ struct PrintExpressionContents printMedium(o, "br_on_cast "); printName(curr->name, o); o << ' '; - printType(o, curr->ref->type, wasm); - o << ' '; - printType(o, curr->castType, wasm); + if (curr->castType.isNullable()) { + printMedium(o, "null "); + } + printHeapType(o, curr->castType.getHeapType(), wasm); return; case BrOnCastFail: // TODO: These instructions are deprecated, so stop emitting them. @@ -2196,9 +2197,10 @@ struct PrintExpressionContents printMedium(o, "br_on_cast_fail "); printName(curr->name, o); o << ' '; - printType(o, curr->ref->type, wasm); - o << ' '; - printType(o, curr->castType, wasm); + if (curr->castType.isNullable()) { + printMedium(o, "null "); + } + printHeapType(o, curr->castType.getHeapType(), wasm); return; } WASM_UNREACHABLE("Unexpected br_on* op"); diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 0a1fad332..d1b7b4923 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1119,12 +1119,16 @@ enum ASTNodes { I31GetU = 0x22, RefTest = 0x40, RefCast = 0x41, - BrOnCast = 0x4e, - BrOnCastFail = 0x4f, + BrOnCast = 0x42, + BrOnCastFail = 0x43, RefTestStatic = 0x44, RefCastStatic = 0x45, + BrOnCastStatic = 0x46, + BrOnCastStaticFail = 0x47, RefTestNull = 0x48, RefCastNull = 0x49, + BrOnCastNull = 0x4a, + BrOnCastFailNull = 0x4b, RefCastNop = 0x4c, RefAsFunc = 0x58, RefAsI31 = 0x5a, diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 133272a67..91309c906 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7034,10 +7034,14 @@ bool WasmBinaryBuilder::maybeVisitBrOn(Expression*& out, uint32_t code) { case BinaryConsts::BrOnNonNull: op = BrOnNonNull; break; + case BinaryConsts::BrOnCastStatic: case BinaryConsts::BrOnCast: + case BinaryConsts::BrOnCastNull: op = BrOnCast; break; + case BinaryConsts::BrOnCastStaticFail: case BinaryConsts::BrOnCastFail: + case BinaryConsts::BrOnCastFailNull: op = BrOnCastFail; break; case BinaryConsts::BrOnFunc: @@ -7059,24 +7063,18 @@ bool WasmBinaryBuilder::maybeVisitBrOn(Expression*& out, uint32_t code) { default: return false; } - uint8_t flags = 0; - if (op == BrOnCast || op == BrOnCastFail) { - flags = getInt8(); - } auto name = getBreakTarget(getU32LEB()).name; - auto* ref = popNonVoidExpression(); - if (op == BrOnCast || op == BrOnCastFail) { - auto inputNullability = (flags & 1) ? Nullable : NonNullable; - auto castNullability = (flags & 2) ? Nullable : NonNullable; - auto inputHeapType = getHeapType(); - auto castHeapType = getHeapType(); - auto inputType = Type(inputHeapType, inputNullability); - castType = Type(castHeapType, castNullability); - if (!Type::isSubType(ref->type, inputType)) { - throwError(std::string("Invalid reference type for ") + - ((op == BrOnCast) ? "br_on_cast" : "br_on_cast_fail")); - } + if (castType == Type::none && (op == BrOnCast || op == BrOnCastFail)) { + auto nullability = (code == BinaryConsts::BrOnCastNull || + code == BinaryConsts::BrOnCastFailNull) + ? Nullable + : NonNullable; + bool legacy = code == BinaryConsts::BrOnCastStatic || + code == BinaryConsts::BrOnCastStaticFail; + auto type = legacy ? getIndexedHeapType() : getHeapType(); + castType = Type(type, nullability); } + auto* ref = popNonVoidExpression(); out = Builder(wasm).makeBrOn(op, name, ref, castType); return true; } diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index a51ad3716..6adfb6149 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2892,16 +2892,16 @@ Expression* SExpressionWasmBuilder::makeBrOnCast(Element& s, bool onFail) { int i = 1; auto name = getLabel(*s[i++]); - std::optional<Type> inputType; if (!castType) { - inputType = elementToType(*s[i++]); - castType = elementToType(*s[i++]); + auto nullability = NonNullable; + if (s[i]->str().str == "null") { + nullability = Nullable; + ++i; + } + auto type = parseHeapType(*s[i++]); + castType = Type(type, nullability); } auto* ref = parseExpression(*s[i]); - if (inputType && !Type::isSubType(ref->type, *inputType)) { - throw ParseException( - "br_on_cast* ref type does not match expected type", s.line, s.col); - } auto op = onFail ? BrOnCastFail : BrOnCast; return Builder(wasm).makeBrOn(op, name, ref, *castType); } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index ee457da69..7a4dd3983 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2045,22 +2045,25 @@ void BinaryInstWriter::visitBrOn(BrOn* curr) { o << U32LEB(getBreakIndex(curr->name)); return; case BrOnCast: - case BrOnCastFail: { o << int8_t(BinaryConsts::GCPrefix); - if (curr->op == BrOnCast) { + if (curr->castType.isNullable()) { + o << U32LEB(BinaryConsts::BrOnCastNull); + } else { o << U32LEB(BinaryConsts::BrOnCast); + } + o << U32LEB(getBreakIndex(curr->name)); + parent.writeHeapType(curr->castType.getHeapType()); + return; + case BrOnCastFail: + o << int8_t(BinaryConsts::GCPrefix); + if (curr->castType.isNullable()) { + o << U32LEB(BinaryConsts::BrOnCastFailNull); } else { o << U32LEB(BinaryConsts::BrOnCastFail); } - assert(curr->ref->type.isRef()); - uint8_t flags = (curr->ref->type.isNullable() ? 1 : 0) | - (curr->castType.isNullable() ? 2 : 0); - o << flags; o << U32LEB(getBreakIndex(curr->name)); - parent.writeHeapType(curr->ref->type.getHeapType()); parent.writeHeapType(curr->castType.getHeapType()); return; - } } WASM_UNREACHABLE("invalid br_on_*"); } diff --git a/test/heap-types.wast b/test/heap-types.wast index 1d297f82e..afdb9128e 100644 --- a/test/heap-types.wast +++ b/test/heap-types.wast @@ -313,9 +313,7 @@ (drop (block $out-B (result (ref $struct.B)) (local.set $temp.A - (br_on_cast $out-B (ref null $struct.A) (ref $struct.B) - (ref.null $struct.A) - ) + (br_on_cast $out-B $struct.B (ref.null $struct.A)) ) (unreachable) ) @@ -323,9 +321,7 @@ (drop (block $out-A (result (ref null $struct.A)) (local.set $temp.B - (br_on_cast_fail $out-A (ref null $struct.A) (ref $struct.B) - (ref.null $struct.A) - ) + (br_on_cast_fail $out-A $struct.B (ref.null $struct.A)) ) (unreachable) ) diff --git a/test/heap-types.wast.from-wast b/test/heap-types.wast.from-wast index cab83fd5e..975d89b49 100644 --- a/test/heap-types.wast.from-wast +++ b/test/heap-types.wast.from-wast @@ -378,7 +378,7 @@ (drop (block $out-B (result (ref $struct.B)) (local.set $temp.A - (br_on_cast $out-B nullref (ref $struct.B) + (br_on_cast $out-B $struct.B (ref.null none) ) ) @@ -388,7 +388,7 @@ (drop (block $out-A (result (ref null $struct.A)) (local.set $temp.B - (br_on_cast_fail $out-A nullref (ref $struct.B) + (br_on_cast_fail $out-A $struct.B (ref.null none) ) ) diff --git a/test/heap-types.wast.fromBinary b/test/heap-types.wast.fromBinary index 7c304a906..99637f92b 100644 --- a/test/heap-types.wast.fromBinary +++ b/test/heap-types.wast.fromBinary @@ -331,7 +331,7 @@ (drop (block $label$1 (result (ref $struct.B)) (local.set $temp.A - (br_on_cast $label$1 nullref (ref $struct.B) + (br_on_cast $label$1 $struct.B (ref.null none) ) ) @@ -341,7 +341,7 @@ (drop (block $label$2 (result (ref null $struct.A)) (local.set $temp.B - (br_on_cast_fail $label$2 nullref (ref $struct.B) + (br_on_cast_fail $label$2 $struct.B (ref.null none) ) ) diff --git a/test/heap-types.wast.fromBinary.noDebugInfo b/test/heap-types.wast.fromBinary.noDebugInfo index 097e92a3d..3107269be 100644 --- a/test/heap-types.wast.fromBinary.noDebugInfo +++ b/test/heap-types.wast.fromBinary.noDebugInfo @@ -331,7 +331,7 @@ (drop (block $label$1 (result (ref ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|})) (local.set $0 - (br_on_cast $label$1 nullref (ref ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}) + (br_on_cast $label$1 ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|} (ref.null none) ) ) @@ -341,7 +341,7 @@ (drop (block $label$2 (result (ref null ${i32_f32_f64})) (local.set $1 - (br_on_cast_fail $label$2 nullref (ref ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}) + (br_on_cast_fail $label$2 ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|} (ref.null none) ) ) diff --git a/test/lit/binary/legacy-static-casts.test b/test/lit/binary/legacy-static-casts.test new file mode 100644 index 000000000..49ed204a7 --- /dev/null +++ b/test/lit/binary/legacy-static-casts.test @@ -0,0 +1,41 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; Test that the opcodes for the deprecated *_static cast instructions still parse. + +;; RUN: wasm-opt %s.wasm -all -S -o - | filecheck %s + +;; CHECK: (type ${} (struct )) + +;; CHECK: (type $none_=>_none (func)) + +;; CHECK: (func $0 (type $none_=>_none) +;; CHECK-NEXT: (drop +;; CHECK-NEXT: (ref.test ${} +;; CHECK-NEXT: (ref.null none) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (drop +;; CHECK-NEXT: (ref.cast null none +;; CHECK-NEXT: (ref.null none) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (drop +;; CHECK-NEXT: (ref.cast_nop none +;; CHECK-NEXT: (ref.null none) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (drop +;; CHECK-NEXT: (block $label$1 (result (ref null ${})) +;; CHECK-NEXT: (br_on_cast $label$1 ${} +;; CHECK-NEXT: (ref.null none) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (drop +;; CHECK-NEXT: (block $label$2 (result (ref null ${})) +;; CHECK-NEXT: (br_on_cast_fail $label$2 ${} +;; CHECK-NEXT: (ref.null none) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) diff --git a/test/lit/binary/legacy-static-casts.test.wasm b/test/lit/binary/legacy-static-casts.test.wasm Binary files differnew file mode 100644 index 000000000..aef179b2a --- /dev/null +++ b/test/lit/binary/legacy-static-casts.test.wasm diff --git a/test/lit/cast-to-basic.wast b/test/lit/cast-to-basic.wast index e66e3cd38..aa58e1f8e 100644 --- a/test/lit/cast-to-basic.wast +++ b/test/lit/cast-to-basic.wast @@ -35,7 +35,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $label$1 (result structref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $label$1 nullref (ref struct) + ;; CHECK-NEXT: (br_on_cast $label$1 struct ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -47,7 +47,7 @@ (drop (block $l (result structref) (drop - (br_on_cast $l nullref (ref struct) + (br_on_cast $l struct (ref.null none) ) ) @@ -60,7 +60,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $label$1 (result structref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $label$1 nullref structref + ;; CHECK-NEXT: (br_on_cast $label$1 null struct ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -72,7 +72,7 @@ (drop (block $l (result structref) (drop - (br_on_cast $l nullref structref + (br_on_cast $l null struct (ref.null none) ) ) @@ -85,7 +85,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $label$1 (result structref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast_fail $label$1 nullref structref + ;; CHECK-NEXT: (br_on_cast_fail $label$1 null struct ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -97,7 +97,7 @@ (drop (block $l (result structref) (drop - (br_on_cast_fail $l nullref structref + (br_on_cast_fail $l null struct (ref.null none) ) ) diff --git a/test/lit/legacy-static-casts.wast b/test/lit/legacy-static-casts.wast index 893fb0a33..dfef240d3 100644 --- a/test/lit/legacy-static-casts.wast +++ b/test/lit/legacy-static-casts.wast @@ -5,11 +5,11 @@ ;; RUN: wasm-opt %s -all -S -o - | filecheck %s (module - ;; CHECK: (type $none_=>_none (func)) - ;; CHECK: (type $struct (struct )) (type $struct (struct)) + ;; CHECK: (type $none_=>_none (func)) + ;; CHECK: (func $test (type $none_=>_none) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.test $struct @@ -26,6 +26,20 @@ ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $l1 (result (ref null $struct)) + ;; CHECK-NEXT: (br_on_cast $l1 $struct + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $l2 (result (ref null $struct)) + ;; CHECK-NEXT: (br_on_cast_fail $l2 $struct + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $test (drop @@ -43,5 +57,19 @@ (ref.null none) ) ) + (drop + (block $l1 (result (ref null $struct)) + (br_on_cast_static $l1 $struct + (ref.null none) + ) + ) + ) + (drop + (block $l2 (result (ref null $struct)) + (br_on_cast_static_fail $l2 $struct + (ref.null none) + ) + ) + ) ) ) diff --git a/test/lit/passes/abstract-type-refining.wast b/test/lit/passes/abstract-type-refining.wast index 8310d28d1..5fffa7972 100644 --- a/test/lit/passes/abstract-type-refining.wast +++ b/test/lit/passes/abstract-type-refining.wast @@ -178,7 +178,7 @@ ;; YESTNH-NEXT: (drop ;; YESTNH-NEXT: (block $block (result (ref $B)) ;; YESTNH-NEXT: (drop - ;; YESTNH-NEXT: (br_on_cast $block anyref (ref $B) + ;; YESTNH-NEXT: (br_on_cast $block $B ;; YESTNH-NEXT: (local.get $x) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) @@ -190,7 +190,7 @@ ;; NO_TNH-NEXT: (drop ;; NO_TNH-NEXT: (block $block (result anyref) ;; NO_TNH-NEXT: (drop - ;; NO_TNH-NEXT: (br_on_cast $block anyref (ref $A) + ;; NO_TNH-NEXT: (br_on_cast $block $A ;; NO_TNH-NEXT: (local.get $x) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) @@ -202,7 +202,7 @@ (drop (block $block (result anyref) (drop - (br_on_cast $block anyref (ref $A) + (br_on_cast $block $A (local.get $x) ) ) @@ -750,7 +750,7 @@ ;; YESTNH-NEXT: (drop ;; YESTNH-NEXT: (block $block (result (ref none)) ;; YESTNH-NEXT: (drop - ;; YESTNH-NEXT: (br_on_cast $block anyref (ref none) + ;; YESTNH-NEXT: (br_on_cast $block none ;; YESTNH-NEXT: (local.get $x) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) @@ -770,7 +770,7 @@ ;; NO_TNH-NEXT: (drop ;; NO_TNH-NEXT: (block $block (result (ref none)) ;; NO_TNH-NEXT: (drop - ;; NO_TNH-NEXT: (br_on_cast $block anyref (ref none) + ;; NO_TNH-NEXT: (br_on_cast $block none ;; NO_TNH-NEXT: (local.get $x) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) @@ -791,7 +791,7 @@ (drop (block $block (result anyref) (drop - (br_on_cast $block anyref (ref $B) + (br_on_cast $block $B (local.get $x) ) ) diff --git a/test/lit/passes/dce_all-features.wast b/test/lit/passes/dce_all-features.wast index 47838dbd6..adddfd3cc 100644 --- a/test/lit/passes/dce_all-features.wast +++ b/test/lit/passes/dce_all-features.wast @@ -1421,7 +1421,7 @@ (func $br_on_cast_fail (result (ref any)) (block $label$1 (result (ref none)) ;; Similar to the above, but using br_on_cast_fail. - (br_on_cast_fail $label$1 anyref structref + (br_on_cast_fail $label$1 null struct (unreachable) ) (unreachable) diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast index 6fb372d72..06998072b 100644 --- a/test/lit/passes/gufa-refs.wast +++ b/test/lit/passes/gufa-refs.wast @@ -988,7 +988,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $parent (result (ref $parent)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $parent (ref $unrelated) (ref $parent) + ;; CHECK-NEXT: (br_on_cast $parent $parent ;; CHECK-NEXT: (struct.new_default $unrelated) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1051,7 +1051,7 @@ (struct.get $parent 0 (block $parent (result (ref $parent)) (drop - (br_on_cast $parent anyref (ref $parent) + (br_on_cast $parent $parent (struct.new $unrelated) ) ) @@ -5344,7 +5344,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $B (result (ref $B)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $B (ref $A) (ref $B) + ;; CHECK-NEXT: (br_on_cast $B $B ;; CHECK-NEXT: (struct.new $A ;; CHECK-NEXT: (i32.const 100) ;; CHECK-NEXT: ) @@ -5361,7 +5361,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $A (result (ref $A)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $A (ref $A) (ref $A) + ;; CHECK-NEXT: (br_on_cast $A $A ;; CHECK-NEXT: (struct.new $A ;; CHECK-NEXT: (i32.const 200) ;; CHECK-NEXT: ) @@ -5387,7 +5387,7 @@ (drop (block $B (result (ref $B)) (drop - (br_on_cast $B anyref (ref $B) + (br_on_cast $B $B (struct.new $A (i32.const 100) ) @@ -5402,7 +5402,7 @@ (ref.test $A (block $A (result (ref $A)) (drop - (br_on_cast $A anyref (ref $A) + (br_on_cast $A $A (struct.new $A (i32.const 200) ) diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast index 369bd685c..20d6230be 100644 --- a/test/lit/passes/precompute-gc.wast +++ b/test/lit/passes/precompute-gc.wast @@ -860,7 +860,7 @@ ;; CHECK: (func $br_on_cast-on-creation (type $none_=>_ref|$empty|) (result (ref $empty)) ;; CHECK-NEXT: (block $label (result (ref $empty)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $label (ref $empty) (ref $empty) + ;; CHECK-NEXT: (br_on_cast $label $empty ;; CHECK-NEXT: (struct.new_default $empty) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -870,7 +870,7 @@ (func $br_on_cast-on-creation (result (ref $empty)) (block $label (result (ref $empty)) (drop - (br_on_cast $label anyref (ref $empty) + (br_on_cast $label $empty (struct.new_default $empty) ) ) diff --git a/test/lit/passes/remove-unused-brs-gc.wast b/test/lit/passes/remove-unused-brs-gc.wast index e063fa482..4fe7bd938 100644 --- a/test/lit/passes/remove-unused-brs-gc.wast +++ b/test/lit/passes/remove-unused-brs-gc.wast @@ -136,7 +136,7 @@ (drop ;; This static cast can be computed at compile time: it will definitely be ;; taken, so we can turn it into a normal br. - (br_on_cast $block anyref (ref $struct) + (br_on_cast $block $struct (struct.new $struct) ) ) @@ -157,7 +157,7 @@ ;; CHECK-NEXT: (local.get $nullable-struct2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $block (ref null $struct2) (ref null $struct) + ;; CHECK-NEXT: (br_on_cast $block null $struct ;; CHECK-NEXT: (local.get $nullable-struct2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -170,26 +170,26 @@ (drop ;; This cast can be computed at compile time: it will definitely fail, so we ;; can remove it. - (br_on_cast $block anyref (ref $struct) + (br_on_cast $block $struct (struct.new $struct2) ) ) (drop ;; We can still remove it even if the cast allows nulls. - (br_on_cast $block anyref (ref null $struct) + (br_on_cast $block null $struct (struct.new $struct2) ) ) (drop ;; Or if the cast does not allow nulls and the value is nullable. - (br_on_cast $block anyref (ref $struct) + (br_on_cast $block $struct (local.get $nullable-struct2) ) ) (drop ;; But if both are nullable, then we can't optimize because the cast would ;; succeed if the value is a null. - (br_on_cast $block anyref (ref null $struct) + (br_on_cast $block null $struct (local.get $nullable-struct2) ) ) @@ -216,7 +216,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast_fail $block (ref null $struct2) (ref null $struct) + ;; CHECK-NEXT: (br_on_cast_fail $block null $struct ;; CHECK-NEXT: (local.get $nullable-struct2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -229,26 +229,26 @@ (drop ;; This cast can be computed at compile time: it will definitely fail, so we ;; can replace it with an unconditional br. - (br_on_cast_fail $block anyref (ref $struct) + (br_on_cast_fail $block $struct (struct.new $struct2) ) ) (drop ;; We can still replace it even if the cast allows nulls. - (br_on_cast_fail $block anyref (ref null $struct) + (br_on_cast_fail $block null $struct (struct.new $struct2) ) ) (drop ;; Or if the cast does not allow nulls and the value is nullable. - (br_on_cast_fail $block anyref (ref $struct) + (br_on_cast_fail $block $struct (local.get $nullable-struct2) ) ) (drop ;; But if both are nullable, then we can't optimize because the cast would ;; succeed if the value is a null. - (br_on_cast_fail $block anyref (ref null $struct) + (br_on_cast_fail $block null $struct (local.get $nullable-struct2) ) ) @@ -260,7 +260,7 @@ ;; CHECK-NEXT: (local $struct (ref null $struct)) ;; CHECK-NEXT: (block $block (result (ref $struct)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $block (ref null $struct) (ref $struct) + ;; CHECK-NEXT: (br_on_cast $block $struct ;; CHECK-NEXT: (local.get $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -271,7 +271,7 @@ (local $struct (ref null $struct)) (block $block (result (ref $struct)) (drop - (br_on_cast $block anyref (ref $struct) + (br_on_cast $block $struct ;; As above, but now the type is nullable, so we cannot infer anything. (local.get $struct) ) @@ -293,7 +293,7 @@ (func $br_on_cast_nullable (result (ref null $struct)) (block $block (result (ref null $struct)) (drop - (br_on_cast $block anyref (ref null $struct) + (br_on_cast $block null $struct ;; As above, but now the cast allows nulls, so we can optimize. (ref.null $struct) ) @@ -315,7 +315,7 @@ (drop ;; As $br_on_cast, but this checks for a failing cast, so we know it will ;; *not* be taken. - (br_on_cast_fail $block anyref (ref $struct) + (br_on_cast_fail $block $struct (struct.new $struct) ) ) @@ -348,7 +348,7 @@ ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (block $something (result anyref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $something (ref null $struct) (ref $struct) + ;; CHECK-NEXT: (br_on_cast $something $struct ;; CHECK-NEXT: (local.get $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -403,7 +403,7 @@ (block (result anyref) (block $something (result anyref) (drop - (br_on_cast $something anyref (ref $struct) + (br_on_cast $something $struct (local.get $struct) ) ) diff --git a/test/lit/passes/type-merging-tnh.wast b/test/lit/passes/type-merging-tnh.wast index 0ec9ac38e..c84e31815 100644 --- a/test/lit/passes/type-merging-tnh.wast +++ b/test/lit/passes/type-merging-tnh.wast @@ -57,7 +57,7 @@ ;; CHECK: (func $test (type $ref|$A|_=>_ref|$B|) (param $a (ref $A)) (result (ref $B)) ;; CHECK-NEXT: (block $__binaryen_fake_return (result (ref $B)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $__binaryen_fake_return (ref $A) (ref $B) + ;; CHECK-NEXT: (br_on_cast $__binaryen_fake_return $B ;; CHECK-NEXT: (local.get $a) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -74,7 +74,7 @@ ;; CHECK-NEXT: ) (func $test (param $a (ref $A)) (result (ref $B)) (drop - (br_on_cast 0 anyref (ref $B) + (br_on_cast 0 $B (local.get $a) ) ) diff --git a/test/lit/passes/type-merging.wast b/test/lit/passes/type-merging.wast index 55ec42bd0..98ae92055 100644 --- a/test/lit/passes/type-merging.wast +++ b/test/lit/passes/type-merging.wast @@ -947,7 +947,7 @@ ;; CHECK: (func $test (type $ref|$A|_=>_ref|$B|) (param $a (ref $A)) (result (ref $B)) ;; CHECK-NEXT: (block $__binaryen_fake_return (result (ref $B)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $__binaryen_fake_return (ref $A) (ref $B) + ;; CHECK-NEXT: (br_on_cast $__binaryen_fake_return $B ;; CHECK-NEXT: (local.get $a) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -964,7 +964,7 @@ ;; CHECK-NEXT: ) (func $test (param $a (ref $A)) (result (ref $B)) (drop - (br_on_cast 0 anyref (ref $B) + (br_on_cast 0 $B (local.get $a) ) ) diff --git a/test/passes/Oz_fuzz-exec_all-features.txt b/test/passes/Oz_fuzz-exec_all-features.txt index 33760cae3..7b555cae0 100644 --- a/test/passes/Oz_fuzz-exec_all-features.txt +++ b/test/passes/Oz_fuzz-exec_all-features.txt @@ -156,7 +156,7 @@ (i32.const 1) ) (drop - (br_on_cast_fail $any (ref $struct) (ref $extendedstruct) + (br_on_cast_fail $any $extendedstruct (local.get $0) ) ) diff --git a/test/passes/Oz_fuzz-exec_all-features.wast b/test/passes/Oz_fuzz-exec_all-features.wast index 3155c3855..d7097ee1e 100644 --- a/test/passes/Oz_fuzz-exec_all-features.wast +++ b/test/passes/Oz_fuzz-exec_all-features.wast @@ -84,9 +84,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 anyref (ref $struct) + (br_on_cast $block $struct ;; first, try to cast our simple $struct to an extended, which will fail - (br_on_cast $extendedblock anyref (ref $extendedstruct) + (br_on_cast $extendedblock $extendedstruct (local.get $any) ) ) @@ -113,7 +113,7 @@ (drop ;; try to cast our simple $struct to an extended, which will fail, and ;; so we will branch, skipping the next logging. - (br_on_cast_fail $any anyref (ref $extendedstruct) + (br_on_cast_fail $any $extendedstruct (local.get $any) ) ) @@ -134,7 +134,7 @@ (drop ;; try to cast our simple $struct to an extended, which will succeed, and ;; so we will continue to the next logging. - (br_on_cast_fail $any anyref (ref $extendedstruct) + (br_on_cast_fail $any $extendedstruct (local.get $any) ) ) @@ -353,9 +353,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 anyref (ref $struct) + (br_on_cast $block $struct ;; first, try to cast our simple $struct to an extended, which will fail - (br_on_cast $extendedblock anyref (ref $extendedstruct) + (br_on_cast $extendedblock $extendedstruct (local.get $any) ) ) @@ -380,7 +380,7 @@ (block $failblock (result anyref) (drop ;; try to cast our simple $struct to an extended, which will fail - (br_on_cast_fail $failblock anyref (ref $extendedstruct) + (br_on_cast_fail $failblock $extendedstruct (local.get $any) ) ) diff --git a/test/spec/ref_cast.wast b/test/spec/ref_cast.wast index 8f7e3eb7f..f1cfbe24b 100644 --- a/test/spec/ref_cast.wast +++ b/test/spec/ref_cast.wast @@ -95,7 +95,7 @@ (drop (block $l (result (ref struct)) (drop - (br_on_cast $l anyref (ref struct) (struct.new $t0)) + (br_on_cast $l struct (struct.new $t0)) ) (return (i32.const 0)) ) @@ -107,7 +107,7 @@ (drop (block $l (result (ref null struct)) (drop - (br_on_cast $l anyref structref (ref.null none)) + (br_on_cast $l null struct (ref.null none)) ) (return (i32.const 0)) ) @@ -119,7 +119,7 @@ (drop (block $l (result (ref struct)) (drop - (br_on_cast_fail $l anyref (ref struct) (struct.new $t0)) + (br_on_cast_fail $l struct (struct.new $t0)) ) (return (i32.const 0)) ) @@ -131,7 +131,7 @@ (drop (block $l (result (ref struct)) (drop - (br_on_cast_fail $l anyref structref (ref.null none)) + (br_on_cast_fail $l null struct (ref.null none)) ) (return (i32.const 0)) ) |