diff options
author | Alon Zakai <azakai@google.com> | 2018-12-11 15:30:16 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2018-12-11 16:35:55 -0800 |
commit | 7edaebedb0f7185fae0f3fbf146a1c6b44842f5c (patch) | |
tree | a804d5759e1f2af056807ad71f7a25e83287feb4 /src | |
parent | 3307ca89fc270bdca7e5124dca8dcb54027918c2 (diff) | |
download | binaryen-7edaebedb0f7185fae0f3fbf146a1c6b44842f5c.tar.gz binaryen-7edaebedb0f7185fae0f3fbf146a1c6b44842f5c.tar.bz2 binaryen-7edaebedb0f7185fae0f3fbf146a1c6b44842f5c.zip |
wasm-emscripten-finalize: import env.STACKTOP, like asm2wasm does
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/wasm-emscripten-finalize.cpp | 1 | ||||
-rw-r--r-- | src/wasm-emscripten.h | 1 | ||||
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 28 |
3 files changed, 25 insertions, 5 deletions
diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp index d477061ae..6c5682703 100644 --- a/src/tools/wasm-emscripten-finalize.cpp +++ b/src/tools/wasm-emscripten-finalize.cpp @@ -187,6 +187,7 @@ int main(int argc, const char *argv[]) { } else { generator.generateRuntimeFunctions(); generator.generateMemoryGrowthFunction(); + generator.generateStackInitialization(); // emscripten calls this by default for side libraries so we only need // to include in as a static ctor for main module case. if (wasm.getExportOrNull("__post_instantiate")) { diff --git a/src/wasm-emscripten.h b/src/wasm-emscripten.h index c15a4b8af..a5de5a128 100644 --- a/src/wasm-emscripten.h +++ b/src/wasm-emscripten.h @@ -36,6 +36,7 @@ public: void generateRuntimeFunctions(); Function* generateMemoryGrowthFunction(); + void generateStackInitialization(); // Create thunks for use with emscripten Runtime.dynCall. Creates one for each // signature in the indirect function table. diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index 09a93a8fe..3c78ce866 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -36,6 +36,7 @@ cashew::IString EM_JS_PREFIX("__em_js__"); static Name STACK_SAVE("stackSave"), STACK_RESTORE("stackRestore"), STACK_ALLOC("stackAlloc"), + STACK_INIT("stack$init"), DUMMY_FUNC("__wasm_nullptr"); void addExportedFunction(Module& wasm, Function* function) { @@ -155,6 +156,21 @@ Function* EmscriptenGlueGenerator::generateMemoryGrowthFunction() { return growFunction; } +void EmscriptenGlueGenerator::generateStackInitialization() { + // Replace a global with a constant initial value with an imported + // initial value, which emscripten JS will send us. + // TODO: with mutable imported globals, we can avoid adding another + // global for the import. + Builder builder(wasm); + auto* import = builder.makeGlobal(STACK_INIT, i32, nullptr, Builder::Immutable); + import->module = ENV; + import->base = STACKTOP; + wasm.addGlobal(import); + auto* stackPointer = getStackPointerGlobal(); + assert(stackPointer->init->is<Const>()); + stackPointer->init = builder.makeGetGlobal(import->name, i32); +} + static bool hasI64ResultOrParam(FunctionType* ft) { if (ft->result == i64) return true; for (auto ty : ft->params) { @@ -227,10 +243,10 @@ static Function* ensureFunctionImport(Module* module, Name name, std::string sig } struct RemoveStackPointer : public PostWalker<RemoveStackPointer> { - RemoveStackPointer(Global* StackPointer) : StackPointer(StackPointer) {} + RemoveStackPointer(Global* stackPointer) : stackPointer(stackPointer) {} void visitGetGlobal(GetGlobal* curr) { - if (getModule()->getGlobalOrNull(curr->name) == StackPointer) { + if (getModule()->getGlobalOrNull(curr->name) == stackPointer) { ensureFunctionImport(getModule(), STACK_SAVE, "i"); if (!builder) builder = make_unique<Builder>(*getModule()); replaceCurrent(builder->makeCall(STACK_SAVE, {}, i32)); @@ -238,7 +254,7 @@ struct RemoveStackPointer : public PostWalker<RemoveStackPointer> { } void visitSetGlobal(SetGlobal* curr) { - if (getModule()->getGlobalOrNull(curr->name) == StackPointer) { + if (getModule()->getGlobalOrNull(curr->name) == stackPointer) { ensureFunctionImport(getModule(), STACK_RESTORE, "vi"); if (!builder) builder = make_unique<Builder>(*getModule()); replaceCurrent(builder->makeCall(STACK_RESTORE, {curr->value}, none)); @@ -247,7 +263,7 @@ struct RemoveStackPointer : public PostWalker<RemoveStackPointer> { private: std::unique_ptr<Builder> builder; - Global* StackPointer; + Global* stackPointer; }; void EmscriptenGlueGenerator::replaceStackPointerGlobal() { @@ -833,7 +849,9 @@ std::string EmscriptenGlueGenerator::generateEmscriptenMetadata( meta << " \"externs\": ["; commaFirst = true; ModuleUtils::iterImportedGlobals(wasm, [&](Global* import) { - meta << nextElement() << "\"_" << import->base.str << '"'; + if (!(import->module == ENV && import->name == STACK_INIT)) { + meta << nextElement() << "\"_" << import->base.str << '"'; + } }); meta << "\n ],\n"; |