Skip to content

Commit 7edaebe

Browse files
committed
wasm-emscripten-finalize: import env.STACKTOP, like asm2wasm does
1 parent 3307ca8 commit 7edaebe

12 files changed

+43
-14
lines changed

src/tools/wasm-emscripten-finalize.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ int main(int argc, const char *argv[]) {
187187
} else {
188188
generator.generateRuntimeFunctions();
189189
generator.generateMemoryGrowthFunction();
190+
generator.generateStackInitialization();
190191
// emscripten calls this by default for side libraries so we only need
191192
// to include in as a static ctor for main module case.
192193
if (wasm.getExportOrNull("__post_instantiate")) {

src/wasm-emscripten.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class EmscriptenGlueGenerator {
3636

3737
void generateRuntimeFunctions();
3838
Function* generateMemoryGrowthFunction();
39+
void generateStackInitialization();
3940

4041
// Create thunks for use with emscripten Runtime.dynCall. Creates one for each
4142
// signature in the indirect function table.

src/wasm/wasm-emscripten.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ cashew::IString EM_JS_PREFIX("__em_js__");
3636
static Name STACK_SAVE("stackSave"),
3737
STACK_RESTORE("stackRestore"),
3838
STACK_ALLOC("stackAlloc"),
39+
STACK_INIT("stack$init"),
3940
DUMMY_FUNC("__wasm_nullptr");
4041

4142
void 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+
158174
static 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

229245
struct 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

248264
private:
249265
std::unique_ptr<Builder> builder;
250-
Global* StackPointer;
266+
Global* stackPointer;
251267
};
252268

253269
void 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

test/lld/duplicate_imports.wast.out

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99
(type $legaltype$puts2 (func (param i32 i32) (result i32)))
1010
(type $legaltype$invoke_ffd (func (param i32 f64 f64) (result f64)))
1111
(type $legaltype$invoke_ffd2 (func (param i32 f64 f64) (result f64)))
12+
(import "env" "STACKTOP" (global $stack$init i32))
1213
(import "env" "puts" (func $puts1 (param i32) (result i32)))
1314
(import "env" "puts" (func $legalimport$puts2 (param i32 i32) (result i32)))
1415
(import "env" "invoke_ffd" (func $legalimport$invoke_ffd (param i32 f64 f64) (result f64)))
1516
(import "env" "invoke_ffd" (func $legalimport$invoke_ffd2 (param i32 f64 f64) (result f64)))
1617
(memory $0 2)
1718
(data (i32.const 568) "Hello, world\00")
1819
(table $0 1 1 anyfunc)
19-
(global $global$0 (mut i32) (i32.const 66128))
20+
(global $global$0 (mut i32) (get_global $stack$init))
2021
(global $global$1 i32 (i32.const 66128))
2122
(global $global$2 i32 (i32.const 581))
2223
(export "memory" (memory $0))

test/lld/em_asm.wast.out

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
(type $FUNCSIG$ii (func (param i32) (result i32)))
88
(type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
99
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
10+
(import "env" "STACKTOP" (global $stack$init i32))
1011
(import "env" "emscripten_asm_const_i" (func $emscripten_asm_const_i (param i32) (result i32)))
1112
(import "env" "emscripten_asm_const_iii" (func $emscripten_asm_const_iii (param i32 i32 i32) (result i32)))
1213
(import "env" "emscripten_asm_const_ii" (func $emscripten_asm_const_ii (param i32 i32) (result i32)))
1314
(memory $0 2)
1415
(data (i32.const 568) "{ Module.print(\"Hello world\"); }\00{ return $0 + $1; }\00{ Module.print(\"Got \" + $0); }\00")
1516
(table $0 1 1 anyfunc)
16-
(global $global$0 (mut i32) (i32.const 66192))
17+
(global $global$0 (mut i32) (get_global $stack$init))
1718
(global $global$1 i32 (i32.const 66192))
1819
(global $global$2 i32 (i32.const 652))
1920
(export "memory" (memory $0))

test/lld/em_asm_table.wast.out

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
(type $FUNCSIG$vii (func (param i32 i32)))
55
(type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
66
(import "env" "memory" (memory $0 8192))
7+
(import "env" "STACKTOP" (global $stack$init i32))
78
(import "env" "emscripten_log" (func $fimport$0 (param i32 i32)))
89
(import "env" "emscripten_asm_const_iii" (func $emscripten_asm_const_iii (param i32 i32 i32) (result i32)))
910
(table $0 159609 anyfunc)
1011
(elem (i32.const 1) $fimport$0 $emscripten_asm_const_iii)
11-
(global $global$0 (mut i32) (i32.const 1024))
12+
(global $global$0 (mut i32) (get_global $stack$init))
1213
(global $global$1 i32 (i32.const 1048))
1314
(export "__data_end" (global $global$1))
1415
(export "stackSave" (func $stackSave))

test/lld/hello_world.wast.mem.out

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
(type $1 (func (result i32)))
44
(type $2 (func))
55
(type $FUNCSIG$ii (func (param i32) (result i32)))
6+
(import "env" "STACKTOP" (global $stack$init i32))
67
(import "env" "puts" (func $puts (param i32) (result i32)))
78
(memory $0 2)
89
(table $0 1 1 anyfunc)
9-
(global $global$0 (mut i32) (i32.const 66128))
10+
(global $global$0 (mut i32) (get_global $stack$init))
1011
(global $global$1 i32 (i32.const 66128))
1112
(global $global$2 i32 (i32.const 581))
1213
(export "memory" (memory $0))

test/lld/hello_world.wast.out

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
(type $1 (func (result i32)))
44
(type $2 (func))
55
(type $FUNCSIG$ii (func (param i32) (result i32)))
6+
(import "env" "STACKTOP" (global $stack$init i32))
67
(import "env" "puts" (func $puts (param i32) (result i32)))
78
(memory $0 2)
89
(data (i32.const 568) "Hello, world\00")
910
(table $0 1 1 anyfunc)
10-
(global $global$0 (mut i32) (i32.const 66128))
11+
(global $global$0 (mut i32) (get_global $stack$init))
1112
(global $global$1 i32 (i32.const 66128))
1213
(global $global$2 i32 (i32.const 581))
1314
(export "memory" (memory $0))

test/lld/init.wast.out

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
(module
22
(type $0 (func))
33
(type $1 (func (result i32)))
4+
(import "env" "STACKTOP" (global $stack$init i32))
45
(memory $0 2)
56
(data (i32.const 568) "\00\00\00\00\00\00\00\00")
67
(table $0 1 1 anyfunc)
7-
(global $global$0 (mut i32) (i32.const 66112))
8+
(global $global$0 (mut i32) (get_global $stack$init))
89
(global $global$1 i32 (i32.const 66112))
910
(global $global$2 i32 (i32.const 576))
1011
(export "memory" (memory $0))

test/lld/recursive.wast.out

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
(type $1 (func (result i32)))
44
(type $2 (func))
55
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
6+
(import "env" "STACKTOP" (global $stack$init i32))
67
(import "env" "printf" (func $printf (param i32 i32) (result i32)))
78
(memory $0 2)
89
(data (i32.const 568) "%d:%d\n\00Result: %d\n\00")
910
(table $0 1 1 anyfunc)
10-
(global $global$0 (mut i32) (i32.const 66128))
11+
(global $global$0 (mut i32) (get_global $stack$init))
1112
(global $global$1 i32 (i32.const 66128))
1213
(global $global$2 i32 (i32.const 587))
1314
(export "memory" (memory $0))

0 commit comments

Comments
 (0)