Skip to content

Commit

Permalink
Fix stack pointer identification for wasm::ABI::getStackSpace(). (#2243)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
wmaddox authored and kripken committed Jul 28, 2019
1 parent 6ac5fa7 commit be6f7c4
Show file tree
Hide file tree
Showing 3 changed files with 851 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/abi/stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
Expand Down
Loading

0 comments on commit be6f7c4

Please sign in to comment.