summaryrefslogtreecommitdiff
path: root/src/wasm-linker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm-linker.cpp')
-rw-r--r--src/wasm-linker.cpp26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/wasm-linker.cpp b/src/wasm-linker.cpp
index a854f0cd0..f4f516073 100644
--- a/src/wasm-linker.cpp
+++ b/src/wasm-linker.cpp
@@ -55,6 +55,7 @@ void Linker::layout() {
// Convert calls to undefined functions to call_imports
for (const auto& f : out.undefinedFunctionCalls) {
Name target = f.first;
+ if (!out.symbolInfo.undefinedFunctions.count(target)) continue;
// Create an import for the target if necessary.
if (!out.wasm.checkImport(target)) {
auto import = new Import;
@@ -210,12 +211,31 @@ bool Linker::linkObject(S2WasmBuilder& builder) {
return false;
}
}
- out.symbolInfo.merge(std::move(*newSymbols));
- builder.build(&out, &out.symbolInfo);
- delete newSymbols;
+ out.symbolInfo.merge(*newSymbols);
+ builder.build(&out);
return true;
}
+bool Linker::linkArchive(Archive& archive) {
+ for (auto child = archive.child_begin(), end = archive.child_end();
+ child != end; ++child) {
+ Archive::SubBuffer memberBuf = child->getBuffer();
+ // S2WasmBuilder expects its input to be NUL-terminated. Archive members are
+ // not NUL-terminated. So we have to copy the contents out before parsing.
+ std::vector<char> memberString(memberBuf.len + 1);
+ memcpy(memberString.data(), memberBuf.data, memberBuf.len);
+ memberString[memberBuf.len] = '\0';
+ S2WasmBuilder memberBuilder(memberString.data(), false);
+ auto* memberSymbols = memberBuilder.getSymbolInfo();
+ for (const Name& symbol : memberSymbols->implementedFunctions) {
+ if (out.symbolInfo.undefinedFunctions.count(symbol)) {
+ if (!linkObject(memberBuilder)) return false;
+ break;
+ }
+ }
+ }
+ return true;
+}
void Linker::emscriptenGlue(std::ostream& o) {
if (debug) {