summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2020-01-24 14:04:12 -0800
committerGitHub <noreply@github.com>2020-01-24 14:04:12 -0800
commita134dbba6686621924a75dc8645abe8ab2273f44 (patch)
tree1af0d8dc159393c9ab690a20d5c3aea46a6c562e /src
parent1a0530da9c0217e7118965aeb4ee1f59f68df73c (diff)
downloadbinaryen-a134dbba6686621924a75dc8645abe8ab2273f44.tar.gz
binaryen-a134dbba6686621924a75dc8645abe8ab2273f44.tar.bz2
binaryen-a134dbba6686621924a75dc8645abe8ab2273f44.zip
Reland "Fix renaming in FixInvokeFunctionNamesWalker (#2513)" (#2622)
This reverts commit 132daae1e9154782bb1afa5df80dfe7ea35f0369. This change is the same as before but the fix in #2619 should now make it safe.
Diffstat (limited to 'src')
-rw-r--r--src/wasm/wasm-emscripten.cpp41
1 files changed, 26 insertions, 15 deletions
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index 1fd87f2ea..8357983b2 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -994,11 +994,11 @@ struct FixInvokeFunctionNamesWalker
: public PostWalker<FixInvokeFunctionNamesWalker> {
Module& wasm;
std::map<Name, Name> importRenames;
- std::vector<Name> toRemove;
- std::set<Name> newImports;
+ std::map<Name, Name> functionReplace;
std::set<Signature> invokeSigs;
+ ImportInfo imports;
- FixInvokeFunctionNamesWalker(Module& _wasm) : wasm(_wasm) {}
+ FixInvokeFunctionNamesWalker(Module& _wasm) : wasm(_wasm), imports(wasm) {}
// Converts invoke wrapper names generated by LLVM backend to real invoke
// wrapper names that are expected by JavaScript glue code.
@@ -1053,27 +1053,38 @@ struct FixInvokeFunctionNamesWalker
return;
}
- assert(importRenames.count(curr->name) == 0);
- BYN_TRACE("renaming: " << curr->name << " -> " << newname << "\n");
- importRenames[curr->name] = newname;
- // Either rename or remove the existing import
- if (wasm.getFunctionOrNull(newname) || !newImports.insert(newname).second) {
- toRemove.push_back(curr->name);
+ BYN_TRACE("renaming import: " << curr->module << "." << curr->base << " ("
+ << curr->name << ") -> " << newname << "\n");
+ assert(importRenames.count(curr->base) == 0);
+ importRenames[curr->base] = newname;
+ // Either rename the import, or replace it with an existing one
+ Function* existingFunc = imports.getImportedFunction(curr->module, newname);
+ if (existingFunc) {
+ BYN_TRACE("replacing with an existing import: " << existingFunc->name
+ << "\n");
+ functionReplace[curr->name] = existingFunc->name;
} else {
+ BYN_TRACE("renaming the import in place\n");
curr->base = newname;
- curr->name = newname;
}
}
void visitModule(Module* curr) {
- for (auto importName : toRemove) {
- wasm.removeFunction(importName);
+ // For each replaced function first remove the function itself then
+ // rename all uses to the point to the new function.
+ for (auto& pair : functionReplace) {
+ BYN_TRACE("removeFunction " << pair.first << "\n");
+ wasm.removeFunction(pair.first);
}
- ModuleUtils::renameFunctions(wasm, importRenames);
- ImportInfo imports(wasm);
+ // Rename all uses of the removed functions
+ ModuleUtils::renameFunctions(wasm, functionReplace);
+
+ // For imports that for renamed, update any associated GOT.func imports.
for (auto& pair : importRenames) {
- // Update any associated GOT.func import.
+ BYN_TRACE("looking for: GOT.func." << pair.first << "\n");
if (auto g = imports.getImportedGlobal("GOT.func", pair.first)) {
+ BYN_TRACE("renaming corresponding GOT entry: " << g->base << " -> "
+ << pair.second << "\n");
g->base = pair.second;
}
}