summaryrefslogtreecommitdiff
path: root/src/passes/LocalSubtyping.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-08-02 11:38:50 -0700
committerGitHub <noreply@github.com>2021-08-02 11:38:50 -0700
commitcde2830e44a3248d0f2d9750f180635c0465a579 (patch)
treeb827176989ec5002612518328aab77a4b9762b4a /src/passes/LocalSubtyping.cpp
parent7835f7d4d4d2d0118ba40b9f60fb32de8a43c272 (diff)
downloadbinaryen-cde2830e44a3248d0f2d9750f180635c0465a579.tar.gz
binaryen-cde2830e44a3248d0f2d9750f180635c0465a579.tar.bz2
binaryen-cde2830e44a3248d0f2d9750f180635c0465a579.zip
[Wasm GC] Handle unreachability in LocalSubtyping (#4044)
Diffstat (limited to 'src/passes/LocalSubtyping.cpp')
-rw-r--r--src/passes/LocalSubtyping.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/passes/LocalSubtyping.cpp b/src/passes/LocalSubtyping.cpp
index ae197858c..19ce2f275 100644
--- a/src/passes/LocalSubtyping.cpp
+++ b/src/passes/LocalSubtyping.cpp
@@ -102,6 +102,7 @@ struct LocalSubtyping : public WalkerPass<PostWalker<LocalSubtyping>> {
// TODO: handle cycles of X -> Y -> X etc.
bool more;
+ bool optimized = false;
do {
more = false;
@@ -150,6 +151,7 @@ struct LocalSubtyping : public WalkerPass<PostWalker<LocalSubtyping>> {
assert(Type::isSubType(newType, oldType));
func->vars[i - varBase] = newType;
more = true;
+ optimized = true;
// Update gets and tees.
for (auto* get : getsForLocal[i]) {
@@ -167,6 +169,24 @@ struct LocalSubtyping : public WalkerPass<PostWalker<LocalSubtyping>> {
}
}
} while (more);
+
+ // If we ever optimized, then we also need to do a final pass to update any
+ // unreachable gets and tees. They are not seen or updated in the above
+ // analysis, but must be fixed up for validation to work.
+ if (optimized) {
+ for (auto* get : FindAll<LocalGet>(func->body).list) {
+ get->type = func->getLocalType(get->index);
+ }
+ for (auto* set : FindAll<LocalSet>(func->body).list) {
+ if (set->isTee()) {
+ set->type = func->getLocalType(set->index);
+ set->finalize();
+ }
+ }
+
+ // Also update their parents.
+ ReFinalize().walkFunctionInModule(func, getModule());
+ }
}
};