diff options
author | Sam Clegg <sbc@chromium.org> | 2020-01-24 14:04:12 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-24 14:04:12 -0800 |
commit | a134dbba6686621924a75dc8645abe8ab2273f44 (patch) | |
tree | 1af0d8dc159393c9ab690a20d5c3aea46a6c562e /src | |
parent | 1a0530da9c0217e7118965aeb4ee1f59f68df73c (diff) | |
download | binaryen-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.cpp | 41 |
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; } } |