summaryrefslogtreecommitdiff
path: root/src/wasm2asm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm2asm.h')
-rw-r--r--src/wasm2asm.h53
1 files changed, 32 insertions, 21 deletions
diff --git a/src/wasm2asm.h b/src/wasm2asm.h
index 465262d5b..956ded5e8 100644
--- a/src/wasm2asm.h
+++ b/src/wasm2asm.h
@@ -29,6 +29,8 @@
#include "asmjs/asmangle.h"
#include "wasm.h"
#include "wasm-builder.h"
+#include "wasm-io.h"
+#include "wasm-validator.h"
#include "emscripten-optimizer/optimizer.h"
#include "mixed_arena.h"
#include "asm_v_wasm.h"
@@ -228,7 +230,11 @@ private:
Ref Wasm2AsmBuilder::processWasm(Module* wasm) {
PassRunner runner(wasm);
runner.add<AutoDrop>();
- runner.add("remove-non-js-ops"); // must be before i64-to-i32
+ // First up remove as many non-JS operations we can, including things like
+ // 64-bit integer multiplication/division, `f32.nearest` instructions, etc.
+ // This may inject intrinsics which use i64 so it needs to be run before the
+ // i64-to-i32 lowering pass.
+ runner.add("remove-non-js-ops");
// Currently the i64-to-32 lowering pass requires that `flatten` be run before
// it produce correct code. For some more details about this see #1480
runner.add("flatten");
@@ -239,6 +245,16 @@ Ref Wasm2AsmBuilder::processWasm(Module* wasm) {
runner.add("vacuum");
runner.setDebug(flags.debug);
runner.run();
+
+ // Make sure we didn't corrupt anything if we're in --allow-asserts mode (aka
+ // tests)
+#ifndef NDEBUG
+ if (!WasmValidator().validate(*wasm)) {
+ WasmPrinter::printModule(wasm);
+ Fatal() << "error in validating input";
+ }
+#endif
+
Ref ret = ValueBuilder::makeToplevel();
Ref asmFunc = ValueBuilder::makeFunction(ASM_FUNC);
ret[1]->push_back(asmFunc);
@@ -486,6 +502,17 @@ void Wasm2AsmBuilder::addGlobal(Ref ast, Global* global) {
}
}
+static bool expressionEndsInReturn(Expression *e) {
+ if (e->is<Return>()) {
+ return true;
+ }
+ if (!e->is<Block>()) {
+ return false;
+ }
+ ExpressionList* stats = &static_cast<Block*>(e)->list;
+ return expressionEndsInReturn((*stats)[stats->size()-1]);
+}
+
Ref Wasm2AsmBuilder::processFunction(Function* func) {
if (flags.debug) {
static int fns = 0;
@@ -530,12 +557,7 @@ Ref Wasm2AsmBuilder::processFunction(Function* func) {
);
};
scanFunctionBody(func->body);
- bool isBodyBlock = func->body->is<Block>();
- ExpressionList* stats = isBodyBlock ?
- &static_cast<Block*>(func->body)->list : nullptr;
- bool endsInReturn =
- (isBodyBlock && ((*stats)[stats->size()-1]->is<Return>())) ||
- func->body->is<Return>();
+ bool endsInReturn = expressionEndsInReturn(func->body);
if (endsInReturn) {
// return already taken care of
flattenAppend(ret, processFunctionBody(func, NO_RESULT));
@@ -1244,21 +1266,10 @@ Ref Wasm2AsmBuilder::processFunctionBody(Function* func, IString result) {
visit(curr->value, EXPRESSION_RESULT)
);
case CtzInt32:
- return makeSigning(
- ValueBuilder::makeCall(
- WASM_CTZ32,
- visit(curr->value, EXPRESSION_RESULT)
- ),
- ASM_SIGNED
- );
case PopcntInt32:
- return makeSigning(
- ValueBuilder::makeCall(
- WASM_POPCNT32,
- visit(curr->value, EXPRESSION_RESULT)
- ),
- ASM_SIGNED
- );
+ std::cerr << "i32 unary should have been removed: " << curr
+ << std::endl;
+ WASM_UNREACHABLE();
case EqZInt32:
return ValueBuilder::makeBinary(
makeAsmCoercion(visit(curr->value,