summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2018-12-11 15:30:16 -0800
committerAlon Zakai <alonzakai@gmail.com>2018-12-11 16:35:55 -0800
commit7edaebedb0f7185fae0f3fbf146a1c6b44842f5c (patch)
treea804d5759e1f2af056807ad71f7a25e83287feb4 /src
parent3307ca89fc270bdca7e5124dca8dcb54027918c2 (diff)
downloadbinaryen-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.cpp1
-rw-r--r--src/wasm-emscripten.h1
-rw-r--r--src/wasm/wasm-emscripten.cpp28
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";