summaryrefslogtreecommitdiff
path: root/src/ir/possible-contents.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/possible-contents.cpp')
-rw-r--r--src/ir/possible-contents.cpp34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp
index e7454c7c6..e5e6cf659 100644
--- a/src/ir/possible-contents.cpp
+++ b/src/ir/possible-contents.cpp
@@ -1135,8 +1135,38 @@ struct InfoCollector
}
}
void visitTryTable(TryTable* curr) {
- // TODO: optimize when possible
- addRoot(curr);
+ receiveChildValue(curr->body, curr);
+
+ // Connect caught tags with their branch targets, and materialize non-null
+ // exnref values.
+ auto numTags = curr->catchTags.size();
+ for (Index tagIndex = 0; tagIndex < numTags; tagIndex++) {
+ auto tag = curr->catchTags[tagIndex];
+ auto target = curr->catchDests[tagIndex];
+
+ Index exnrefIndex = 0;
+ if (tag.is()) {
+ auto params = getModule()->getTag(tag)->sig.params;
+
+ for (Index i = 0; i < params.size(); i++) {
+ if (isRelevant(params[i])) {
+ info.links.push_back(
+ {TagLocation{tag, i},
+ BreakTargetLocation{getFunction(), target, i}});
+ }
+ }
+
+ exnrefIndex = params.size();
+ }
+
+ if (curr->catchRefs[tagIndex]) {
+ auto location = CaughtExnRefLocation{};
+ addRoot(location,
+ PossibleContents::fromType(Type(HeapType::exn, NonNullable)));
+ info.links.push_back(
+ {location, BreakTargetLocation{getFunction(), target, exnrefIndex}});
+ }
+ }
}
void visitThrow(Throw* curr) {
auto& operands = curr->operands;