diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/abi/js.h | 4 | ||||
-rw-r--r-- | src/asmjs/shared-constants.cpp | 2 | ||||
-rw-r--r-- | src/asmjs/shared-constants.h | 1 | ||||
-rw-r--r-- | src/wasm2js.h | 48 |
4 files changed, 34 insertions, 21 deletions
diff --git a/src/abi/js.h b/src/abi/js.h index 970f7ffa7..96bfc2125 100644 --- a/src/abi/js.h +++ b/src/abi/js.h @@ -50,6 +50,7 @@ extern cashew::IString DATA_DROP; extern cashew::IString ATOMIC_WAIT_I32; extern cashew::IString ATOMIC_RMW_I64; extern cashew::IString GET_STASHED_BITS; +extern cashew::IString TRAP; // The wasm2js helpers let us do things that can't be done without special help, // like read and write to scratch memory for purposes of implementing things @@ -89,6 +90,7 @@ inline void ensureHelpers(Module* wasm, {Type::i32, Type::i32, Type::i32, Type::i32, Type::i32, Type::i32}, Type::i32); ensureImport(GET_STASHED_BITS, {}, Type::i32); + ensureImport(TRAP, {}, Type::none); } inline bool isHelper(cashew::IString name) { @@ -97,7 +99,7 @@ inline bool isHelper(cashew::IString name) { name == SCRATCH_LOAD_F64 || name == SCRATCH_STORE_F64 || name == ATOMIC_WAIT_I32 || name == MEMORY_INIT || name == MEMORY_FILL || name == MEMORY_COPY || name == DATA_DROP || - name == ATOMIC_RMW_I64 || name == GET_STASHED_BITS; + name == ATOMIC_RMW_I64 || name == GET_STASHED_BITS || name == TRAP; } } // namespace wasm2js diff --git a/src/asmjs/shared-constants.cpp b/src/asmjs/shared-constants.cpp index 20b148155..f66b5de18 100644 --- a/src/asmjs/shared-constants.cpp +++ b/src/asmjs/shared-constants.cpp @@ -94,7 +94,6 @@ cashew::IString WASM_I64_SREM("__wasm_i64_srem"); cashew::IString WASM_I64_UREM("__wasm_i64_urem"); cashew::IString ASM_FUNC("asmFunc"); -cashew::IString ABORT_FUNC("abort"); cashew::IString FUNCTION_TABLE("FUNCTION_TABLE"); cashew::IString NO_RESULT("wasm2js$noresult"); // no result at all // result in an expression, no temp var @@ -116,6 +115,7 @@ cashew::IString DATA_DROP("wasm2js_data_drop"); cashew::IString ATOMIC_WAIT_I32("wasm2js_atomic_wait_i32"); cashew::IString ATOMIC_RMW_I64("wasm2js_atomic_rmw_i64"); cashew::IString GET_STASHED_BITS("wasm2js_get_stashed_bits"); +cashew::IString TRAP("wasm2js_trap"); } // namespace wasm2js } // namespace ABI diff --git a/src/asmjs/shared-constants.h b/src/asmjs/shared-constants.h index 20edacb7e..cebe8baaa 100644 --- a/src/asmjs/shared-constants.h +++ b/src/asmjs/shared-constants.h @@ -97,7 +97,6 @@ extern cashew::IString WASM_I64_SREM; extern cashew::IString WASM_I64_UREM; // wasm2js constants extern cashew::IString ASM_FUNC; -extern cashew::IString ABORT_FUNC; extern cashew::IString FUNCTION_TABLE; extern cashew::IString NO_RESULT; extern cashew::IString EXPRESSION_RESULT; diff --git a/src/wasm2js.h b/src/wasm2js.h index 05ba2ace9..ab9fae0d9 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -588,13 +588,6 @@ void Wasm2JSBuilder::addBasics(Ref ast, Module* wasm) { addMath(MATH_CEIL, CEIL); addMath(MATH_TRUNC, TRUNC); addMath(MATH_SQRT, SQRT); - // abort function - Ref abortVar = ValueBuilder::makeVar(); - ast->push_back(abortVar); - ValueBuilder::appendToVar( - abortVar, - "abort", - ValueBuilder::makeDot(ValueBuilder::makeName(ENV), ABORT_FUNC)); // TODO: this shouldn't be needed once we stop generating literal asm.js code // NaN and Infinity variables Ref nanVar = ValueBuilder::makeVar(); @@ -2030,13 +2023,15 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, makeJsCoercion(visit(curr->delta, EXPRESSION_RESULT), wasmToJsType(curr->delta->type))); } else { - return ValueBuilder::makeCall(ABORT_FUNC); + ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TRAP); + return ValueBuilder::makeCall(ABI::wasm2js::TRAP); } } Ref visitNop(Nop* curr) { return ValueBuilder::makeToplevel(); } Ref visitUnreachable(Unreachable* curr) { - return ValueBuilder::makeCall(ABORT_FUNC); + ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TRAP); + return ValueBuilder::makeCall(ABI::wasm2js::TRAP); } // Atomics @@ -2524,7 +2519,7 @@ void Wasm2JSBuilder::addMemoryGrowFunc(Ref ast, Module* wasm) { ast->push_back(memoryGrowFunc); } -// Wasm2JSGlue emits the core of the module - the functions etc. that would +// Wasm2JSBuilder emits the core of the module - the functions etc. that would // be the asm.js function in an asm.js world. This class emits the rest of the // "glue" around that. class Wasm2JSGlue { @@ -2650,8 +2645,7 @@ void Wasm2JSGlue::emitPostES6() { // Actually invoke the `asmFunc` generated function, passing in all global // values followed by all imports - out << "var ret" << moduleName.str << " = " << moduleName.str << "("; - out << " { abort: function() { throw new Error('abort'); }"; + out << "var ret" << moduleName.str << " = " << moduleName.str << "({\n"; ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) { // The special helpers are emitted in the glue, see code and comments @@ -2659,7 +2653,7 @@ void Wasm2JSGlue::emitPostES6() { if (ABI::wasm2js::isHelper(import->base)) { return; } - out << ",\n " << asmangle(import->base.str); + out << " " << asmangle(import->base.str) << ",\n"; }); ModuleUtils::iterImportedMemories(wasm, [&](Memory* import) { @@ -2668,8 +2662,8 @@ void Wasm2JSGlue::emitPostES6() { if (ABI::wasm2js::isHelper(import->base)) { return; } - out << ",\n " << asmangle(import->base.str) << ": { buffer : mem" - << moduleName.str << " }"; + out << " " << asmangle(import->base.str) << ": { buffer : mem" + << moduleName.str << " }\n"; }); ModuleUtils::iterImportedTables(wasm, [&](Table* import) { @@ -2678,10 +2672,10 @@ void Wasm2JSGlue::emitPostES6() { if (ABI::wasm2js::isHelper(import->base)) { return; } - out << ",\n " << asmangle(import->base.str); + out << " " << asmangle(import->base.str) << ",\n"; }); - out << "\n });\n"; + out << "});\n"; if (flags.allowAsserts) { return; @@ -2811,10 +2805,19 @@ void Wasm2JSGlue::emitSpecialSupport() { // The special support functions are emitted as part of the JS glue, if we // need them. bool need = false; + bool needScratch = false; ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) { if (ABI::wasm2js::isHelper(import->base)) { need = true; } + if (import->base == ABI::wasm2js::SCRATCH_STORE_I32 || + import->base == ABI::wasm2js::SCRATCH_LOAD_I32 || + import->base == ABI::wasm2js::SCRATCH_STORE_F32 || + import->base == ABI::wasm2js::SCRATCH_LOAD_F32 || + import->base == ABI::wasm2js::SCRATCH_STORE_F64 || + import->base == ABI::wasm2js::SCRATCH_LOAD_F64) { + needScratch = true; + } }); if (!need) { return; @@ -2872,14 +2875,19 @@ void Wasm2JSGlue::emitSpecialSupport() { // optimizer runs), so they are guaranteed to be adjacent (and a JS optimizer // that runs later will handle that ok since they are calls, which can always // have side effects). - out << R"( + if (needScratch) { + out << R"( var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); )"; + } ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) { + if (!ABI::wasm2js::isHelper(import->base)) { + return; + } if (import->base == ABI::wasm2js::SCRATCH_STORE_I32) { out << R"( function wasm2js_scratch_store_i32(index, value) { @@ -3012,6 +3020,10 @@ void Wasm2JSGlue::emitSpecialSupport() { return stashedBits; } )"; + } else if (import->base == ABI::wasm2js::TRAP) { + out << "function wasm2js_trap() { throw new Error('abort'); }\n"; + } else { + WASM_UNREACHABLE("bad helper function"); } }); |