summaryrefslogtreecommitdiff
path: root/src/passes
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes')
-rw-r--r--src/passes/hash-stringify-walker.cpp2
-rw-r--r--src/passes/stringify-walker-impl.h47
-rw-r--r--src/passes/stringify-walker.h101
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);
};