summaryrefslogtreecommitdiff
path: root/src/passes/LegalizeJSInterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/LegalizeJSInterface.cpp')
-rw-r--r--src/passes/LegalizeJSInterface.cpp33
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; }