From 5f6911f1f1fcae058bf77720f04e1166bafca8e3 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Mon, 29 Nov 2021 13:57:05 -0800 Subject: Handle try in Flatten pass (#2567) This adds handling of try in the Flatten pass. --- src/ir/eh-utils.cpp | 4 ++++ src/passes/Flatten.cpp | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) (limited to 'src') diff --git a/src/ir/eh-utils.cpp b/src/ir/eh-utils.cpp index ed7ec1e0a..31ddfe306 100644 --- a/src/ir/eh-utils.cpp +++ b/src/ir/eh-utils.cpp @@ -108,6 +108,10 @@ bool isPopValid(Expression* catchBody) { } void handleBlockNestedPops(Function* func, Module& wasm) { + if (!wasm.features.hasExceptionHandling()) { + return; + } + Builder builder(wasm); FindAll trys(func->body); for (auto* try_ : trys.list) { diff --git a/src/passes/Flatten.cpp b/src/passes/Flatten.cpp index 298b6241e..be43e57f2 100644 --- a/src/passes/Flatten.cpp +++ b/src/passes/Flatten.cpp @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -192,6 +193,37 @@ struct Flatten loop->finalize(); replaceCurrent(rep); + } else if (auto* tryy = curr->dynCast()) { + // remove a try value + Expression* rep = tryy; + auto* originalBody = tryy->body; + std::vector originalCatchBodies(tryy->catchBodies.begin(), + tryy->catchBodies.end()); + auto type = tryy->type; + if (type.isConcrete()) { + Index temp = builder.addVar(getFunction(), type); + if (tryy->body->type.isConcrete()) { + tryy->body = builder.makeLocalSet(temp, tryy->body); + } + for (Index i = 0; i < tryy->catchBodies.size(); i++) { + if (tryy->catchBodies[i]->type.isConcrete()) { + tryy->catchBodies[i] = + builder.makeLocalSet(temp, tryy->catchBodies[i]); + } + } + // and we leave just a get of the value + rep = builder.makeLocalGet(temp, type); + // the whole try is now a prelude + ourPreludes.push_back(tryy); + } + tryy->body = getPreludesWithExpression(originalBody, tryy->body); + for (Index i = 0; i < tryy->catchBodies.size(); i++) { + tryy->catchBodies[i] = getPreludesWithExpression( + originalCatchBodies[i], tryy->catchBodies[i]); + } + tryy->finalize(); + replaceCurrent(rep); + } else { WASM_UNREACHABLE("unexpected expr type"); } @@ -347,6 +379,10 @@ struct Flatten << type; } } + + // Flatten can generate blocks within 'catch', making pops invalid. Fix them + // up. + EHUtils::handleBlockNestedPops(curr, *getModule()); } private: -- cgit v1.2.3