summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-09-18 16:33:06 -0700
committerGitHub <noreply@github.com>2017-09-18 16:33:06 -0700
commit0532093e5856662a11cf66cbf59feaeb3acb9c29 (patch)
treef0ec2dfa924c6a57f8d29886d89a23c5980ced45 /src
parent8f2f6a13736336ca13d6b4bccb1af6d34f3aae48 (diff)
downloadbinaryen-0532093e5856662a11cf66cbf59feaeb3acb9c29.tar.gz
binaryen-0532093e5856662a11cf66cbf59feaeb3acb9c29.tar.bz2
binaryen-0532093e5856662a11cf66cbf59feaeb3acb9c29.zip
Expressions should not appear twice in the ast (#1191)
Diffstat (limited to 'src')
-rw-r--r--src/wasm-emscripten.cpp3
-rw-r--r--src/wasm-validator.h3
-rw-r--r--src/wasm/wasm-validator.cpp18
3 files changed, 23 insertions, 1 deletions
diff --git a/src/wasm-emscripten.cpp b/src/wasm-emscripten.cpp
index 7463ec594..9c617a31e 100644
--- a/src/wasm-emscripten.cpp
+++ b/src/wasm-emscripten.cpp
@@ -129,7 +129,8 @@ void generateStackAllocFunction(LinkerObject& linker) {
Block* block = builder.makeBlock();
block->list.push_back(setStackLocal);
block->list.push_back(storeStack);
- block->list.push_back(getStackLocal);
+ GetLocal* getStackLocal2 = builder.makeGetLocal(1, i32);
+ block->list.push_back(getStackLocal2);
block->type = i32;
function->body = block;
diff --git a/src/wasm-validator.h b/src/wasm-validator.h
index 0851d33e8..ceaaee890 100644
--- a/src/wasm-validator.h
+++ b/src/wasm-validator.h
@@ -39,6 +39,7 @@
#include <set>
#include <sstream>
+#include <unordered_set>
#include "wasm.h"
#include "wasm-printing.h"
@@ -83,6 +84,8 @@ struct WasmValidator : public PostWalker<WasmValidator> {
std::set<Name> labelNames; // Binaryen IR requires that label names must be unique - IR generators must ensure that
+ std::unordered_set<Expression*> seenExpressions; // expressions must not appear twice
+
void noteLabelName(Name name);
public:
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 5534eb7b9..85e2193fa 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -559,6 +559,24 @@ void WasmValidator::visitFunction(Function *curr) {
shouldBeTrue(breakTargets.empty(), curr->body, "all named break targets must exist");
returnType = unreachable;
labelNames.clear();
+ // expressions must not be seen more than once
+ struct Walker : public PostWalker<Walker, UnifiedExpressionVisitor<Walker>> {
+ std::unordered_set<Expression*>& seen;
+ std::vector<Expression*> dupes;
+
+ Walker(std::unordered_set<Expression*>& seen) : seen(seen) {}
+
+ void visitExpression(Expression* curr) {
+ bool inserted;
+ std::tie(std::ignore, inserted) = seen.insert(curr);
+ if (!inserted) dupes.push_back(curr);
+ }
+ };
+ Walker walker(seenExpressions);
+ walker.walk(curr->body);
+ for (auto* bad : walker.dupes) {
+ fail("expression seen more than once in the tree", bad);
+ }
}
static bool checkOffset(Expression* curr, Address add, Address max) {