summaryrefslogtreecommitdiff
path: root/src/wasm-interpreter.h
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-09-20 10:47:14 -0700
committerGitHub <noreply@github.com>2021-09-20 17:47:14 +0000
commit737c22d30798c491eea3b401b948b9327ac979de (patch)
treef75a72adbd81a85eca19b732378837670c828b23 /src/wasm-interpreter.h
parentb5e8c371001de20128453d5064ac0422d481020e (diff)
downloadbinaryen-737c22d30798c491eea3b401b948b9327ac979de.tar.gz
binaryen-737c22d30798c491eea3b401b948b9327ac979de.tar.bz2
binaryen-737c22d30798c491eea3b401b948b9327ac979de.zip
[Wasm GC] Add static variants of ref.test, ref.cast, and br_on_cast* (#4163)
These variants take a HeapType that is the type we intend to cast to, and do not take an RTT. These are intended to be more statically optimizable. For now though this PR just implements the minimum to get them parsing and to get through the optimizer without crashing. Spec: https://docs.google.com/document/d/1afthjsL_B9UaMqCA5ekgVmOm75BVFu6duHNsN9-gnXw/edit# See #4149
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r--src/wasm-interpreter.h59
1 files changed, 40 insertions, 19 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index ca456406f..53d3048b7 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1424,11 +1424,16 @@ public:
cast.breaking = ref;
return cast;
}
- Flow rtt = this->visit(curr->rtt);
- if (rtt.breaking()) {
- cast.outcome = cast.Break;
- cast.breaking = rtt;
- return cast;
+ Literal intendedRtt;
+ if (curr->rtt) {
+ // This is a dynamic check with an rtt.
+ Flow rtt = this->visit(curr->rtt);
+ if (rtt.breaking()) {
+ cast.outcome = cast.Break;
+ cast.breaking = rtt;
+ return cast;
+ }
+ intendedRtt = rtt.getSingleValue();
}
cast.originalRef = ref.getSingleValue();
if (cast.originalRef.isNull()) {
@@ -1443,8 +1448,6 @@ public:
cast.outcome = cast.Failure;
return cast;
}
- Literal seenRtt;
- Literal intendedRtt = rtt.getSingleValue();
if (cast.originalRef.isFunction()) {
// Function casts are simple in that they have no RTT hierarchies; instead
// each reference has the canonical RTT for the signature.
@@ -1460,24 +1463,42 @@ public:
cast.breaking = NONCONSTANT_FLOW;
return cast;
}
- seenRtt = Literal(Type(Rtt(0, func->type)));
- if (!seenRtt.isSubRtt(intendedRtt)) {
- cast.outcome = cast.Failure;
- return cast;
+ if (curr->rtt) {
+ Literal seenRtt = Literal(Type(Rtt(0, func->type)));
+ if (!seenRtt.isSubRtt(intendedRtt)) {
+ cast.outcome = cast.Failure;
+ return cast;
+ }
+ cast.castRef = Literal(
+ func->name, Type(intendedRtt.type.getHeapType(), NonNullable));
+ } else {
+ if (!HeapType::isSubType(func->type, curr->intendedType)) {
+ cast.outcome = cast.Failure;
+ return cast;
+ }
+ cast.castRef =
+ Literal(func->name, Type(curr->intendedType, NonNullable));
}
- cast.castRef =
- Literal(func->name, Type(intendedRtt.type.getHeapType(), NonNullable));
} else {
// GC data store an RTT in each instance.
assert(cast.originalRef.isData());
auto gcData = cast.originalRef.getGCData();
- seenRtt = gcData->rtt;
- if (!seenRtt.isSubRtt(intendedRtt)) {
- cast.outcome = cast.Failure;
- return cast;
+ Literal seenRtt = gcData->rtt;
+ if (curr->rtt) {
+ if (!seenRtt.isSubRtt(intendedRtt)) {
+ cast.outcome = cast.Failure;
+ return cast;
+ }
+ cast.castRef =
+ Literal(gcData, Type(intendedRtt.type.getHeapType(), NonNullable));
+ } else {
+ auto seenType = seenRtt.type.getHeapType();
+ if (!HeapType::isSubType(seenType, curr->intendedType)) {
+ cast.outcome = cast.Failure;
+ return cast;
+ }
+ cast.castRef = Literal(gcData, Type(seenType, NonNullable));
}
- cast.castRef =
- Literal(gcData, Type(intendedRtt.type.getHeapType(), NonNullable));
}
cast.outcome = cast.Success;
return cast;