summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-05-23 15:11:26 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-05-23 15:50:03 -0700
commit03d5f2a3d11151887d8c2a1a0ef93011b75979c7 (patch)
tree321a1f6a0eb513a5264176cbc680af4f5158bbb0 /src
parenta78daa409853b106228d0cca0c5564222c489e04 (diff)
downloadbinaryen-03d5f2a3d11151887d8c2a1a0ef93011b75979c7.tar.gz
binaryen-03d5f2a3d11151887d8c2a1a0ef93011b75979c7.tar.bz2
binaryen-03d5f2a3d11151887d8c2a1a0ef93011b75979c7.zip
validate in asm2wasm, and fix some validation errors for that
Diffstat (limited to 'src')
-rw-r--r--src/asm2wasm.h35
-rw-r--r--src/passes/RemoveUnusedBrs.cpp18
2 files changed, 35 insertions, 18 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h
index 0aa3f91ac..2c78df2c0 100644
--- a/src/asm2wasm.h
+++ b/src/asm2wasm.h
@@ -30,6 +30,7 @@
#include "pass.h"
#include "ast_utils.h"
#include "wasm-builder.h"
+#include <wasm-validator.h>
namespace wasm {
@@ -730,7 +731,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
// note that the target is already masked, so we just offset it, we don't need to guard against overflow (which would be an error anyhow)
sub->op = AddInt32;
sub->left = call->target;
- sub->right = allocator.alloc<Const>()->set(Literal((int32_t)functionTableStarts[tableName]));
+ sub->right = builder.makeConst(Literal((int32_t)functionTableStarts[tableName]));
sub->type = WasmType::i32;
call->target = sub;
}
@@ -854,6 +855,8 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
func->body = body;
}
#endif
+
+ assert(WasmValidator().validate(wasm));
}
Function* Asm2WasmBuilder::processFunction(Ref ast) {
@@ -957,9 +960,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
ret->bytes = getWasmTypeSize(global.type);
ret->offset = 0;
ret->align = ret->bytes;
- auto ptr = allocator.alloc<Const>();
- ptr->value = Literal(int32_t(global.address)); // XXX for wasm64, need 64
- ret->ptr = ptr;
+ ret->ptr = builder.makeConst(Literal(int32_t(global.address)));
ret->value = process(ast[3]);
ret->type = global.type;
return ret;
@@ -1067,9 +1068,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
ret->signed_ = true; // but doesn't matter
ret->offset = 0;
ret->align = ret->bytes;
- auto ptr = allocator.alloc<Const>();
- ptr->value = Literal(int32_t(global.address)); // XXX for wasm64, need 64
- ret->ptr = ptr;
+ ret->ptr = builder.makeConst(Literal(int32_t(global.address)));
ret->type = global.type;
return ret;
} else if (what == SUB) {
@@ -1090,7 +1089,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
if (ast[1] == PLUS) {
Literal literal = checkLiteral(ast);
if (literal.type != none) {
- return allocator.alloc<Const>()->set(literal);
+ return builder.makeConst(literal);
}
auto ret = process(ast[2]); // we are a +() coercion
if (ret->type == i32) {
@@ -1121,7 +1120,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
// wasm has no unary negation for int, so do 0-
auto ret = allocator.alloc<Binary>();
ret->op = SubInt32;
- ret->left = allocator.alloc<Const>()->set(Literal((int32_t)0));
+ ret->left = builder.makeConst(Literal((int32_t)0));
ret->right = process(ast[2]);
ret->type = WasmType::i32;
return ret;
@@ -1178,7 +1177,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
auto ret = allocator.alloc<Binary>();
ret->op = XorInt32;
ret->left = process(ast[2]);
- ret->right = allocator.alloc<Const>()->set(Literal(int32_t(-1)));
+ ret->right = builder.makeConst(Literal(int32_t(-1)));
ret->type = WasmType::i32;
return ret;
} else if (ast[1] == L_NOT) {
@@ -1219,9 +1218,9 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
assert(ast[2]->size() == 1);
Literal lit = checkLiteral(ast[2][0]);
if (lit.type == i32) {
- return allocator.alloc<Const>()->set(Literal((float)lit.geti32()));
+ return builder.makeConst(Literal((float)lit.geti32()));
} else if (lit.type == f64) {
- return allocator.alloc<Const>()->set(Literal((float)lit.getf64()));
+ return builder.makeConst(Literal((float)lit.getf64()));
}
auto ret = allocator.alloc<Unary>();
ret->value = process(ast[2][0]);
@@ -1259,13 +1258,13 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
auto isNegative = allocator.alloc<Binary>();
isNegative->op = LtSInt32;
isNegative->left = get();
- isNegative->right = allocator.alloc<Const>()->set(Literal(0));
+ isNegative->right = builder.makeConst(Literal(0));
isNegative->finalize();
auto block = allocator.alloc<Block>();
block->list.push_back(set);
auto flip = allocator.alloc<Binary>();
flip->op = SubInt32;
- flip->left = allocator.alloc<Const>()->set(Literal(0));
+ flip->left = builder.makeConst(Literal(0));
flip->right = get();
flip->type = i32;
auto select = allocator.alloc<Select>();
@@ -1627,7 +1626,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
Binary* offsetor = allocator.alloc<Binary>();
offsetor->op = BinaryOp::SubInt32;
offsetor->left = br->condition;
- offsetor->right = allocator.alloc<Const>()->set(Literal(min));
+ offsetor->right = builder.makeConst(Literal(min));
offsetor->type = i32;
br->condition = offsetor;
@@ -1695,9 +1694,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
// constant, apply a shift (e.g. HEAP32[1] is address 4)
unsigned addr = ptr[1]->getInteger();
unsigned shifted = addr << shifts;
- auto ret = allocator.alloc<Const>();
- ret->value = Literal(int32_t(shifted));
- return (Expression*)ret;
+ return (Expression*)builder.makeConst(Literal(int32_t(shifted)));
}
abort_on("bad processUnshifted", ptr);
return (Expression*)nullptr; // avoid warning
@@ -1729,6 +1726,8 @@ void Asm2WasmBuilder::optimize() {
passRunner.add("post-emscripten");
}
passRunner.run();
+
+ assert(WasmValidator().validate(wasm));
}
} // namespace wasm
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index 570e14b38..785e09570 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -156,6 +156,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
void walk(Expression*& root) {
// multiple cycles may be needed
+ bool worked = false;
do {
anotherCycle = false;
WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<RemoveUnusedBrs>>>::walk(root);
@@ -174,6 +175,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
}
}
flows.clear();
+ if (anotherCycle) worked = true;
} while (anotherCycle);
// finally, we may have simplified ifs enough to turn them into selects
struct Selectifier : public WalkerPass<PostWalker<Selectifier, Visitor<Selectifier>>> {
@@ -202,6 +204,22 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
Selectifier selectifier;
selectifier.setModule(getModule());
selectifier.walk(root);
+ if (worked) {
+ // Our work may alter block and if types, they may now return
+ struct TypeUpdater : public WalkerPass<PostWalker<TypeUpdater, Visitor<TypeUpdater>>> {
+ void visitBlock(Block* curr) {
+ curr->finalize();
+ }
+ void visitLoop(Loop* curr) {
+ curr->finalize();
+ }
+ void visitIf(If* curr) {
+ curr->finalize();
+ }
+ };
+ TypeUpdater typeUpdater;
+ typeUpdater.walk(root);
+ }
}
};