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.cpp49
1 files changed, 42 insertions, 7 deletions
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index f0d130d6b..b41f34ddf 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -916,22 +916,52 @@ void BrOn::finalize() {
if (ref->type == Type::unreachable ||
(rtt && rtt->type == Type::unreachable)) {
type = Type::unreachable;
- } else {
- if (op == BrOnNull) {
- // If BrOnNull does not branch, it flows out the existing value as
- // non-null.
+ return;
+ }
+ switch (op) {
+ case BrOnNull:
+ // If we do not branch, we flow out the existing value as non-null.
type = Type(ref->type.getHeapType(), NonNullable);
- } else {
+ break;
+ case BrOnNonNull:
+ // If we do not branch, we flow out nothing (the spec could also have had
+ // 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(rtt->type.getHeapType(), NonNullable);
+ break;
+ case BrOnNonFunc:
+ type = Type(HeapType::func, NonNullable);
+ break;
+ case BrOnNonData:
+ type = Type(HeapType::data, NonNullable);
+ break;
+ case BrOnNonI31:
+ type = Type(HeapType::i31, NonNullable);
+ break;
+ default:
+ WASM_UNREACHABLE("invalid br_on_*");
}
}
-Type BrOn::getCastType() {
+Type BrOn::getSentType() {
switch (op) {
case BrOnNull:
// BrOnNull does not send a value on the branch.
return Type::none;
+ case BrOnNonNull:
+ // BrOnNonNull sends the non-nullable type on the branch.
+ return Type(ref->type.getHeapType(), NonNullable);
case BrOnCast:
return Type(rtt->type.getHeapType(), NonNullable);
case BrOnFunc:
@@ -940,6 +970,11 @@ Type BrOn::getCastType() {
return Type::dataref;
case BrOnI31:
return Type::i31ref;
+ case BrOnCastFail:
+ case BrOnNonFunc:
+ case BrOnNonData:
+ case BrOnNonI31:
+ return ref->type;
default:
WASM_UNREACHABLE("invalid br_on_*");
}