summaryrefslogtreecommitdiff
path: root/src/wasm/wasm.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-01-28 22:09:31 +0000
committerGitHub <noreply@github.com>2021-01-28 14:09:31 -0800
commit6299471584ce74d365526e33ed0a662bd2ee3490 (patch)
treed3aa2132d0897ea84bacab31c4e424780009efad /src/wasm/wasm.cpp
parent53c471a445ef26eac7befc3f3a5e0a53870df8cb (diff)
downloadbinaryen-6299471584ce74d365526e33ed0a662bd2ee3490.tar.gz
binaryen-6299471584ce74d365526e33ed0a662bd2ee3490.tar.bz2
binaryen-6299471584ce74d365526e33ed0a662bd2ee3490.zip
[GC] Add br_on_func/data/i31 (#3525)
This expands the existing BrOnCast into BrOn that can also handle the func/data/i31 variants. This is not as elegant as RefIs / RefAs in that BrOnCast has an extra rtt field, but I think it is still the best option. We already have optional fields on Break (the value and condition), so making rtt optional is not odd. And it allows us to share all the behavior of br_on_* which aside from the cast or the check itself, is identical - returning the value if the branch is not taken, etc.
Diffstat (limited to 'src/wasm/wasm.cpp')
-rw-r--r--src/wasm/wasm.cpp22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index 1e4ff6e3e..a62435412 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -931,15 +931,29 @@ void RefCast::finalize() {
Type RefCast::getCastType() { return doGetCastType(this); }
-void BrOnCast::finalize() {
- if (ref->type == Type::unreachable || rtt->type == Type::unreachable) {
+void BrOn::finalize() {
+ if (ref->type == Type::unreachable ||
+ (rtt && rtt->type == Type::unreachable)) {
type = Type::unreachable;
} else {
type = ref->type;
}
}
-Type BrOnCast::getCastType() { return Type(rtt->type.getHeapType(), Nullable); }
+Type BrOn::getCastType() {
+ switch (op) {
+ case BrOnCast:
+ return Type(rtt->type.getHeapType(), Nullable);
+ case BrOnFunc:
+ return Type::funcref;
+ case BrOnData:
+ return Type::dataref;
+ case BrOnI31:
+ return Type::i31ref;
+ default:
+ WASM_UNREACHABLE("invalid br_on_*");
+ }
+}
void RttCanon::finalize() {
// Nothing to do - the type must have been set already during construction.
@@ -1032,7 +1046,7 @@ void RefAs::finalize() {
type = Type::i31ref;
break;
default:
- WASM_UNREACHABLE("unimplemented ref.is_*");
+ WASM_UNREACHABLE("invalid ref.as_*");
}
}