summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-emscripten.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-emscripten.cpp')
-rw-r--r--src/wasm/wasm-emscripten.cpp23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index 3c78ce866..b18fe0c76 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -247,7 +247,7 @@ struct RemoveStackPointer : public PostWalker<RemoveStackPointer> {
void visitGetGlobal(GetGlobal* curr) {
if (getModule()->getGlobalOrNull(curr->name) == stackPointer) {
- ensureFunctionImport(getModule(), STACK_SAVE, "i");
+ needStackSave = true;
if (!builder) builder = make_unique<Builder>(*getModule());
replaceCurrent(builder->makeCall(STACK_SAVE, {}, i32));
}
@@ -255,12 +255,15 @@ struct RemoveStackPointer : public PostWalker<RemoveStackPointer> {
void visitSetGlobal(SetGlobal* curr) {
if (getModule()->getGlobalOrNull(curr->name) == stackPointer) {
- ensureFunctionImport(getModule(), STACK_RESTORE, "vi");
+ needStackRestore = true;
if (!builder) builder = make_unique<Builder>(*getModule());
replaceCurrent(builder->makeCall(STACK_RESTORE, {curr->value}, none));
}
}
+ bool needStackSave = false;
+ bool needStackRestore = false;
+
private:
std::unique_ptr<Builder> builder;
Global* stackPointer;
@@ -272,6 +275,12 @@ void EmscriptenGlueGenerator::replaceStackPointerGlobal() {
// Replace all uses of stack pointer global
RemoveStackPointer walker(stackPointer);
walker.walkModule(&wasm);
+ if (walker.needStackSave) {
+ ensureFunctionImport(&wasm, STACK_SAVE, "i");
+ }
+ if (walker.needStackRestore) {
+ ensureFunctionImport(&wasm, STACK_RESTORE, "vi");
+ }
// Finally remove the stack pointer global itself. This avoids importing
// a mutable global.
@@ -331,6 +340,7 @@ void EmscriptenGlueGenerator::generateJSCallThunks(
JSCallWalker walker = getJSCallWalker(wasm);
auto& tableSegmentData = wasm.table.segments[0].data;
+ unsigned numEntriesAdded = 0;
for (std::string sig : walker.indirectlyCallableSigs) {
// Add imports for jsCall_sig (e.g. jsCall_vi).
// Imported jsCall_sig functions have their first parameter as an index to
@@ -371,11 +381,13 @@ void EmscriptenGlueGenerator::generateJSCallThunks(
f->body = call;
wasm.addFunction(f);
tableSegmentData.push_back(f->name);
+ numEntriesAdded++;
}
}
- wasm.table.initial = wasm.table.max =
- wasm.table.segments[0].offset->cast<Const>()->value.getInteger() +
- tableSegmentData.size();
+ wasm.table.initial.addr += numEntriesAdded;
+ if (wasm.table.max != Table::kUnlimitedSize) {
+ wasm.table.max.addr += numEntriesAdded;
+ }
}
std::vector<Address> getSegmentOffsets(Module& wasm) {
@@ -800,6 +812,7 @@ std::string EmscriptenGlueGenerator::generateEmscriptenMetadata(
}
meta << " \"staticBump\": " << staticBump << ",\n";
+ meta << " \"tableSize\": " << wasm.table.initial.addr << ",\n";
if (!initializerFunctions.empty()) {
meta << " \"initializers\": [";