summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2021-10-21 16:44:58 -0700
committerGitHub <noreply@github.com>2021-10-21 16:44:58 -0700
commit1a7169113a65a401cd2ccfd3beb988b38cda9728 (patch)
tree3895fb800e66e80cf97628ce299d0065e6c217f6 /src
parent4bac51d1d9a98e853fb7f75341820cda425393eb (diff)
downloadbinaryen-1a7169113a65a401cd2ccfd3beb988b38cda9728.tar.gz
binaryen-1a7169113a65a401cd2ccfd3beb988b38cda9728.tar.bz2
binaryen-1a7169113a65a401cd2ccfd3beb988b38cda9728.zip
[EH] Support try-delegate in CFGWalker (#4269)
This adds support for `try`-`delegate` to `CFGWalker`. This also adds a single test for `catch`-less `try`.
Diffstat (limited to 'src')
-rw-r--r--src/cfg/cfg-traversal.h24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/cfg/cfg-traversal.h b/src/cfg/cfg-traversal.h
index 1464b4eb7..9b2027c42 100644
--- a/src/cfg/cfg-traversal.h
+++ b/src/cfg/cfg-traversal.h
@@ -258,8 +258,29 @@ struct CFGWalker : public ControlFlowWalker<SubType, VisitorType> {
// ...
// end
assert(self->unwindExprStack.size() == self->throwingInstsStack.size());
- for (int i = self->throwingInstsStack.size() - 1; i >= 0; i--) {
+ for (int i = self->throwingInstsStack.size() - 1; i >= 0;) {
auto* tryy = self->unwindExprStack[i]->template cast<Try>();
+ if (tryy->isDelegate()) {
+ // If this delegates to the caller, there is no possibility that this
+ // instruction can throw to outer catches.
+ if (tryy->delegateTarget == DELEGATE_CALLER_TARGET) {
+ break;
+ }
+ // If this delegates to an outer try, we skip catches between this try
+ // and the target try.
+ bool found = false;
+ for (int j = i - 1; j >= 0; j--) {
+ if (self->unwindExprStack[j]->template cast<Try>()->name ==
+ tryy->delegateTarget) {
+ i = j;
+ found = true;
+ break;
+ }
+ }
+ assert(found);
+ continue;
+ }
+
// Exception thrown. Note outselves so that we will create a link to each
// catch within the try when we get there.
self->throwingInstsStack[i].push_back(self->currBasicBlock);
@@ -269,6 +290,7 @@ struct CFGWalker : public ControlFlowWalker<SubType, VisitorType> {
if (tryy->hasCatchAll()) {
break;
}
+ i--;
}
}