summaryrefslogtreecommitdiff
path: root/src/ir/eh-utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/eh-utils.cpp')
-rw-r--r--src/ir/eh-utils.cpp84
1 files changed, 43 insertions, 41 deletions
diff --git a/src/ir/eh-utils.cpp b/src/ir/eh-utils.cpp
index 37af738ce..3d369573d 100644
--- a/src/ir/eh-utils.cpp
+++ b/src/ir/eh-utils.cpp
@@ -107,54 +107,56 @@ bool containsValidDanglingPop(Expression* catchBody) {
return pop != nullptr && !isPopNested;
}
+void handleBlockNestedPop(Try* try_, Function* func, Module& wasm) {
+ Builder builder(wasm);
+ for (Index i = 0; i < try_->catchTags.size(); i++) {
+ Name tagName = try_->catchTags[i];
+ auto* tag = wasm.getTag(tagName);
+ if (tag->sig.params == Type::none) {
+ continue;
+ }
+
+ auto* catchBody = try_->catchBodies[i];
+ bool isPopNested = false;
+ Expression** popPtr = nullptr;
+ Expression* pop = getFirstPop(catchBody, isPopNested, popPtr);
+ assert(pop && "Pop has not been found in this catch");
+
+ // Change code like
+ // (catch $e
+ // ...
+ // (block
+ // (pop i32)
+ // )
+ // )
+ // into
+ // (catch $e
+ // (local.set $new
+ // (pop i32)
+ // )
+ // ...
+ // (block
+ // (local.get $new)
+ // )
+ // )
+ if (isPopNested) {
+ assert(popPtr);
+ Index newLocal = builder.addVar(func, pop->type);
+ try_->catchBodies[i] =
+ builder.makeSequence(builder.makeLocalSet(newLocal, pop), catchBody);
+ *popPtr = builder.makeLocalGet(newLocal, pop->type);
+ }
+ }
+}
+
void handleBlockNestedPops(Function* func, Module& wasm) {
if (!wasm.features.hasExceptionHandling()) {
return;
}
-
- Builder builder(wasm);
FindAll<Try> trys(func->body);
for (auto* try_ : trys.list) {
- for (Index i = 0; i < try_->catchTags.size(); i++) {
- Name tagName = try_->catchTags[i];
- auto* tag = wasm.getTag(tagName);
- if (tag->sig.params == Type::none) {
- continue;
- }
-
- auto* catchBody = try_->catchBodies[i];
- bool isPopNested = false;
- Expression** popPtr = nullptr;
- Expression* pop = getFirstPop(catchBody, isPopNested, popPtr);
- assert(pop && "Pop has not been found in this catch");
-
- // Change code like
- // (catch $e
- // ...
- // (block
- // (pop i32)
- // )
- // )
- // into
- // (catch $e
- // (local.set $new
- // (pop i32)
- // )
- // ...
- // (block
- // (local.get $new)
- // )
- // )
- if (isPopNested) {
- assert(popPtr);
- Index newLocal = builder.addVar(func, pop->type);
- try_->catchBodies[i] =
- builder.makeSequence(builder.makeLocalSet(newLocal, pop), catchBody);
- *popPtr = builder.makeLocalGet(newLocal, pop->type);
- }
- }
+ handleBlockNestedPop(try_, func, wasm);
}
-
// Pops we handled can be of non-defaultable types, so we may have created
// non-nullable type locals. Fix them.
TypeUpdating::handleNonDefaultableLocals(func, wasm);