summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-binary.cpp30
-rw-r--r--src/wasm/wasm-s-parser.cpp14
-rw-r--r--src/wasm/wasm-stack.cpp19
3 files changed, 32 insertions, 31 deletions
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_*");
}