summaryrefslogtreecommitdiff
path: root/src/wasm.cpp
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-05-18 11:39:22 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-05-18 14:24:40 -0700
commitcf224aa34a3660aa5154091759d396936e946b28 (patch)
tree17e6ab9a9e2537ca37ba1a727d633b6d7e585708 /src/wasm.cpp
parent9700fca02229f4c3e15425a2396740384f7736cb (diff)
downloadbinaryen-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.cpp67
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