summaryrefslogtreecommitdiff
path: root/src/ir
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir')
-rw-r--r--src/ir/ExpressionAnalyzer.cpp1
-rw-r--r--src/ir/ExpressionManipulator.cpp1
-rw-r--r--src/ir/branch-utils.h2
-rw-r--r--src/ir/cost.h4
-rw-r--r--src/ir/effects.h33
-rw-r--r--src/ir/utils.h6
6 files changed, 34 insertions, 13 deletions
diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp
index 88dce6767..04ef52026 100644
--- a/src/ir/ExpressionAnalyzer.cpp
+++ b/src/ir/ExpressionAnalyzer.cpp
@@ -206,6 +206,7 @@ bool ExpressionAnalyzer::flexibleEqual(Expression* left,
}
#define DELEGATE_FIELD_INT_ARRAY(id, name) COMPARE_LIST(name)
+#define DELEGATE_FIELD_NAME_VECTOR(id, name) COMPARE_LIST(name)
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, name) \
if (castLeft->name.is() != castRight->name.is()) { \
diff --git a/src/ir/ExpressionManipulator.cpp b/src/ir/ExpressionManipulator.cpp
index 18c3f2df9..7ad8d0f50 100644
--- a/src/ir/ExpressionManipulator.cpp
+++ b/src/ir/ExpressionManipulator.cpp
@@ -97,6 +97,7 @@ flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) {
COPY_FIELD_LIST(name)
#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, name) COPY_VECTOR(name)
+#define DELEGATE_FIELD_NAME_VECTOR(id, name) COPY_VECTOR(name)
#define DELEGATE_FIELD_INT_ARRAY(id, name) COPY_ARRAY(name)
diff --git a/src/ir/branch-utils.h b/src/ir/branch-utils.h
index d7a6edcae..2e7ef470d 100644
--- a/src/ir/branch-utils.h
+++ b/src/ir/branch-utils.h
@@ -58,6 +58,7 @@ template<typename T> void operateOnScopeNameUses(Expression* expr, T func) {
#define DELEGATE_FIELD_INT(id, name)
#define DELEGATE_FIELD_LITERAL(id, name)
#define DELEGATE_FIELD_NAME(id, name)
+#define DELEGATE_FIELD_NAME_VECTOR(id, name)
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, name)
#define DELEGATE_FIELD_SIGNATURE(id, name)
#define DELEGATE_FIELD_TYPE(id, name)
@@ -104,6 +105,7 @@ template<typename T> void operateOnScopeNameDefs(Expression* expr, T func) {
#define DELEGATE_FIELD_INT(id, name)
#define DELEGATE_FIELD_LITERAL(id, name)
#define DELEGATE_FIELD_NAME(id, name)
+#define DELEGATE_FIELD_NAME_VECTOR(id, name)
#define DELEGATE_FIELD_SIGNATURE(id, name)
#define DELEGATE_FIELD_TYPE(id, name)
#define DELEGATE_FIELD_ADDRESS(id, name)
diff --git a/src/ir/cost.h b/src/ir/cost.h
index fbb4e83ad..4424f2e00 100644
--- a/src/ir/cost.h
+++ b/src/ir/cost.h
@@ -546,7 +546,7 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> {
}
Index visitTry(Try* curr) {
// We assume no exception will be thrown in most cases
- return visit(curr->body) + maybeVisit(curr->catchBody);
+ return visit(curr->body);
}
Index visitThrow(Throw* curr) {
Index ret = 100;
@@ -555,7 +555,7 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> {
}
return ret;
}
- Index visitRethrow(Rethrow* curr) { return 100 + visit(curr->exnref); }
+ Index visitRethrow(Rethrow* curr) { return 100; }
Index visitBrOnExn(BrOnExn* curr) {
return 1 + visit(curr->exnref) + curr->sent.size();
}
diff --git a/src/ir/effects.h b/src/ir/effects.h
index 71957d1f8..22fab593d 100644
--- a/src/ir/effects.h
+++ b/src/ir/effects.h
@@ -84,14 +84,16 @@ public:
// wrt atomics (e.g. memory.grow)
bool isAtomic = false;
bool throws = false;
- // The nested depth of try. If an instruction that may throw is inside an
- // inner try, we don't mark it as 'throws', because it will be caught by an
- // inner catch.
+ // The nested depth of try-catch_all. If an instruction that may throw is
+ // inside an inner try-catch_all, we don't mark it as 'throws', because it
+ // will be caught by an inner catch_all. We only count 'try's with a
+ // 'catch_all' because instructions within a 'try' without a 'catch_all' can
+ // still throw outside of the try.
size_t tryDepth = 0;
// The nested depth of catch. This is necessary to track danglng pops.
size_t catchDepth = 0;
- // If this expression contains 'exnref.pop's that are not enclosed in 'catch'
- // body. For example, (drop (exnref.pop)) should set this to true.
+ // If this expression contains 'pop's that are not enclosed in 'catch' body.
+ // For example, (drop (pop i32)) should set this to true.
bool danglingPop = false;
// Helper functions to check for various effect types
@@ -258,7 +260,10 @@ private:
if (curr->is<Try>()) {
self->pushTask(doVisitTry, currp);
self->pushTask(doEndCatch, currp);
- self->pushTask(scan, &curr->cast<Try>()->catchBody);
+ auto& catchBodies = curr->cast<Try>()->catchBodies;
+ for (int i = int(catchBodies.size()) - 1; i >= 0; i--) {
+ self->pushTask(scan, &catchBodies[i]);
+ }
self->pushTask(doStartCatch, currp);
self->pushTask(scan, &curr->cast<Try>()->body);
self->pushTask(doStartTry, currp);
@@ -269,12 +274,22 @@ private:
}
static void doStartTry(InternalAnalyzer* self, Expression** currp) {
- self->parent.tryDepth++;
+ Try* curr = (*currp)->cast<Try>();
+ // We only count 'try's with a 'catch_all' because instructions within a
+ // 'try' without a 'catch_all' can still throw outside of the try.
+ if (curr->hasCatchAll()) {
+ self->parent.tryDepth++;
+ }
}
static void doStartCatch(InternalAnalyzer* self, Expression** currp) {
- assert(self->parent.tryDepth > 0 && "try depth cannot be negative");
- self->parent.tryDepth--;
+ Try* curr = (*currp)->cast<Try>();
+ // We only count 'try's with a 'catch_all' because instructions within a
+ // 'try' without a 'catch_all' can still throw outside of the try.
+ if (curr->hasCatchAll()) {
+ assert(self->parent.tryDepth > 0 && "try depth cannot be negative");
+ self->parent.tryDepth--;
+ }
self->parent.catchDepth++;
}
diff --git a/src/ir/utils.h b/src/ir/utils.h
index 0136fd11c..424298bb3 100644
--- a/src/ir/utils.h
+++ b/src/ir/utils.h
@@ -222,8 +222,10 @@ struct AutoDrop : public WalkerPass<ExpressionStackWalker<AutoDrop>> {
if (maybeDrop(curr->body)) {
acted = true;
}
- if (maybeDrop(curr->catchBody)) {
- acted = true;
+ for (auto* catchBody : curr->catchBodies) {
+ if (maybeDrop(catchBody)) {
+ acted = true;
+ }
}
if (acted) {
reFinalize();