diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-05-18 11:39:22 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-05-18 14:24:40 -0700 |
commit | cf224aa34a3660aa5154091759d396936e946b28 (patch) | |
tree | 17e6ab9a9e2537ca37ba1a727d633b6d7e585708 /src/wasm.cpp | |
parent | 9700fca02229f4c3e15425a2396740384f7736cb (diff) | |
download | binaryen-cf224aa34a3660aa5154091759d396936e946b28.tar.gz binaryen-cf224aa34a3660aa5154091759d396936e946b28.tar.bz2 binaryen-cf224aa34a3660aa5154091759d396936e946b28.zip |
spec test updates, and many validation fixes
Diffstat (limited to 'src/wasm.cpp')
-rw-r--r-- | src/wasm.cpp | 67 |
1 files changed, 33 insertions, 34 deletions
diff --git a/src/wasm.cpp b/src/wasm.cpp index 98268310a..09d9c3c16 100644 --- a/src/wasm.cpp +++ b/src/wasm.cpp @@ -22,66 +22,65 @@ namespace wasm { struct BlockTypeSeeker : public PostWalker<BlockTypeSeeker, Visitor<BlockTypeSeeker>> { Block* target; // look for this one - WasmType type = unreachable; + std::vector<WasmType> types; BlockTypeSeeker(Block* target) : target(target) {} - void noteType(WasmType other) { - // once none, stop. it then indicates a poison value, that must not be consumed - // and ignore unreachable - if (type != none) { - if (other == none) { - type = none; - } else if (other != unreachable) { - if (type == unreachable) { - type = other; - } else if (type != other) { - type = none; // poison value, we saw multiple types; this should not be consumed - } - } - } - } - void visitBreak(Break *curr) { if (curr->name == target->name) { - noteType(curr->value ? curr->value->type : none); + types.push_back(curr->value ? curr->value->type : none); } } void visitSwitch(Switch *curr) { for (auto name : curr->targets) { - if (name == target->name) noteType(curr->value ? curr->value->type : none); + if (name == target->name) types.push_back(curr->value ? curr->value->type : none); } } void visitBlock(Block *curr) { if (curr == target) { - if (curr->list.size() > 0) noteType(curr->list.back()->type); - } else { - type = unreachable; // ignore all breaks til now, they were captured by someone with the same name + if (curr->list.size() > 0) { + types.push_back(curr->list.back()->type); + } else { + types.push_back(none); + } + } else if (curr->name == target->name) { + types.clear(); // ignore all breaks til now, they were captured by someone with the same name } } }; void Block::finalize() { - if (list.size() > 0) { - auto last = list.back()->type; - if (last != unreachable) { - // well that was easy - type = last; - return; - } - } if (!name.is()) { - // that was rather silly - type = unreachable; + // nothing branches here, so this is easy + if (list.size() > 0) { + type = list.back()->type; + } else { + type = unreachable; + } return; } - // oh no this is hard + BlockTypeSeeker seeker(this); Expression* temp = this; seeker.walk(temp); - type = seeker.type; + type = unreachable; + for (auto other : seeker.types) { + // once none, stop. it then indicates a poison value, that must not be consumed + // and ignore unreachable + if (type != none) { + if (other == none) { + type = none; + } else if (other != unreachable) { + if (type == unreachable) { + type = other; + } else if (type != other) { + type = none; // poison value, we saw multiple types; this should not be consumed + } + } + } + } } } // namespace wasm |