diff options
Diffstat (limited to 'src/wasm-linker.cpp')
-rw-r--r-- | src/wasm-linker.cpp | 26 |
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) { |