Skip to content

Commit ec16a4d

Browse files
authored
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).
1 parent f1666bd commit ec16a4d

File tree

3 files changed

+36
-25
lines changed

3 files changed

+36
-25
lines changed

src/tools/wasm-emscripten-finalize.cpp

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,30 @@ int main(int argc, const char *argv[]) {
130130
WasmPrinter::printModule(&wasm, std::cerr);
131131
}
132132

133-
Export* dataEndExport = wasm.getExport("__data_end");
134-
if (dataEndExport == nullptr) {
135-
Fatal() << "__data_end export not found";
133+
bool isSideModule = false;
134+
for (const UserSection& section : wasm.userSections) {
135+
if (section.name == BinaryConsts::UserSections::Dylink) {
136+
isSideModule = true;
137+
}
136138
}
137-
Global* dataEnd = wasm.getGlobal(dataEndExport->value);
138-
if (dataEnd == nullptr) {
139-
Fatal() << "__data_end global not found";
140-
}
141-
if (dataEnd->type != Type::i32) {
142-
Fatal() << "__data_end global has wrong type";
139+
140+
uint32_t dataSize = 0;
141+
142+
if (!isSideModule) {
143+
Export* dataEndExport = wasm.getExport("__data_end");
144+
if (dataEndExport == nullptr) {
145+
Fatal() << "__data_end export not found";
146+
}
147+
Global* dataEnd = wasm.getGlobal(dataEndExport->value);
148+
if (dataEnd == nullptr) {
149+
Fatal() << "__data_end global not found";
150+
}
151+
if (dataEnd->type != Type::i32) {
152+
Fatal() << "__data_end global has wrong type";
153+
}
154+
Const* dataEndConst = dataEnd->init->cast<Const>();
155+
dataSize = dataEndConst->value.geti32() - globalBase;
143156
}
144-
Const* dataEndConst = dataEnd->init->cast<Const>();
145-
uint32_t dataSize = dataEndConst->value.geti32() - globalBase;
146157

147158
std::vector<Name> initializerFunctions;
148159
if (wasm.getFunctionOrNull("__wasm_call_ctors")) {
@@ -160,8 +171,10 @@ int main(int argc, const char *argv[]) {
160171
passRunner.run();
161172
}
162173

163-
generator.generateRuntimeFunctions();
164-
generator.generateMemoryGrowthFunction();
174+
if (!isSideModule) {
175+
generator.generateRuntimeFunctions();
176+
generator.generateMemoryGrowthFunction();
177+
}
165178
generator.generateDynCallThunks();
166179
generator.generateJSCallThunks(numReservedFunctionPointers);
167180
std::string metadata = generator.generateEmscriptenMetadata(dataSize, initializerFunctions, numReservedFunctionPointers);

src/wasm-emscripten.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ class EmscriptenGlueGenerator {
5050
Address staticBump, std::vector<Name> const& initializerFunctions,
5151
unsigned numReservedFunctionPointers);
5252

53-
// Replace placeholder emscripten_asm_const functions with *_signature versions.
54-
void fixEmAsmConsts();
55-
5653
void fixInvokeFunctionNames();
5754

5855
void separateDataSegments(Output* outfile);

src/wasm/wasm-emscripten.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ void addExportedFunction(Module& wasm, Function* function) {
4444

4545
Global* EmscriptenGlueGenerator::getStackPointerGlobal() {
4646
// Assumption: first global is __stack_pointer
47+
// TODO(sbc): Once mutable globals are a thing we shouldn't need this
48+
// at all since we can simply export __stack_pointer.
4749
return wasm.globals[0].get();
4850
}
4951

@@ -308,9 +310,14 @@ void EmscriptenGlueGenerator::generateJSCallThunks(
308310
std::vector<Address> getSegmentOffsets(Module& wasm) {
309311
std::vector<Address> segmentOffsets;
310312
for (unsigned i = 0; i < wasm.memory.segments.size(); ++i) {
311-
Const* addrConst = wasm.memory.segments[i].offset->cast<Const>();
312-
auto address = addrConst->value.geti32();
313-
segmentOffsets.push_back(address);
313+
if (auto* addrConst = wasm.memory.segments[i].offset->dynCast<Const>()) {
314+
auto address = addrConst->value.geti32();
315+
segmentOffsets.push_back(address);
316+
} else {
317+
// TODO(sbc): Wasm shared libraries have data segments with non-const
318+
// offset.
319+
segmentOffsets.push_back(0);
320+
}
314321
}
315322
return segmentOffsets;
316323
}
@@ -552,12 +559,6 @@ EmJsWalker fixEmJsFuncsAndReturnWalker(Module& wasm) {
552559
return walker;
553560
}
554561

555-
void EmscriptenGlueGenerator::fixEmAsmConsts() {
556-
fixEmAsmConstsAndReturnWalker(wasm);
557-
fixEmJsFuncsAndReturnWalker(wasm);
558-
}
559-
560-
561562
// Fixes function name hacks caused by LLVM exception & setjmp/longjmp
562563
// handling pass for wasm.
563564
// This does two things:

0 commit comments

Comments
 (0)