From 0532093e5856662a11cf66cbf59feaeb3acb9c29 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 18 Sep 2017 16:33:06 -0700 Subject: Expressions should not appear twice in the ast (#1191) --- src/wasm-emscripten.cpp | 3 ++- src/wasm-validator.h | 3 +++ src/wasm/wasm-validator.cpp | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) (limited to 'src') 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 #include +#include #include "wasm.h" #include "wasm-printing.h" @@ -83,6 +84,8 @@ struct WasmValidator : public PostWalker { std::set labelNames; // Binaryen IR requires that label names must be unique - IR generators must ensure that + std::unordered_set 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> { + std::unordered_set& seen; + std::vector dupes; + + Walker(std::unordered_set& 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) { -- cgit v1.2.3