diff options
author | Alon Zakai <azakai@google.com> | 2021-08-02 11:38:50 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-02 11:38:50 -0700 |
commit | cde2830e44a3248d0f2d9750f180635c0465a579 (patch) | |
tree | b827176989ec5002612518328aab77a4b9762b4a /src/passes/LocalSubtyping.cpp | |
parent | 7835f7d4d4d2d0118ba40b9f60fb32de8a43c272 (diff) | |
download | binaryen-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.cpp | 20 |
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()); + } } }; |