summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast_utils.h6
-rw-r--r--src/wasm-binary.h18
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);