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.cpp38
1 files changed, 23 insertions, 15 deletions
diff --git a/src/wasm-linker.cpp b/src/wasm-linker.cpp
index f4f516073..a4bd97e2f 100644
--- a/src/wasm-linker.cpp
+++ b/src/wasm-linker.cpp
@@ -217,23 +217,31 @@ bool Linker::linkObject(S2WasmBuilder& builder) {
}
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;
+ bool selected;
+ do {
+ selected = false;
+ 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;
+ selected = true;
+ break;
+ }
}
}
- }
+ // If we selected an archive member, it may depend on another archive member
+ // so continue to make passes over the members until no more are added.
+ } while (selected);
return true;
}