diff options
Diffstat (limited to 'src/passes')
-rw-r--r-- | src/passes/hash-stringify-walker.cpp | 2 | ||||
-rw-r--r-- | src/passes/stringify-walker-impl.h | 47 | ||||
-rw-r--r-- | src/passes/stringify-walker.h | 101 |
3 files changed, 118 insertions, 32 deletions
diff --git a/src/passes/hash-stringify-walker.cpp b/src/passes/hash-stringify-walker.cpp index 9a7cee08f..43cc3d544 100644 --- a/src/passes/hash-stringify-walker.cpp +++ b/src/passes/hash-stringify-walker.cpp @@ -52,7 +52,7 @@ bool StringifyEquator::operator()(Expression* lhs, Expression* rhs) const { return ExpressionAnalyzer::shallowEqual(lhs, rhs); } -void HashStringifyWalker::addUniqueSymbol() { +void HashStringifyWalker::addUniqueSymbol(SeparatorReason reason) { // Use a negative value to distinguish symbols for separators from symbols // for Expressions assert((uint32_t)nextSeparatorVal >= nextVal); diff --git a/src/passes/stringify-walker-impl.h b/src/passes/stringify-walker-impl.h index e856773c9..8ed166d75 100644 --- a/src/passes/stringify-walker-impl.h +++ b/src/passes/stringify-walker-impl.h @@ -31,28 +31,12 @@ inline void StringifyWalker<SubType>::doWalkModule(Module* module) { template<typename SubType> inline void StringifyWalker<SubType>::doWalkFunction(Function* func) { - walk(func->body); - /* - * We add a unique symbol after walking the function body to separate the - * string generated from visiting the function body as a single unit from the - * subsequent strings that will be generated from visiting the sub-expressions - * of the function body. If we did not add this unique symbol and a program - * had two functions with the same instructions, we would incorrectly create a - * new function with the instructions repeated twice. - * - * It might be helpful to think of the function body as a block that needs to - * be separated from subsequent instructions. - */ - addUniqueSymbol(); -} - -template<typename SubType> -inline void StringifyWalker<SubType>::walk(Expression* curr) { - Super::walk(curr); - do { - addUniqueSymbol(); + addUniqueSymbol(SeparatorReason::makeFuncStart(func)); + Super::walk(func->body); + addUniqueSymbol(SeparatorReason::makeEnd()); + while (!controlFlowQueue.empty()) { dequeueControlFlow(); - } while (!controlFlowQueue.empty()); + } } template<typename SubType> @@ -76,10 +60,6 @@ inline void StringifyWalker<SubType>::scan(SubType* self, Expression** currp) { // of control flow. template<typename SubType> void StringifyWalker<SubType>::dequeueControlFlow() { auto& queue = controlFlowQueue; - if (queue.empty()) { - return; - } - Expression** currp = queue.front(); queue.pop(); Expression* curr = *currp; @@ -88,32 +68,41 @@ template<typename SubType> void StringifyWalker<SubType>::dequeueControlFlow() { switch (curr->_id) { case Expression::Id::BlockId: { auto* block = curr->cast<Block>(); + addUniqueSymbol(SeparatorReason::makeBlockStart(block)); for (auto& child : block->list) { Super::walk(child); } + addUniqueSymbol(SeparatorReason::makeEnd()); break; } case Expression::Id::IfId: { auto* iff = curr->cast<If>(); + addUniqueSymbol(SeparatorReason::makeIfStart(iff)); Super::walk(iff->ifTrue); if (iff->ifFalse) { - addUniqueSymbol(); + addUniqueSymbol(SeparatorReason::makeElseStart(iff)); Super::walk(iff->ifFalse); } + addUniqueSymbol(SeparatorReason::makeEnd()); break; } case Expression::Id::TryId: { auto* tryy = curr->cast<Try>(); + addUniqueSymbol(SeparatorReason::makeTryBodyStart()); Super::walk(tryy->body); + addUniqueSymbol(SeparatorReason::makeEnd()); for (auto& child : tryy->catchBodies) { - addUniqueSymbol(); + addUniqueSymbol(SeparatorReason::makeTryCatchStart()); Super::walk(child); + addUniqueSymbol(SeparatorReason::makeEnd()); } break; } case Expression::Id::LoopId: { auto* loop = curr->cast<Loop>(); + addUniqueSymbol(SeparatorReason::makeLoopStart(loop)); Super::walk(loop->body); + addUniqueSymbol(SeparatorReason::makeEnd()); break; } default: { @@ -131,13 +120,13 @@ void StringifyWalker<SubType>::doVisitExpression(SubType* self, } template<typename SubType> -inline void StringifyWalker<SubType>::addUniqueSymbol() { +inline void StringifyWalker<SubType>::addUniqueSymbol(SeparatorReason reason) { // TODO: Add the following static_assert when the compilers running our GitHub // actions are updated enough to know that this is a constant condition: // static_assert(&StringifyWalker<SubType>::addUniqueSymbol != // &SubType::addUniqueSymbol); auto self = static_cast<SubType*>(this); - self->addUniqueSymbol(); + self->addUniqueSymbol(reason); } } // namespace wasm diff --git a/src/passes/stringify-walker.h b/src/passes/stringify-walker.h index c20d250ec..129021bc4 100644 --- a/src/passes/stringify-walker.h +++ b/src/passes/stringify-walker.h @@ -66,6 +66,103 @@ struct StringifyWalker using Super = PostWalker<SubType, UnifiedExpressionVisitor<SubType>>; + struct SeparatorReason { + struct FuncStart { + Function* func; + }; + + struct BlockStart { + Block* curr; + }; + + struct IfStart { + If* iff; + }; + + struct ElseStart { + If* iff; + }; + + struct LoopStart { + Loop* loop; + }; + + struct TryBodyStart {}; + + struct TryCatchStart {}; + + struct End { + Expression* curr; + }; + using Separator = std::variant<FuncStart, + BlockStart, + IfStart, + ElseStart, + LoopStart, + TryBodyStart, + TryCatchStart, + End>; + + Separator reason; + + SeparatorReason(Separator reason) : reason(reason) {} + + static SeparatorReason makeFuncStart(Function* func) { + return SeparatorReason(FuncStart{func}); + } + static SeparatorReason makeBlockStart(Block* block) { + return SeparatorReason(BlockStart{block}); + } + static SeparatorReason makeIfStart(If* iff) { + return SeparatorReason(IfStart{iff}); + } + static SeparatorReason makeElseStart(If* iff) { + return SeparatorReason(ElseStart{iff}); + } + static SeparatorReason makeLoopStart(Loop* loop) { + return SeparatorReason(LoopStart{loop}); + } + static SeparatorReason makeTryCatchStart() { + return SeparatorReason(TryCatchStart{}); + } + static SeparatorReason makeTryBodyStart() { + return SeparatorReason(TryBodyStart{}); + } + static SeparatorReason makeEnd() { return SeparatorReason(End{}); } + bool isFuncStart() { return std::get_if<FuncStart>(&reason); } + bool isBlockStart() { return std::get_if<BlockStart>(&reason); } + bool isIfStart() { return std::get_if<IfStart>(&reason); } + bool isElseStart() { return std::get_if<ElseStart>(&reason); } + bool isLoopStart() { return std::get_if<LoopStart>(&reason); } + bool isTryBodyStart() { return std::get_if<TryBodyStart>(&reason); } + bool isTryCatchStart() { return std::get_if<TryCatchStart>(&reason); } + bool isEnd() { return std::get_if<End>(&reason); } + }; + + friend std::ostream& + operator<<(std::ostream& o, + typename StringifyWalker::SeparatorReason reason) { + if (reason.isFuncStart()) { + return o << "Func Start"; + } else if (reason.isBlockStart()) { + return o << "Block Start"; + } else if (reason.isIfStart()) { + return o << "If Start"; + } else if (reason.isElseStart()) { + return o << "Else Start"; + } else if (reason.isLoopStart()) { + return o << "Loop Start"; + } else if (reason.isTryBodyStart()) { + return o << "Try Body Start"; + } else if (reason.isTryCatchStart()) { + return o << "Try Catch Start"; + } else if (reason.isEnd()) { + return o << "End"; + } + + return o << "~~~Undefined in operator<< overload~~~"; + } + std::queue<Expression**> controlFlowQueue; /* @@ -77,7 +174,7 @@ struct StringifyWalker * appropriate points during the walk and should be implemented by subclasses. */ void visitExpression(Expression* curr); - void addUniqueSymbol(); + void addUniqueSymbol(SeparatorReason reason); void doWalkModule(Module* module); void doWalkFunction(Function* func); @@ -130,7 +227,7 @@ struct HashStringifyWalker : public StringifyWalker<HashStringifyWalker> { std::unordered_map<Expression*, uint32_t, StringifyHasher, StringifyEquator> exprToCounter; - void addUniqueSymbol(); + void addUniqueSymbol(SeparatorReason reason); void visitExpression(Expression* curr); }; |