diff options
author | Alon Zakai <azakai@google.com> | 2019-12-12 19:15:39 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-12 19:15:39 -0800 |
commit | 16c6b44da64630cd6906433cf35edabcea93cffc (patch) | |
tree | f36d41e14f17b64bbfd3f7080cb624565fc11c59 /src/wasm | |
parent | 89d1cf92be0636a219ee6415eead387241963dcf (diff) | |
download | binaryen-16c6b44da64630cd6906433cf35edabcea93cffc.tar.gz binaryen-16c6b44da64630cd6906433cf35edabcea93cffc.tar.bz2 binaryen-16c6b44da64630cd6906433cf35edabcea93cffc.zip |
Support stack overflow checks in standalone mode (#2525)
In normal mode we call a JS import, but we can't import from JS
in standalone mode. Instead, just trap in that case with an
unreachable. (The error reporting is not as good in this case, but
at least it catches all errors and halts, and the emitted wasm is
valid for standalone mode.)
Helps emscripten-core/emscripten#10019
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index be4e51b9e..f069e558d 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -103,18 +103,25 @@ inline Expression* stackBoundsCheck(Builder& builder, Expression* value, Global* stackPointer, Global* stackLimit, - Name handler) { + Name handlerName) { // Add a local to store the value of the expression. We need the value twice: // once to check if it has overflowed, and again to assign to store it. auto newSP = Builder::addVar(func, stackPointer->type); + // If we imported a handler, call it. That can show a nice error in JS. + // Otherwise, just trap. + Expression* handler; + if (handlerName.is()) { + handler = builder.makeCall(handlerName, {}, none); + } else { + handler = builder.makeUnreachable(); + } // (if (i32.lt_u (local.tee $newSP (...value...)) (global.get $__stack_limit)) - // (call $handler)) auto check = builder.makeIf(builder.makeBinary( BinaryOp::LtUInt32, builder.makeLocalTee(newSP, value, stackPointer->type), builder.makeGlobalGet(stackLimit->name, stackLimit->type)), - builder.makeCall(handler, {}, none)); + handler); // (global.set $__stack_pointer (local.get $newSP)) auto newSet = builder.makeGlobalSet( stackPointer->name, builder.makeLocalGet(newSP, stackPointer->type)); @@ -530,8 +537,7 @@ void EmscriptenGlueGenerator::enforceStackLimit() { Builder::Mutable); wasm.addGlobal(stackLimit); - auto handler = importStackOverflowHandler(); - + Name handler = importStackOverflowHandler(); StackLimitEnforcer walker(stackPointer, stackLimit, builder, handler); PassRunner runner(&wasm); walker.run(&runner, &wasm); @@ -549,6 +555,12 @@ void EmscriptenGlueGenerator::generateSetStackLimitFunction() { } Name EmscriptenGlueGenerator::importStackOverflowHandler() { + // We can call an import to handle stack overflows normally, but not in + // standalone mode, where we can't import from JS. + if (standalone) { + return Name(); + } + ImportInfo info(wasm); if (auto* existing = info.getImportedFunction(ENV, STACK_OVERFLOW_IMPORT)) { |