diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast_utils.h | 6 | ||||
-rw-r--r-- | src/wasm-binary.h | 18 |
2 files changed, 22 insertions, 2 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h index 5cda48578..55499d808 100644 --- a/src/ast_utils.h +++ b/src/ast_utils.h @@ -32,6 +32,12 @@ struct BreakSeeker : public PostWalker<BreakSeeker, Visitor<BreakSeeker>> { if (curr->name == target) found++; } + void visitSwitch(Switch *curr) { + for (auto name : curr->targets) { + if (name == target) found++; + } + } + static bool has(Expression* tree, Name target) { BreakSeeker breakSeeker(target); breakSeeker.walk(tree); diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 3ded58f40..ea57d5d3b 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -29,6 +29,7 @@ #include "shared-constants.h" #include "asm_v_wasm.h" #include "wasm-builder.h" +#include "ast_utils.h" namespace wasm { @@ -801,17 +802,30 @@ public: breakStack.pop_back(); o << int8_t(BinaryConsts::End); } + + // emits a node, but if it is a block with no name, emit a list of its contents + void recursePossibleBlockContents(Expression* curr) { + auto* block = curr->dynCast<Block>(); + if (!block || (block->name.is() && BreakSeeker::has(curr, block->name))) { + recurse(curr); + return; + } + for (auto* child : block->list) { + recurse(child); + } + } + void visitIf(If *curr) { if (debug) std::cerr << "zz node: If" << std::endl; recurse(curr->condition); o << int8_t(BinaryConsts::If); breakStack.push_back(IMPOSSIBLE_CONTINUE); // the binary format requires this; we have a block if we need one; TODO: optimize - recurse(curr->ifTrue); // TODO: emit block contents directly, if possible + recursePossibleBlockContents(curr->ifTrue); // TODO: emit block contents directly, if possible breakStack.pop_back(); if (curr->ifFalse) { o << int8_t(BinaryConsts::Else); breakStack.push_back(IMPOSSIBLE_CONTINUE); // TODO ditto - recurse(curr->ifFalse); + recursePossibleBlockContents(curr->ifFalse); breakStack.pop_back(); } o << int8_t(BinaryConsts::End); |