summaryrefslogtreecommitdiff
path: root/src/ir/effects.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/effects.h')
-rw-r--r--src/ir/effects.h26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/ir/effects.h b/src/ir/effects.h
index fee8b3441..716624d64 100644
--- a/src/ir/effects.h
+++ b/src/ir/effects.h
@@ -431,6 +431,14 @@ private:
self->pushTask(doStartTry, currp);
return;
}
+ if (auto* tryTable = curr->dynCast<TryTable>()) {
+ // We need to increment try depth before starting.
+ self->pushTask(doEndTryTable, currp);
+ self->pushTask(doVisitTryTable, currp);
+ self->pushTask(scan, &tryTable->body);
+ self->pushTask(doStartTryTable, currp);
+ return;
+ }
PostWalker<InternalAnalyzer, OverriddenVisitor<InternalAnalyzer>>::scan(
self, currp);
}
@@ -472,6 +480,24 @@ private:
self->parent.catchDepth--;
}
+ static void doStartTryTable(InternalAnalyzer* self, Expression** currp) {
+ auto* curr = (*currp)->cast<TryTable>();
+ // We only count 'try_table's with a 'catch_all' because instructions
+ // within a 'try_table' without a 'catch_all' can still throw outside of
+ // the try.
+ if (curr->hasCatchAll()) {
+ self->parent.tryDepth++;
+ }
+ }
+
+ static void doEndTryTable(InternalAnalyzer* self, Expression** currp) {
+ auto* curr = (*currp)->cast<TryTable>();
+ if (curr->hasCatchAll()) {
+ assert(self->parent.tryDepth > 0 && "try depth cannot be negative");
+ self->parent.tryDepth--;
+ }
+ }
+
void visitBlock(Block* curr) {
if (curr->name.is()) {
parent.breakTargets.erase(curr->name); // these were internal breaks