summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/PostEmscripten.cpp21
-rw-r--r--src/wasm-emscripten.h3
-rw-r--r--src/wasm/wasm-emscripten.cpp12
-rw-r--r--test/passes/post-emscripten_pass-arg=stack-pointer@1234.txt4
-rw-r--r--test/passes/post-emscripten_pass-arg=stack-pointer@1234.wast4
5 files changed, 37 insertions, 7 deletions
diff --git a/src/passes/PostEmscripten.cpp b/src/passes/PostEmscripten.cpp
index 8efaae8c5..68f0c06e0 100644
--- a/src/passes/PostEmscripten.cpp
+++ b/src/passes/PostEmscripten.cpp
@@ -28,8 +28,11 @@
#include <pass.h>
#include <shared-constants.h>
#include <wasm-builder.h>
+#include <wasm-emscripten.h>
#include <wasm.h>
+#define DEBUG_TYPE "post-emscripten"
+
namespace wasm {
namespace {
@@ -75,6 +78,24 @@ struct OptimizeCalls : public WalkerPass<PostWalker<OptimizeCalls>> {
struct PostEmscripten : public Pass {
void run(PassRunner* runner, Module* module) override {
+ // Apply the stack pointer, if it was provided. This is needed here
+ // because the emscripten JS compiler can add static data allocations that
+ // come before the stack.
+ auto stackPtrStr =
+ runner->options.getArgumentOrDefault("stack-pointer", "");
+ if (stackPtrStr != "") {
+ Global* stackPointer = getStackPointerGlobal(*module);
+ BYN_TRACE("stack_pointer: " << stackPtrStr << "\n");
+ if (stackPointer && !stackPointer->imported()) {
+ auto stackPtr = std::stoi(stackPtrStr);
+ auto oldValue = stackPointer->init->cast<Const>()->value;
+ BYN_TRACE("updating __stack_pointer: " << oldValue.geti32() << " -> "
+ << stackPtr << "\n");
+ stackPointer->init =
+ Builder(*module).makeConst(Literal(int32_t(stackPtr)));
+ }
+ }
+
// Apply the sbrk ptr, if it was provided.
auto sbrkPtrStr =
runner->options.getArgumentOrDefault("emscripten-sbrk-ptr", "");
diff --git a/src/wasm-emscripten.h b/src/wasm-emscripten.h
index 80277cb18..5ede78375 100644
--- a/src/wasm-emscripten.h
+++ b/src/wasm-emscripten.h
@@ -23,6 +23,8 @@
namespace wasm {
+Global* getStackPointerGlobal(Module& wasm);
+
// Class which modifies a wasm module for use with emscripten. Generates
// runtime functions and emits metadata.
class EmscriptenGlueGenerator {
@@ -78,7 +80,6 @@ private:
// so far.
std::unordered_set<Signature> sigs;
- Global* getStackPointerGlobal();
Expression* generateLoadStackPointer();
Expression* generateStoreStackPointer(Function* func, Expression* value);
void generateDynCallThunk(Signature sig);
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index 460af19c2..4bc1aa08e 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -65,7 +65,7 @@ bool isExported(Module& wasm, Name name) {
return false;
}
-Global* EmscriptenGlueGenerator::getStackPointerGlobal() {
+Global* getStackPointerGlobal(Module& wasm) {
// Assumption: The stack pointer is either imported as __stack_pointer or
// its the first non-imported and non-exported global.
// TODO(sbc): Find a better way to discover the stack pointer. Perhaps the
@@ -92,7 +92,7 @@ Expression* EmscriptenGlueGenerator::generateLoadStackPointer() {
/* ptr =*/builder.makeConst(Literal(0)),
/* type =*/Type::i32);
}
- Global* stackPointer = getStackPointerGlobal();
+ Global* stackPointer = getStackPointerGlobal(wasm);
if (!stackPointer) {
Fatal() << "stack pointer global not found";
}
@@ -142,7 +142,7 @@ EmscriptenGlueGenerator::generateStoreStackPointer(Function* func,
/* value =*/value,
/* type =*/Type::i32);
}
- Global* stackPointer = getStackPointerGlobal();
+ Global* stackPointer = getStackPointerGlobal(wasm);
if (!stackPointer) {
Fatal() << "stack pointer global not found";
}
@@ -530,7 +530,7 @@ private:
// __stack_pointer and initializes it from an immutable global instead.
// For -shared builds we instead call replaceStackPointerGlobal.
void EmscriptenGlueGenerator::internalizeStackPointerGlobal() {
- Global* stackPointer = getStackPointerGlobal();
+ Global* stackPointer = getStackPointerGlobal(wasm);
if (!stackPointer || !stackPointer->imported() || !stackPointer->mutable_) {
return;
}
@@ -552,7 +552,7 @@ void EmscriptenGlueGenerator::internalizeStackPointerGlobal() {
}
void EmscriptenGlueGenerator::replaceStackPointerGlobal() {
- Global* stackPointer = getStackPointerGlobal();
+ Global* stackPointer = getStackPointerGlobal(wasm);
if (!stackPointer) {
return;
}
@@ -606,7 +606,7 @@ private:
};
void EmscriptenGlueGenerator::enforceStackLimit() {
- Global* stackPointer = getStackPointerGlobal();
+ Global* stackPointer = getStackPointerGlobal(wasm);
if (!stackPointer) {
return;
}
diff --git a/test/passes/post-emscripten_pass-arg=stack-pointer@1234.txt b/test/passes/post-emscripten_pass-arg=stack-pointer@1234.txt
new file mode 100644
index 000000000..7f389e2de
--- /dev/null
+++ b/test/passes/post-emscripten_pass-arg=stack-pointer@1234.txt
@@ -0,0 +1,4 @@
+(module
+ (import "env" "not_stack" (global $import$global0 i32))
+ (global $should_be_stack_pointer (mut i32) (i32.const 1234))
+)
diff --git a/test/passes/post-emscripten_pass-arg=stack-pointer@1234.wast b/test/passes/post-emscripten_pass-arg=stack-pointer@1234.wast
new file mode 100644
index 000000000..c96bbf4f9
--- /dev/null
+++ b/test/passes/post-emscripten_pass-arg=stack-pointer@1234.wast
@@ -0,0 +1,4 @@
+(module
+ (import "env" "not_stack" (global i32))
+ (global $should_be_stack_pointer (mut i32) (i32.const 2))
+)