summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/asm2wasm.h10
-rw-r--r--src/tools/wasm-emscripten-finalize.cpp20
-rw-r--r--src/wasm-emscripten.h2
-rw-r--r--src/wasm/wasm-emscripten.cpp14
4 files changed, 26 insertions, 20 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h
index d958c4b6a..c193791f8 100644
--- a/src/asm2wasm.h
+++ b/src/asm2wasm.h
@@ -426,13 +426,16 @@ public:
std::map<IString, MappedGlobal> mappedGlobals;
private:
- void allocateGlobal(IString name, Type type) {
+ void allocateGlobal(IString name, Type type, Literal value=Literal()) {
assert(mappedGlobals.find(name) == mappedGlobals.end());
+ if (value.type == none) {
+ value = Literal::makeZero(type);
+ }
mappedGlobals.emplace(name, MappedGlobal(type));
wasm.addGlobal(builder.makeGlobal(
name,
type,
- LiteralUtils::makeZero(type, wasm),
+ builder.makeConst(value),
Builder::Mutable
));
}
@@ -986,8 +989,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
Ref value = pair[1];
if (value->isNumber()) {
// global int
- assert(value->getNumber() == 0);
- allocateGlobal(name, Type::i32);
+ allocateGlobal(name, Type::i32, Literal(int32_t(value->getInteger())));
} else if (value[0] == BINARY) {
// int import
assert(value[1] == OR && value[3]->isNumber() && value[3]->getNumber() == 0);
diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp
index 3d74138cc..3ea3629c5 100644
--- a/src/tools/wasm-emscripten-finalize.cpp
+++ b/src/tools/wasm-emscripten-finalize.cpp
@@ -36,6 +36,8 @@ using namespace cashew;
using namespace wasm;
int main(int argc, const char *argv[]) {
+ const uint64_t INVALID_BASE = -1;
+
std::string infile;
std::string outfile;
std::string inputSourceMapFilename;
@@ -46,7 +48,8 @@ int main(int argc, const char *argv[]) {
bool debugInfo = false;
bool legalizeJavaScriptFFI = true;
unsigned numReservedFunctionPointers = 0;
- uint64_t globalBase;
+ uint64_t globalBase = INVALID_BASE;
+ uint64_t initialStackPointer = INVALID_BASE;
Options options("wasm-emscripten-finalize",
"Performs Emscripten-specific transforms on .wasm files");
options
@@ -75,11 +78,16 @@ int main(int argc, const char *argv[]) {
const std::string &argument) {
numReservedFunctionPointers = std::stoi(argument);
})
- .add("--global-base", "", "Where lld started to place globals",
+ .add("--global-base", "", "The address at which static globals were placed",
Options::Arguments::One,
[&globalBase](Options*, const std::string&argument ) {
globalBase = std::stoull(argument);
})
+ .add("--initial-stack-pointer", "", "The initial location of the stack pointer",
+ Options::Arguments::One,
+ [&initialStackPointer](Options*, const std::string&argument ) {
+ initialStackPointer = std::stoull(argument);
+ })
.add("--input-source-map", "-ism", "Consume source map from the specified file",
Options::Arguments::One,
@@ -141,6 +149,12 @@ int main(int argc, const char *argv[]) {
uint32_t dataSize = 0;
if (!isSideModule) {
+ if (globalBase == INVALID_BASE) {
+ Fatal() << "globalBase must be set";
+ }
+ if (initialStackPointer == INVALID_BASE) {
+ Fatal() << "initialStackPointer must be set";
+ }
Export* dataEndExport = wasm.getExport("__data_end");
if (dataEndExport == nullptr) {
Fatal() << "__data_end export not found";
@@ -189,7 +203,7 @@ int main(int argc, const char *argv[]) {
} else {
generator.generateRuntimeFunctions();
generator.generateMemoryGrowthFunction();
- generator.generateStackInitialization();
+ generator.generateStackInitialization(initialStackPointer);
// 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 2b626a7c9..d078cafbf 100644
--- a/src/wasm-emscripten.h
+++ b/src/wasm-emscripten.h
@@ -36,7 +36,7 @@ public:
void generateRuntimeFunctions();
Function* generateMemoryGrowthFunction();
- void generateStackInitialization();
+ void generateStackInitialization(Address addr);
// 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 b18fe0c76..88e66ea07 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -156,19 +156,9 @@ 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);
+void EmscriptenGlueGenerator::generateStackInitialization(Address addr) {
auto* stackPointer = getStackPointerGlobal();
- assert(stackPointer->init->is<Const>());
- stackPointer->init = builder.makeGetGlobal(import->name, i32);
+ stackPointer->init->cast<Const>()->value = Literal(int32_t(addr));
}
static bool hasI64ResultOrParam(FunctionType* ft) {