summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2023-06-12 08:52:17 -0700
committerGitHub <noreply@github.com>2023-06-12 08:52:17 -0700
commitdc30f42a8c2da6c62e287fd881671b59b1866baa (patch)
tree539d683f9a9bbd96915d65bc631d6f0e6c40a5be
parent4ec79ce9826d96225d33dec77dfc344adab92606 (diff)
downloadbinaryen-dc30f42a8c2da6c62e287fd881671b59b1866baa.tar.gz
binaryen-dc30f42a8c2da6c62e287fd881671b59b1866baa.tar.bz2
binaryen-dc30f42a8c2da6c62e287fd881671b59b1866baa.zip
Update br_on_cast binary and text format (#5762)
The final versions of the br_on_cast and br_on_cast_fail instructions have two reference type annotations: one for the input type and one for the cast target type. In the binary format, this is represented as a flags byte followed by two encoded heap types. Upgrade all of the tests at once to use the new versions of the instructions and drop support for the old instructions from the text parser. Keep support in the binary parser to avoid breaking users, though. Drop some binary tests of deprecated instruction encodings that would be more effort to update than they're worth. Re-land with fixes of #5734
-rw-r--r--src/ir/module-utils.cpp1
-rw-r--r--src/passes/Print.cpp14
-rw-r--r--src/wasm-binary.h12
-rw-r--r--src/wasm/wasm-binary.cpp47
-rw-r--r--src/wasm/wasm-s-parser.cpp14
-rw-r--r--src/wasm/wasm-stack.cpp19
-rw-r--r--test/heap-types.wast8
-rw-r--r--test/heap-types.wast.from-wast4
-rw-r--r--test/heap-types.wast.fromBinary4
-rw-r--r--test/heap-types.wast.fromBinary.noDebugInfo4
-rw-r--r--test/lit/binary/legacy-static-casts.test41
-rw-r--r--test/lit/binary/legacy-static-casts.test.wasmbin66 -> 0 bytes
-rw-r--r--test/lit/cast-to-basic.wast12
-rw-r--r--test/lit/legacy-static-casts.wast32
-rw-r--r--test/lit/passes/abstract-type-refining.wast12
-rw-r--r--test/lit/passes/dce_all-features.wast2
-rw-r--r--test/lit/passes/gufa-refs.wast12
-rw-r--r--test/lit/passes/precompute-gc.wast4
-rw-r--r--test/lit/passes/remove-unused-brs-gc.wast34
-rw-r--r--test/lit/passes/type-merging-tnh.wast4
-rw-r--r--test/lit/passes/type-merging.wast4
-rw-r--r--test/passes/Oz_fuzz-exec_all-features.txt2
-rw-r--r--test/passes/Oz_fuzz-exec_all-features.wast14
-rw-r--r--test/spec/ref_cast.wast8
24 files changed, 129 insertions, 179 deletions
diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp
index d3ca1c192..7e202a5da 100644
--- a/src/ir/module-utils.cpp
+++ b/src/ir/module-utils.cpp
@@ -91,6 +91,7 @@ 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 0d74d43f1..4bcc042a1 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -2172,10 +2172,9 @@ struct PrintExpressionContents
printMedium(o, "br_on_cast ");
printName(curr->name, o);
o << ' ';
- if (curr->castType.isNullable()) {
- printMedium(o, "null ");
- }
- printHeapType(o, curr->castType.getHeapType(), wasm);
+ printType(o, curr->ref->type, wasm);
+ o << ' ';
+ printType(o, curr->castType, wasm);
return;
case BrOnCastFail:
// TODO: These instructions are deprecated, so stop emitting them.
@@ -2197,10 +2196,9 @@ struct PrintExpressionContents
printMedium(o, "br_on_cast_fail ");
printName(curr->name, o);
o << ' ';
- if (curr->castType.isNullable()) {
- printMedium(o, "null ");
- }
- printHeapType(o, curr->castType.getHeapType(), wasm);
+ printType(o, curr->ref->type, wasm);
+ o << ' ';
+ printType(o, curr->castType, wasm);
return;
}
WASM_UNREACHABLE("Unexpected br_on* op");
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index d1b7b4923..81cc80d22 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -1119,16 +1119,16 @@ enum ASTNodes {
I31GetU = 0x22,
RefTest = 0x40,
RefCast = 0x41,
- BrOnCast = 0x42,
- BrOnCastFail = 0x43,
+ BrOnCastLegacy = 0x42,
+ BrOnCastFailLegacy = 0x43,
+ BrOnCastNullLegacy = 0x4a,
+ BrOnCastFailNullLegacy = 0x4b,
+ BrOnCast = 0x4e,
+ BrOnCastFail = 0x4f,
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 7b3f741b6..ed27dd81a 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -7043,14 +7043,14 @@ bool WasmBinaryBuilder::maybeVisitBrOn(Expression*& out, uint32_t code) {
case BinaryConsts::BrOnNonNull:
op = BrOnNonNull;
break;
- case BinaryConsts::BrOnCastStatic:
case BinaryConsts::BrOnCast:
- case BinaryConsts::BrOnCastNull:
+ case BinaryConsts::BrOnCastLegacy:
+ case BinaryConsts::BrOnCastNullLegacy:
op = BrOnCast;
break;
- case BinaryConsts::BrOnCastStaticFail:
case BinaryConsts::BrOnCastFail:
- case BinaryConsts::BrOnCastFailNull:
+ case BinaryConsts::BrOnCastFailLegacy:
+ case BinaryConsts::BrOnCastFailNullLegacy:
op = BrOnCastFail;
break;
case BinaryConsts::BrOnFunc:
@@ -7072,18 +7072,37 @@ bool WasmBinaryBuilder::maybeVisitBrOn(Expression*& out, uint32_t code) {
default:
return false;
}
- auto name = getBreakTarget(getU32LEB()).name;
- 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);
+ bool hasInputAnnotation =
+ code == BinaryConsts::BrOnCast || code == BinaryConsts::BrOnCastFail;
+ uint8_t flags = 0;
+ if (hasInputAnnotation) {
+ flags = getInt8();
}
+ auto name = getBreakTarget(getU32LEB()).name;
auto* ref = popNonVoidExpression();
+ if (op == BrOnCast || op == BrOnCastFail) {
+ Nullability inputNullability, castNullability;
+ HeapType inputHeapType, castHeapType;
+ if (hasInputAnnotation) {
+ inputNullability = (flags & 1) ? Nullable : NonNullable;
+ castNullability = (flags & 2) ? Nullable : NonNullable;
+ inputHeapType = getHeapType();
+ } else {
+ castNullability = (code == BinaryConsts::BrOnCastNullLegacy ||
+ code == BinaryConsts::BrOnCastFailNullLegacy)
+ ? Nullable
+ : NonNullable;
+ }
+ castHeapType = getHeapType();
+ castType = Type(castHeapType, castNullability);
+ if (hasInputAnnotation) {
+ auto inputType = Type(inputHeapType, inputNullability);
+ if (!Type::isSubType(ref->type, inputType)) {
+ throwError(std::string("Invalid reference type for ") +
+ ((op == BrOnCast) ? "br_on_cast" : "br_on_cast_fail"));
+ }
+ }
+ }
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 6adfb6149..a51ad3716 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) {
- auto nullability = NonNullable;
- if (s[i]->str().str == "null") {
- nullability = Nullable;
- ++i;
- }
- auto type = parseHeapType(*s[i++]);
- castType = Type(type, nullability);
+ inputType = elementToType(*s[i++]);
+ castType = elementToType(*s[i++]);
}
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 7a4dd3983..ee457da69 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -2045,25 +2045,22 @@ void BinaryInstWriter::visitBrOn(BrOn* curr) {
o << U32LEB(getBreakIndex(curr->name));
return;
case BrOnCast:
+ case BrOnCastFail: {
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->castType.isNullable()) {
- o << U32LEB(BinaryConsts::BrOnCastNull);
- } else {
+ if (curr->op == BrOnCast) {
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 afdb9128e..1d297f82e 100644
--- a/test/heap-types.wast
+++ b/test/heap-types.wast
@@ -313,7 +313,9 @@
(drop
(block $out-B (result (ref $struct.B))
(local.set $temp.A
- (br_on_cast $out-B $struct.B (ref.null $struct.A))
+ (br_on_cast $out-B (ref null $struct.A) (ref $struct.B)
+ (ref.null $struct.A)
+ )
)
(unreachable)
)
@@ -321,7 +323,9 @@
(drop
(block $out-A (result (ref null $struct.A))
(local.set $temp.B
- (br_on_cast_fail $out-A $struct.B (ref.null $struct.A))
+ (br_on_cast_fail $out-A (ref null $struct.A) (ref $struct.B)
+ (ref.null $struct.A)
+ )
)
(unreachable)
)
diff --git a/test/heap-types.wast.from-wast b/test/heap-types.wast.from-wast
index 975d89b49..cab83fd5e 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 $struct.B
+ (br_on_cast $out-B nullref (ref $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 $struct.B
+ (br_on_cast_fail $out-A nullref (ref $struct.B)
(ref.null none)
)
)
diff --git a/test/heap-types.wast.fromBinary b/test/heap-types.wast.fromBinary
index 99637f92b..7c304a906 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 $struct.B
+ (br_on_cast $label$1 nullref (ref $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 $struct.B
+ (br_on_cast_fail $label$2 nullref (ref $struct.B)
(ref.null none)
)
)
diff --git a/test/heap-types.wast.fromBinary.noDebugInfo b/test/heap-types.wast.fromBinary.noDebugInfo
index 3107269be..097e92a3d 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 ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}
+ (br_on_cast $label$1 nullref (ref ${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 ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}
+ (br_on_cast_fail $label$2 nullref (ref ${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
deleted file mode 100644
index 49ed204a7..000000000
--- a/test/lit/binary/legacy-static-casts.test
+++ /dev/null
@@ -1,41 +0,0 @@
-;; 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
deleted file mode 100644
index aef179b2a..000000000
--- a/test/lit/binary/legacy-static-casts.test.wasm
+++ /dev/null
Binary files differ
diff --git a/test/lit/cast-to-basic.wast b/test/lit/cast-to-basic.wast
index aa58e1f8e..e66e3cd38 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 struct
+ ;; CHECK-NEXT: (br_on_cast $label$1 nullref (ref struct)
;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -47,7 +47,7 @@
(drop
(block $l (result structref)
(drop
- (br_on_cast $l struct
+ (br_on_cast $l nullref (ref 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 null struct
+ ;; CHECK-NEXT: (br_on_cast $label$1 nullref structref
;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -72,7 +72,7 @@
(drop
(block $l (result structref)
(drop
- (br_on_cast $l null struct
+ (br_on_cast $l nullref structref
(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 null struct
+ ;; CHECK-NEXT: (br_on_cast_fail $label$1 nullref structref
;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -97,7 +97,7 @@
(drop
(block $l (result structref)
(drop
- (br_on_cast_fail $l null struct
+ (br_on_cast_fail $l nullref structref
(ref.null none)
)
)
diff --git a/test/lit/legacy-static-casts.wast b/test/lit/legacy-static-casts.wast
index dfef240d3..893fb0a33 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,20 +26,6 @@
;; 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
@@ -57,19 +43,5 @@
(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 5fffa7972..8310d28d1 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 $B
+ ;; YESTNH-NEXT: (br_on_cast $block anyref (ref $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 $A
+ ;; NO_TNH-NEXT: (br_on_cast $block anyref (ref $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 $A
+ (br_on_cast $block anyref (ref $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 none
+ ;; YESTNH-NEXT: (br_on_cast $block anyref (ref 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 none
+ ;; NO_TNH-NEXT: (br_on_cast $block anyref (ref 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 $B
+ (br_on_cast $block anyref (ref $B)
(local.get $x)
)
)
diff --git a/test/lit/passes/dce_all-features.wast b/test/lit/passes/dce_all-features.wast
index adddfd3cc..47838dbd6 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 null struct
+ (br_on_cast_fail $label$1 anyref structref
(unreachable)
)
(unreachable)
diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast
index 06998072b..6fb372d72 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 $parent
+ ;; CHECK-NEXT: (br_on_cast $parent (ref $unrelated) (ref $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 $parent
+ (br_on_cast $parent anyref (ref $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 $B
+ ;; CHECK-NEXT: (br_on_cast $B (ref $A) (ref $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 $A
+ ;; CHECK-NEXT: (br_on_cast $A (ref $A) (ref $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 $B
+ (br_on_cast $B anyref (ref $B)
(struct.new $A
(i32.const 100)
)
@@ -5402,7 +5402,7 @@
(ref.test $A
(block $A (result (ref $A))
(drop
- (br_on_cast $A $A
+ (br_on_cast $A anyref (ref $A)
(struct.new $A
(i32.const 200)
)
diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast
index 20d6230be..369bd685c 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 $empty
+ ;; CHECK-NEXT: (br_on_cast $label (ref $empty) (ref $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 $empty
+ (br_on_cast $label anyref (ref $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 4fe7bd938..e063fa482 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 $struct
+ (br_on_cast $block anyref (ref $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 null $struct
+ ;; CHECK-NEXT: (br_on_cast $block (ref null $struct2) (ref 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 $struct
+ (br_on_cast $block anyref (ref $struct)
(struct.new $struct2)
)
)
(drop
;; We can still remove it even if the cast allows nulls.
- (br_on_cast $block null $struct
+ (br_on_cast $block anyref (ref null $struct)
(struct.new $struct2)
)
)
(drop
;; Or if the cast does not allow nulls and the value is nullable.
- (br_on_cast $block $struct
+ (br_on_cast $block anyref (ref $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 null $struct
+ (br_on_cast $block anyref (ref null $struct)
(local.get $nullable-struct2)
)
)
@@ -216,7 +216,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (br_on_cast_fail $block null $struct
+ ;; CHECK-NEXT: (br_on_cast_fail $block (ref null $struct2) (ref 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 $struct
+ (br_on_cast_fail $block anyref (ref $struct)
(struct.new $struct2)
)
)
(drop
;; We can still replace it even if the cast allows nulls.
- (br_on_cast_fail $block null $struct
+ (br_on_cast_fail $block anyref (ref null $struct)
(struct.new $struct2)
)
)
(drop
;; Or if the cast does not allow nulls and the value is nullable.
- (br_on_cast_fail $block $struct
+ (br_on_cast_fail $block anyref (ref $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 null $struct
+ (br_on_cast_fail $block anyref (ref 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 $struct
+ ;; CHECK-NEXT: (br_on_cast $block (ref null $struct) (ref $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 $struct
+ (br_on_cast $block anyref (ref $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 null $struct
+ (br_on_cast $block anyref (ref 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 $struct
+ (br_on_cast_fail $block anyref (ref $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 $struct
+ ;; CHECK-NEXT: (br_on_cast $something (ref null $struct) (ref $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 $struct
+ (br_on_cast $something anyref (ref $struct)
(local.get $struct)
)
)
diff --git a/test/lit/passes/type-merging-tnh.wast b/test/lit/passes/type-merging-tnh.wast
index c84e31815..0ec9ac38e 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 $B
+ ;; CHECK-NEXT: (br_on_cast $__binaryen_fake_return (ref $A) (ref $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 $B
+ (br_on_cast 0 anyref (ref $B)
(local.get $a)
)
)
diff --git a/test/lit/passes/type-merging.wast b/test/lit/passes/type-merging.wast
index 98ae92055..55ec42bd0 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 $B
+ ;; CHECK-NEXT: (br_on_cast $__binaryen_fake_return (ref $A) (ref $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 $B
+ (br_on_cast 0 anyref (ref $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 7b555cae0..33760cae3 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 $extendedstruct
+ (br_on_cast_fail $any (ref $struct) (ref $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 d7097ee1e..3155c3855 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 $struct
+ (br_on_cast $block anyref (ref $struct)
;; first, try to cast our simple $struct to an extended, which will fail
- (br_on_cast $extendedblock $extendedstruct
+ (br_on_cast $extendedblock anyref (ref $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 $extendedstruct
+ (br_on_cast_fail $any anyref (ref $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 $extendedstruct
+ (br_on_cast_fail $any anyref (ref $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 $struct
+ (br_on_cast $block anyref (ref $struct)
;; first, try to cast our simple $struct to an extended, which will fail
- (br_on_cast $extendedblock $extendedstruct
+ (br_on_cast $extendedblock anyref (ref $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 $extendedstruct
+ (br_on_cast_fail $failblock anyref (ref $extendedstruct)
(local.get $any)
)
)
diff --git a/test/spec/ref_cast.wast b/test/spec/ref_cast.wast
index f1cfbe24b..8f7e3eb7f 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 struct (struct.new $t0))
+ (br_on_cast $l anyref (ref struct) (struct.new $t0))
)
(return (i32.const 0))
)
@@ -107,7 +107,7 @@
(drop
(block $l (result (ref null struct))
(drop
- (br_on_cast $l null struct (ref.null none))
+ (br_on_cast $l anyref structref (ref.null none))
)
(return (i32.const 0))
)
@@ -119,7 +119,7 @@
(drop
(block $l (result (ref struct))
(drop
- (br_on_cast_fail $l struct (struct.new $t0))
+ (br_on_cast_fail $l anyref (ref struct) (struct.new $t0))
)
(return (i32.const 0))
)
@@ -131,7 +131,7 @@
(drop
(block $l (result (ref struct))
(drop
- (br_on_cast_fail $l null struct (ref.null none))
+ (br_on_cast_fail $l anyref structref (ref.null none))
)
(return (i32.const 0))
)