@@ -36,6 +36,7 @@ cashew::IString EM_JS_PREFIX("__em_js__");
3636static Name STACK_SAVE (" stackSave" ),
3737 STACK_RESTORE(" stackRestore" ),
3838 STACK_ALLOC(" stackAlloc" ),
39+ STACK_INIT(" stack$init" ),
3940 DUMMY_FUNC(" __wasm_nullptr" );
4041
4142void addExportedFunction (Module& wasm, Function* function) {
@@ -155,6 +156,21 @@ Function* EmscriptenGlueGenerator::generateMemoryGrowthFunction() {
155156 return growFunction;
156157}
157158
159+ void EmscriptenGlueGenerator::generateStackInitialization () {
160+ // Replace a global with a constant initial value with an imported
161+ // initial value, which emscripten JS will send us.
162+ // TODO: with mutable imported globals, we can avoid adding another
163+ // global for the import.
164+ Builder builder (wasm);
165+ auto * import = builder.makeGlobal (STACK_INIT, i32 , nullptr , Builder::Immutable);
166+ import ->module = ENV;
167+ import ->base = STACKTOP;
168+ wasm.addGlobal (import );
169+ auto * stackPointer = getStackPointerGlobal ();
170+ assert (stackPointer->init ->is <Const>());
171+ stackPointer->init = builder.makeGetGlobal (import ->name , i32 );
172+ }
173+
158174static bool hasI64ResultOrParam (FunctionType* ft) {
159175 if (ft->result == i64 ) return true ;
160176 for (auto ty : ft->params ) {
@@ -227,18 +243,18 @@ static Function* ensureFunctionImport(Module* module, Name name, std::string sig
227243}
228244
229245struct RemoveStackPointer : public PostWalker <RemoveStackPointer> {
230- RemoveStackPointer (Global* StackPointer ) : StackPointer(StackPointer ) {}
246+ RemoveStackPointer (Global* stackPointer ) : stackPointer(stackPointer ) {}
231247
232248 void visitGetGlobal (GetGlobal* curr) {
233- if (getModule ()->getGlobalOrNull (curr->name ) == StackPointer ) {
249+ if (getModule ()->getGlobalOrNull (curr->name ) == stackPointer ) {
234250 ensureFunctionImport (getModule (), STACK_SAVE, " i" );
235251 if (!builder) builder = make_unique<Builder>(*getModule ());
236252 replaceCurrent (builder->makeCall (STACK_SAVE, {}, i32 ));
237253 }
238254 }
239255
240256 void visitSetGlobal (SetGlobal* curr) {
241- if (getModule ()->getGlobalOrNull (curr->name ) == StackPointer ) {
257+ if (getModule ()->getGlobalOrNull (curr->name ) == stackPointer ) {
242258 ensureFunctionImport (getModule (), STACK_RESTORE, " vi" );
243259 if (!builder) builder = make_unique<Builder>(*getModule ());
244260 replaceCurrent (builder->makeCall (STACK_RESTORE, {curr->value }, none));
@@ -247,7 +263,7 @@ struct RemoveStackPointer : public PostWalker<RemoveStackPointer> {
247263
248264private:
249265 std::unique_ptr<Builder> builder;
250- Global* StackPointer ;
266+ Global* stackPointer ;
251267};
252268
253269void EmscriptenGlueGenerator::replaceStackPointerGlobal () {
@@ -833,7 +849,9 @@ std::string EmscriptenGlueGenerator::generateEmscriptenMetadata(
833849 meta << " \" externs\" : [" ;
834850 commaFirst = true ;
835851 ModuleUtils::iterImportedGlobals (wasm, [&](Global* import ) {
836- meta << nextElement () << " \" _" << import ->base .str << ' "' ;
852+ if (!(import ->module == ENV && import ->name == STACK_INIT)) {
853+ meta << nextElement () << " \" _" << import ->base .str << ' "' ;
854+ }
837855 });
838856 meta << " \n ],\n " ;
839857
0 commit comments