@@ -36,6 +36,7 @@ cashew::IString EM_JS_PREFIX("__em_js__");
36
36
static Name STACK_SAVE (" stackSave" ),
37
37
STACK_RESTORE(" stackRestore" ),
38
38
STACK_ALLOC(" stackAlloc" ),
39
+ STACK_INIT(" stack$init" ),
39
40
DUMMY_FUNC(" __wasm_nullptr" );
40
41
41
42
void addExportedFunction (Module& wasm, Function* function) {
@@ -155,6 +156,21 @@ Function* EmscriptenGlueGenerator::generateMemoryGrowthFunction() {
155
156
return growFunction;
156
157
}
157
158
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
+
158
174
static bool hasI64ResultOrParam (FunctionType* ft) {
159
175
if (ft->result == i64 ) return true ;
160
176
for (auto ty : ft->params ) {
@@ -227,18 +243,18 @@ static Function* ensureFunctionImport(Module* module, Name name, std::string sig
227
243
}
228
244
229
245
struct RemoveStackPointer : public PostWalker <RemoveStackPointer> {
230
- RemoveStackPointer (Global* StackPointer ) : StackPointer(StackPointer ) {}
246
+ RemoveStackPointer (Global* stackPointer ) : stackPointer(stackPointer ) {}
231
247
232
248
void visitGetGlobal (GetGlobal* curr) {
233
- if (getModule ()->getGlobalOrNull (curr->name ) == StackPointer ) {
249
+ if (getModule ()->getGlobalOrNull (curr->name ) == stackPointer ) {
234
250
ensureFunctionImport (getModule (), STACK_SAVE, " i" );
235
251
if (!builder) builder = make_unique<Builder>(*getModule ());
236
252
replaceCurrent (builder->makeCall (STACK_SAVE, {}, i32 ));
237
253
}
238
254
}
239
255
240
256
void visitSetGlobal (SetGlobal* curr) {
241
- if (getModule ()->getGlobalOrNull (curr->name ) == StackPointer ) {
257
+ if (getModule ()->getGlobalOrNull (curr->name ) == stackPointer ) {
242
258
ensureFunctionImport (getModule (), STACK_RESTORE, " vi" );
243
259
if (!builder) builder = make_unique<Builder>(*getModule ());
244
260
replaceCurrent (builder->makeCall (STACK_RESTORE, {curr->value }, none));
@@ -247,7 +263,7 @@ struct RemoveStackPointer : public PostWalker<RemoveStackPointer> {
247
263
248
264
private:
249
265
std::unique_ptr<Builder> builder;
250
- Global* StackPointer ;
266
+ Global* stackPointer ;
251
267
};
252
268
253
269
void EmscriptenGlueGenerator::replaceStackPointerGlobal () {
@@ -833,7 +849,9 @@ std::string EmscriptenGlueGenerator::generateEmscriptenMetadata(
833
849
meta << " \" externs\" : [" ;
834
850
commaFirst = true ;
835
851
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
+ }
837
855
});
838
856
meta << " \n ],\n " ;
839
857
0 commit comments