summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2018-11-15 10:22:12 -0800
committerGitHub <noreply@github.com>2018-11-15 10:22:12 -0800
commitec16a4d076d290f892fc00f598777631cdda5f09 (patch)
tree9f1be6bd53e9a5d2b78eed7ba0de35f969bb585e
parentf1666bd5eb86324867b50a9aa3d039832183f8d1 (diff)
downloadbinaryen-ec16a4d076d290f892fc00f598777631cdda5f09.tar.gz
binaryen-ec16a4d076d290f892fc00f598777631cdda5f09.tar.bz2
binaryen-ec16a4d076d290f892fc00f598777631cdda5f09.zip
wasm-emscripten-finalize: Initial support for handling shared libraries (#1746)
In this case we won't want generate any of the normal memory helper functions (they come from the main module).
-rw-r--r--src/tools/wasm-emscripten-finalize.cpp39
-rw-r--r--src/wasm-emscripten.h3
-rw-r--r--src/wasm/wasm-emscripten.cpp19
3 files changed, 36 insertions, 25 deletions
diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp
index 495ed5df9..6814ae032 100644
--- a/src/tools/wasm-emscripten-finalize.cpp
+++ b/src/tools/wasm-emscripten-finalize.cpp
@@ -130,19 +130,30 @@ int main(int argc, const char *argv[]) {
WasmPrinter::printModule(&wasm, std::cerr);
}
- Export* dataEndExport = wasm.getExport("__data_end");
- if (dataEndExport == nullptr) {
- Fatal() << "__data_end export not found";
+ bool isSideModule = false;
+ for (const UserSection& section : wasm.userSections) {
+ if (section.name == BinaryConsts::UserSections::Dylink) {
+ isSideModule = true;
+ }
}
- Global* dataEnd = wasm.getGlobal(dataEndExport->value);
- if (dataEnd == nullptr) {
- Fatal() << "__data_end global not found";
- }
- if (dataEnd->type != Type::i32) {
- Fatal() << "__data_end global has wrong type";
+
+ uint32_t dataSize = 0;
+
+ if (!isSideModule) {
+ Export* dataEndExport = wasm.getExport("__data_end");
+ if (dataEndExport == nullptr) {
+ Fatal() << "__data_end export not found";
+ }
+ Global* dataEnd = wasm.getGlobal(dataEndExport->value);
+ if (dataEnd == nullptr) {
+ Fatal() << "__data_end global not found";
+ }
+ if (dataEnd->type != Type::i32) {
+ Fatal() << "__data_end global has wrong type";
+ }
+ Const* dataEndConst = dataEnd->init->cast<Const>();
+ dataSize = dataEndConst->value.geti32() - globalBase;
}
- Const* dataEndConst = dataEnd->init->cast<Const>();
- uint32_t dataSize = dataEndConst->value.geti32() - globalBase;
std::vector<Name> initializerFunctions;
if (wasm.getFunctionOrNull("__wasm_call_ctors")) {
@@ -160,8 +171,10 @@ int main(int argc, const char *argv[]) {
passRunner.run();
}
- generator.generateRuntimeFunctions();
- generator.generateMemoryGrowthFunction();
+ if (!isSideModule) {
+ generator.generateRuntimeFunctions();
+ generator.generateMemoryGrowthFunction();
+ }
generator.generateDynCallThunks();
generator.generateJSCallThunks(numReservedFunctionPointers);
std::string metadata = generator.generateEmscriptenMetadata(dataSize, initializerFunctions, numReservedFunctionPointers);
diff --git a/src/wasm-emscripten.h b/src/wasm-emscripten.h
index 78d24b13f..aa42b86b2 100644
--- a/src/wasm-emscripten.h
+++ b/src/wasm-emscripten.h
@@ -50,9 +50,6 @@ public:
Address staticBump, std::vector<Name> const& initializerFunctions,
unsigned numReservedFunctionPointers);
- // Replace placeholder emscripten_asm_const functions with *_signature versions.
- void fixEmAsmConsts();
-
void fixInvokeFunctionNames();
void separateDataSegments(Output* outfile);
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index c61e40b1d..14104c1eb 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -44,6 +44,8 @@ void addExportedFunction(Module& wasm, Function* function) {
Global* EmscriptenGlueGenerator::getStackPointerGlobal() {
// Assumption: first global is __stack_pointer
+ // TODO(sbc): Once mutable globals are a thing we shouldn't need this
+ // at all since we can simply export __stack_pointer.
return wasm.globals[0].get();
}
@@ -308,9 +310,14 @@ void EmscriptenGlueGenerator::generateJSCallThunks(
std::vector<Address> getSegmentOffsets(Module& wasm) {
std::vector<Address> segmentOffsets;
for (unsigned i = 0; i < wasm.memory.segments.size(); ++i) {
- Const* addrConst = wasm.memory.segments[i].offset->cast<Const>();
- auto address = addrConst->value.geti32();
- segmentOffsets.push_back(address);
+ if (auto* addrConst = wasm.memory.segments[i].offset->dynCast<Const>()) {
+ auto address = addrConst->value.geti32();
+ segmentOffsets.push_back(address);
+ } else {
+ // TODO(sbc): Wasm shared libraries have data segments with non-const
+ // offset.
+ segmentOffsets.push_back(0);
+ }
}
return segmentOffsets;
}
@@ -552,12 +559,6 @@ EmJsWalker fixEmJsFuncsAndReturnWalker(Module& wasm) {
return walker;
}
-void EmscriptenGlueGenerator::fixEmAsmConsts() {
- fixEmAsmConstsAndReturnWalker(wasm);
- fixEmJsFuncsAndReturnWalker(wasm);
-}
-
-
// Fixes function name hacks caused by LLVM exception & setjmp/longjmp
// handling pass for wasm.
// This does two things: