diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-03-08 12:20:53 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-03-10 16:30:01 -0800 |
commit | 7734ce6ef5f95697c5bdebc18b96d3902c766b8e (patch) | |
tree | 61e24549dec76a6f989a7fd74a68a59d783d90c8 /src/wasm.h | |
parent | 0467407decb3cd30ad407f553a078b9f533b479d (diff) | |
download | binaryen-7734ce6ef5f95697c5bdebc18b96d3902c766b8e.tar.gz binaryen-7734ce6ef5f95697c5bdebc18b96d3902c766b8e.tar.bz2 binaryen-7734ce6ef5f95697c5bdebc18b96d3902c766b8e.zip |
de-recurse operations on nested blocks
Diffstat (limited to 'src/wasm.h')
-rw-r--r-- | src/wasm.h | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/src/wasm.h b/src/wasm.h index 4bcb4bc87..b52803799 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1408,7 +1408,37 @@ struct WasmWalker : public WasmWalkerBase<SubType, ReturnType> { void walk(Expression*& curr) override { if (!curr) return; - ChildWalker<WasmWalker<SubType, ReturnType>>(*this).visit(curr); + // special-case Block, because Block nesting (in their first element) can be incredibly deep + if (curr->is<Block>()) { + auto* block = curr->dyn_cast<Block>(); + std::vector<Block*> stack; + stack.push_back(block); + while (block->list.size() > 0 && block->list[0]->is<Block>()) { + block = block->list[0]->cast<Block>(); + stack.push_back(block); + } + // walk all the children + for (int i = int(stack.size()) - 1; i >= 0; i--) { + auto* block = stack[i]; + auto& children = block->list; + for (size_t j = 0; j < children.size(); j++) { + if (i < int(stack.size()) - 1 && j == 0) { + // this is one of the stacked blocks, no need to walk its children, we are doing that ourselves + this->visit(children[0]); + if (replace) { + children[0] = replace; + replace = nullptr; + } + } else { + this->walk(children[j]); + } + } + } + // we walked all the children, and can rejoin later below to visit this node itself + } else { + // generic child-walking + ChildWalker<WasmWalker<SubType, ReturnType>>(*this).visit(curr); + } this->visit(curr); |