summaryrefslogtreecommitdiff
path: root/src/wasm/wasm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm.cpp')
-rw-r--r--src/wasm/wasm.cpp46
1 files changed, 34 insertions, 12 deletions
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index 682936461..de18966ff 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -968,18 +968,12 @@ void BrOn::finalize() {
// us flow out the null, but it does not).
type = Type::none;
break;
- case BrOnCast:
case BrOnFunc:
case BrOnData:
case BrOnI31:
// If we do not branch, we return the input in this case.
type = ref->type;
break;
- case BrOnCastFail:
- // If we do not branch, the cast worked, and we have something of the cast
- // type.
- type = Type(intendedType, NonNullable);
- break;
case BrOnNonFunc:
type = Type(HeapType::func, NonNullable);
break;
@@ -989,6 +983,26 @@ void BrOn::finalize() {
case BrOnNonI31:
type = Type(HeapType::i31, NonNullable);
break;
+ case BrOnCast:
+ if (castType.isNullable()) {
+ // Nulls take the branch, so the result is non-nullable.
+ type = Type(ref->type.getHeapType(), NonNullable);
+ } else {
+ // Nulls do not take the branch, so the result is non-nullable only if
+ // the input is.
+ type = ref->type;
+ }
+ break;
+ case BrOnCastFail:
+ if (castType.isNullable()) {
+ // Nulls do not take the branch, so the result is non-nullable only if
+ // the input is.
+ type = Type(castType.getHeapType(), ref->type.getNullability());
+ } else {
+ // Nulls take the branch, so the result is non-nullable.
+ type = castType;
+ }
+ break;
default:
WASM_UNREACHABLE("invalid br_on_*");
}
@@ -1007,22 +1021,30 @@ Type BrOn::getSentType() {
}
// BrOnNonNull sends the non-nullable type on the branch.
return Type(ref->type.getHeapType(), NonNullable);
- case BrOnCast:
- if (ref->type == Type::unreachable) {
- return Type::unreachable;
- }
- return Type(intendedType, NonNullable);
case BrOnFunc:
return Type(HeapType::func, NonNullable);
case BrOnData:
return Type(HeapType::data, NonNullable);
case BrOnI31:
return Type(HeapType::i31, NonNullable);
- case BrOnCastFail:
case BrOnNonFunc:
case BrOnNonData:
case BrOnNonI31:
return ref->type;
+ case BrOnCast:
+ // The same as the result type of br_on_cast_fail.
+ if (castType.isNullable()) {
+ return Type(castType.getHeapType(), ref->type.getNullability());
+ } else {
+ return castType;
+ }
+ case BrOnCastFail:
+ // The same as the result type of br_on_cast.
+ if (castType.isNullable()) {
+ return Type(ref->type.getHeapType(), NonNullable);
+ } else {
+ return ref->type;
+ }
default:
WASM_UNREACHABLE("invalid br_on_*");
}