summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/abi/js.h4
-rw-r--r--src/asmjs/shared-constants.cpp2
-rw-r--r--src/asmjs/shared-constants.h1
-rw-r--r--src/wasm2js.h48
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");
}
});