#include "stringify-walker.h"
#define STRINGIFY_DEBUG 0
#if STRINGIFY_DEBUG
#define DBG(statement) statement
#else
#define DBG(statement)
#endif
#ifndef wasm_passes_stringify_walker_impl_h
#define wasm_passes_stringify_walker_impl_h
namespace wasm {
template<typename SubType>
inline void StringifyWalker<SubType>::doWalkModule(Module* module) {
ModuleUtils::iterDefinedFunctions(
*module, [&](Function* func) { this->walkFunction(func); });
}
template<typename SubType>
inline void StringifyWalker<SubType>::doWalkFunction(Function* func) {
addUniqueSymbol(SeparatorReason::makeFuncStart(func));
Super::walk(func->body);
addUniqueSymbol(SeparatorReason::makeEnd());
while (!controlFlowQueue.empty()) {
dequeueControlFlow();
}
}
template<typename SubType>
inline void StringifyWalker<SubType>::scan(SubType* self, Expression** currp) {
Expression* curr = *currp;
if (Properties::isControlFlowStructure(curr)) {
self->controlFlowQueue.push(curr);
DBG(std::cerr << "controlFlowQueue.push: " << ShallowExpression{curr}
<< ", " << curr << "\n");
self->pushTask(doVisitExpression, currp);
for (auto*& child : ValueChildIterator(curr)) {
Super::scan(self, &child);
}
} else {
Super::scan(self, currp);
}
}
template<typename SubType> void StringifyWalker<SubType>::dequeueControlFlow() {
auto& queue = controlFlowQueue;
Expression* curr = queue.front();
queue.pop();
DBG(std::cerr << "controlFlowQueue.pop: " << ShallowExpression{curr} << ", "
<< curr << "\n");
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(SeparatorReason::makeElseStart());
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(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: {
assert(Properties::isControlFlowStructure(curr));
WASM_UNREACHABLE("unexpected expression");
}
}
}
template<typename SubType>
void StringifyWalker<SubType>::doVisitExpression(SubType* self,
Expression** currp) {
Expression* curr = *currp;
self->visit(curr);
}
template<typename SubType>
inline void StringifyWalker<SubType>::addUniqueSymbol(SeparatorReason reason) {
auto self = static_cast<SubType*>(this);
self->addUniqueSymbol(reason);
}
}
#endif