diff options
author | Heejin Ahn <aheejin@gmail.com> | 2023-12-19 11:10:27 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-19 11:10:27 -0800 |
commit | 4c53361b205ad30acc05136388b789296a4180f7 (patch) | |
tree | a5802be899e365b733efacba4364027b0af9c2e0 /src/ir/branch-utils.h | |
parent | cad983c975a05bc262437a6d7ed3a61020ef4e8d (diff) | |
download | binaryen-4c53361b205ad30acc05136388b789296a4180f7.tar.gz binaryen-4c53361b205ad30acc05136388b789296a4180f7.tar.bz2 binaryen-4c53361b205ad30acc05136388b789296a4180f7.zip |
[EH] Add instructions for new proposal (#6181)
This adds basic support for the new instructions in the new EH proposal
passed at the Oct CG hybrid CG meeting:
https://github.com/WebAssembly/meetings/blob/main/main/2023/CG-10.md
https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md
This mainly adds two instructions: `try_table` and `throw_ref`. This is
the bare minimum required to read and write text and binary format, and
does not include analyses or optimizations. (It includes some analysis
required for validation of existing instructions.) Validation for
the new instructions is not yet included.
`try_table` faces the same problem with the `resume` instruction in
#6083 that without the module-level tag info, we are unable to know the
'sent types' of `try_table`. This solves it with a similar approach
taken in #6083: this adds `Module*` parameter to `finalize` methods,
which defaults to `nullptr` when not given. The `Module*` parameter is
given when called from the binary and text parser, and we cache those
tag types in `sentTypes` array within `TryTable` class. In later
optimization passes, as long as they don't touch tags, it is fine to
call `finalize` without the `Module*`. Refer to
https://github.com/WebAssembly/binaryen/pull/6083#issuecomment-1854634679
and #6096 for related discussions when `resume` was added.
Diffstat (limited to 'src/ir/branch-utils.h')
-rw-r--r-- | src/ir/branch-utils.h | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/src/ir/branch-utils.h b/src/ir/branch-utils.h index 9598e2830..3c0275701 100644 --- a/src/ir/branch-utils.h +++ b/src/ir/branch-utils.h @@ -75,6 +75,13 @@ void operateOnScopeNameUsesAndSentTypes(Expression* expr, T func) { func(name, sw->value ? sw->value->type : Type::none); } else if (auto* br = expr->dynCast<BrOn>()) { func(name, br->getSentType()); + } else if (auto* tt = expr->dynCast<TryTable>()) { + for (Index i = 0; i < tt->catchTags.size(); i++) { + auto dest = tt->catchDests[i]; + if (dest == name) { + func(name, tt->sentTypes[i]); + } + } } else { assert(expr->is<Try>() || expr->is<Rethrow>()); // delegate or rethrow } @@ -82,7 +89,8 @@ void operateOnScopeNameUsesAndSentTypes(Expression* expr, T func) { } // Similar to operateOnScopeNameUses, but also passes in the expression that is -// sent if the branch is taken. nullptr is given if there is no value. +// sent if the branch is taken. nullptr is given if there is no value or there +// is a value but it is not known statically. template<typename T> void operateOnScopeNameUsesAndSentValues(Expression* expr, T func) { operateOnScopeNameUses(expr, [&](Name& name) { @@ -94,6 +102,10 @@ void operateOnScopeNameUsesAndSentValues(Expression* expr, T func) { func(name, sw->value); } else if (auto* br = expr->dynCast<BrOn>()) { func(name, br->ref); + } else if (auto* tt = expr->dynCast<TryTable>()) { + // The values are supplied by throwing instructions, so we are unable to + // know what they will be here. + func(name, nullptr); } else { assert(expr->is<Try>() || expr->is<Rethrow>()); // delegate or rethrow } |