From 4c53361b205ad30acc05136388b789296a4180f7 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 19 Dec 2023 11:10:27 -0800 Subject: [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. --- src/wasm/wasm.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src/wasm/wasm.cpp') diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 8ff2dc978..6589ca069 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -900,6 +900,47 @@ void Throw::finalize() { type = Type::unreachable; } void Rethrow::finalize() { type = Type::unreachable; } +void ThrowRef::finalize() { type = Type::unreachable; } + +bool TryTable::hasCatchAll() const { + return std::any_of( + catchTags.begin(), catchTags.end(), [](Name t) { return !t; }); +} + +static void populateTryTableSentTypes(TryTable* curr, Module* wasm) { + if (!wasm) { + return; + } + curr->sentTypes.clear(); + Type exnref = Type(HeapType::exn, Nullable); + for (Index i = 0; i < curr->catchTags.size(); i++) { + auto tagName = curr->catchTags[i]; + std::vector sentType; + if (tagName) { + for (auto t : wasm->getTag(tagName)->sig.params) { + sentType.push_back(t); + } + } + if (curr->catchRefs[i]) { + sentType.push_back(exnref); + } + curr->sentTypes.push_back(sentType.empty() ? Type::none : Type(sentType)); + } +} + +void TryTable::finalize(Module* wasm) { + type = body->type; + populateTryTableSentTypes(this, wasm); +} + +void TryTable::finalize(Type type_, Module* wasm) { + type = type_; + if (type == Type::none && body->type == Type::unreachable) { + type = Type::unreachable; + } + populateTryTableSentTypes(this, wasm); +} + void TupleMake::finalize() { std::vector types; types.reserve(operands.size()); -- cgit v1.2.3