Skip to content

Commit be6f7c4

Browse files
wmaddoxkripken
authored andcommitted
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.
1 parent 6ac5fa7 commit be6f7c4

3 files changed

Lines changed: 851 additions & 0 deletions

File tree

src/abi/stack.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,44 @@ inline Index stackAlign(Index size) {
3838
// Allocate some space on the stack, and assign it to a local.
3939
// The local will have the same constant value in all the function, so you can
4040
// just local.get it anywhere there.
41+
//
42+
// FIXME: This function assumes that the stack grows upward, per the convention
43+
// used by fastcomp. The stack grows downward when using the WASM backend.
44+
4145
inline void
4246
getStackSpace(Index local, Function* func, Index size, Module& wasm) {
47+
// Attempt to locate the stack pointer by recognizing code idioms
48+
// used by Emscripten. First, look for a global initialized to an
49+
// imported variable named "STACKTOP" in environment "env".
4350
auto* stackPointer =
4451
GlobalUtils::getGlobalInitializedToImport(wasm, ENV, "STACKTOP");
52+
// Starting with Emscripten 1.38.24, the stack pointer variable is
53+
// initialized with a literal constant, eliminating the import that
54+
// we used to locate the stack pointer by name. We must match a more
55+
// complicated idiom, expecting to see the module structured as follows:
56+
//
57+
//(module
58+
// ...
59+
// (export "stackSave" (func $stackSave))
60+
// ...
61+
// (func $stackSave (; 410 ;) (; has Stack IR ;) (result i32)
62+
// (global.get $STACKTOP)
63+
// )
64+
// ...
65+
//)
66+
if (!stackPointer) {
67+
auto* stackSaveFunctionExport = wasm.getExportOrNull("stackSave");
68+
if (stackSaveFunctionExport &&
69+
stackSaveFunctionExport->kind == ExternalKind::Function) {
70+
auto* stackSaveFunction =
71+
wasm.getFunction(stackSaveFunctionExport->value);
72+
assert(!stackSaveFunction->imported());
73+
auto* globalGet = stackSaveFunction->body->dynCast<GlobalGet>();
74+
if (globalGet) {
75+
stackPointer = wasm.getGlobal(globalGet->name);
76+
}
77+
}
78+
}
4579
if (!stackPointer) {
4680
Fatal() << "getStackSpace: failed to find the stack pointer";
4781
}

0 commit comments

Comments
 (0)