diff options
Diffstat (limited to 'src/wasm2asm.h')
-rw-r--r-- | src/wasm2asm.h | 53 |
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, |