diff options
Diffstat (limited to 'src/ir')
-rw-r--r-- | src/ir/ExpressionAnalyzer.cpp | 1 | ||||
-rw-r--r-- | src/ir/ExpressionManipulator.cpp | 1 | ||||
-rw-r--r-- | src/ir/branch-utils.h | 2 | ||||
-rw-r--r-- | src/ir/cost.h | 4 | ||||
-rw-r--r-- | src/ir/effects.h | 33 | ||||
-rw-r--r-- | src/ir/utils.h | 6 |
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(); |