diff options
Diffstat (limited to 'src/tools/wasm2js.cpp')
-rw-r--r-- | src/tools/wasm2js.cpp | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp index 1c128390f..b3f8068e2 100644 --- a/src/tools/wasm2js.cpp +++ b/src/tools/wasm2js.cpp @@ -136,6 +136,12 @@ static void replaceInPlace(Ref target, Ref value) { } } +static void replaceInPlaceIfPossible(Ref target, Ref value) { + if (target->isArray() && value->isArray()) { + replaceInPlace(target, value); + } +} + static void optimizeJS(Ref ast) { // Helpers @@ -377,7 +383,8 @@ static void optimizeJS(Ref ast) { } }); - // Remove unnecessary break/continue labels, when referring to the top level. + // Remove unnecessary break/continue labels, when the name is that of the + // highest target anyhow, which we would reach without the name. std::vector<Ref> breakCapturers; std::vector<Ref> continueCapturers; @@ -437,6 +444,30 @@ static void optimizeJS(Ref ast) { } } }); + + // Remove unnecessary block/loop labels. + + std::set<IString> usedLabelNames; + + traversePost(ast, [&](Ref node) { + if (node->isArray() && !node->empty()) { + if (node[0] == BREAK || node[0] == CONTINUE) { + if (!node[1]->isNull()) { + auto label = node[1]->getIString(); + usedLabelNames.insert(label); + } + } else if (node[0] == LABEL) { + auto label = node[1]->getIString(); + if (usedLabelNames.count(label)) { + // It's used; just erase it from the data structure. + usedLabelNames.erase(label); + } else { + // It's not used - get rid of it. + replaceInPlaceIfPossible(node, node[2]); + } + } + } + }); } static void emitWasm(Module& wasm, |