diff options
author | William Maddox <16312695+wmaddox@users.noreply.github.com> | 2019-07-28 11:02:14 -0700 |
---|---|---|
committer | Alon Zakai <azakai@google.com> | 2019-07-28 11:02:14 -0700 |
commit | be6f7c4795ab3bc135e10162b0d7a1063e5d65ba (patch) | |
tree | 081fcb0744be156ad05b374227d8777cc896ef65 /src/abi/stack.h | |
parent | 6ac5fa713b421588eede2e791235e4b60b22b172 (diff) | |
download | binaryen-be6f7c4795ab3bc135e10162b0d7a1063e5d65ba.tar.gz binaryen-be6f7c4795ab3bc135e10162b0d7a1063e5d65ba.tar.bz2 binaryen-be6f7c4795ab3bc135e10162b0d7a1063e5d65ba.zip |
Fix stack pointer identification for wasm::ABI::getStackSpace(). (#2243)
* Fix stack pointer identification for wasm::ABI::getStackSpace().
Recent stack pointer simplification in Emscripten broke the --spill-pointers
pass. This fix for #2229 restores this functionality by recognizing an
alternative coding idiom in Emscripten-generated WASM code.
Diffstat (limited to 'src/abi/stack.h')
-rw-r--r-- | src/abi/stack.h | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/abi/stack.h b/src/abi/stack.h index 72220645c..22cd8ba3c 100644 --- a/src/abi/stack.h +++ b/src/abi/stack.h @@ -38,10 +38,44 @@ inline Index stackAlign(Index size) { // Allocate some space on the stack, and assign it to a local. // The local will have the same constant value in all the function, so you can // just local.get it anywhere there. +// +// FIXME: This function assumes that the stack grows upward, per the convention +// used by fastcomp. The stack grows downward when using the WASM backend. + inline void getStackSpace(Index local, Function* func, Index size, Module& wasm) { + // Attempt to locate the stack pointer by recognizing code idioms + // used by Emscripten. First, look for a global initialized to an + // imported variable named "STACKTOP" in environment "env". auto* stackPointer = GlobalUtils::getGlobalInitializedToImport(wasm, ENV, "STACKTOP"); + // Starting with Emscripten 1.38.24, the stack pointer variable is + // initialized with a literal constant, eliminating the import that + // we used to locate the stack pointer by name. We must match a more + // complicated idiom, expecting to see the module structured as follows: + // + //(module + // ... + // (export "stackSave" (func $stackSave)) + // ... + // (func $stackSave (; 410 ;) (; has Stack IR ;) (result i32) + // (global.get $STACKTOP) + // ) + // ... + //) + if (!stackPointer) { + auto* stackSaveFunctionExport = wasm.getExportOrNull("stackSave"); + if (stackSaveFunctionExport && + stackSaveFunctionExport->kind == ExternalKind::Function) { + auto* stackSaveFunction = + wasm.getFunction(stackSaveFunctionExport->value); + assert(!stackSaveFunction->imported()); + auto* globalGet = stackSaveFunction->body->dynCast<GlobalGet>(); + if (globalGet) { + stackPointer = wasm.getGlobal(globalGet->name); + } + } + } if (!stackPointer) { Fatal() << "getStackSpace: failed to find the stack pointer"; } |