diff options
Diffstat (limited to 'src/passes/LegalizeJSInterface.cpp')
-rw-r--r-- | src/passes/LegalizeJSInterface.cpp | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/src/passes/LegalizeJSInterface.cpp b/src/passes/LegalizeJSInterface.cpp index 8c7bc4414..df6651b0d 100644 --- a/src/passes/LegalizeJSInterface.cpp +++ b/src/passes/LegalizeJSInterface.cpp @@ -107,14 +107,43 @@ struct LegalizeJSInterface : public Pass { } } } + if (!illegalImportsToLegal.empty()) { + // Gather functions used in 'ref.func'. They should not be removed. + std::unordered_map<Name, std::atomic<bool>> usedInRefFunc; + + struct RefFuncScanner : public WalkerPass<PostWalker<RefFuncScanner>> { + Module& wasm; + std::unordered_map<Name, std::atomic<bool>>& usedInRefFunc; + + bool isFunctionParallel() override { return true; } + + Pass* create() override { + return new RefFuncScanner(wasm, usedInRefFunc); + } + + RefFuncScanner( + Module& wasm, + std::unordered_map<Name, std::atomic<bool>>& usedInRefFunc) + : wasm(wasm), usedInRefFunc(usedInRefFunc) { + // Fill in unordered_map, as we operate on it in parallel + for (auto& func : wasm.functions) { + usedInRefFunc[func->name]; + } + } + + void visitRefFunc(RefFunc* curr) { usedInRefFunc[curr->func] = true; } + }; + + RefFuncScanner(*module, usedInRefFunc).run(runner, module); for (auto& pair : illegalImportsToLegal) { - module->removeFunction(pair.first); + if (!usedInRefFunc[pair.first]) { + module->removeFunction(pair.first); + } } // fix up imports: call_import of an illegal must be turned to a call of a // legal - struct FixImports : public WalkerPass<PostWalker<FixImports>> { bool isFunctionParallel() override { return true; } |