diff options
-rw-r--r-- | src/passes/LegalizeJSInterface.cpp | 61 | ||||
-rw-r--r-- | test/lld/duplicate_imports.wat.out | 3 | ||||
-rw-r--r-- | test/passes/legalize-js-interface-minimally.txt | 3 | ||||
-rw-r--r-- | test/passes/legalize-js-interface_all-features.txt | 8 | ||||
-rw-r--r-- | test/passes/legalize-js-interface_all-features.wast | 3 |
5 files changed, 26 insertions, 52 deletions
diff --git a/src/passes/LegalizeJSInterface.cpp b/src/passes/LegalizeJSInterface.cpp index a53481d65..e840e375b 100644 --- a/src/passes/LegalizeJSInterface.cpp +++ b/src/passes/LegalizeJSInterface.cpp @@ -107,51 +107,16 @@ 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; - - // Fill in unordered_map, as we operate on it in parallel. - for (auto& func : module->functions) { - usedInRefFunc[func->name]; - } - - 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) {} - - void visitRefFunc(RefFunc* curr) { usedInRefFunc[curr->func] = true; } - }; - - RefFuncScanner(*module, usedInRefFunc).run(runner, module); - for (auto& pair : illegalImportsToLegal) { - 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>> { + // legal. the same must be done with ref.funcs. + struct Fixer : public WalkerPass<PostWalker<Fixer>> { bool isFunctionParallel() override { return true; } - Pass* create() override { - return new FixImports(illegalImportsToLegal); - } + Pass* create() override { return new Fixer(illegalImportsToLegal); } std::map<Name, Name>* illegalImportsToLegal; - FixImports(std::map<Name, Name>* illegalImportsToLegal) + Fixer(std::map<Name, Name>* illegalImportsToLegal) : illegalImportsToLegal(illegalImportsToLegal) {} void visitCall(Call* curr) { @@ -160,19 +125,25 @@ struct LegalizeJSInterface : public Pass { return; } - if (iter->second == getFunction()->name) { - // inside the stub function itself, is the one safe place to do the - // call - return; - } replaceCurrent( Builder(*getModule()) .makeCall( iter->second, curr->operands, curr->type, curr->isReturn)); } + + void visitRefFunc(RefFunc* curr) { + auto iter = illegalImportsToLegal->find(curr->func); + if (iter == illegalImportsToLegal->end()) { + return; + } + + curr->func = iter->second; + } }; - FixImports(&illegalImportsToLegal).run(runner, module); + Fixer fixer(&illegalImportsToLegal); + fixer.run(runner, module); + fixer.walkModuleCode(module); } } diff --git a/test/lld/duplicate_imports.wat.out b/test/lld/duplicate_imports.wat.out index f6e1b1223..5a5fa94e3 100644 --- a/test/lld/duplicate_imports.wat.out +++ b/test/lld/duplicate_imports.wat.out @@ -1,14 +1,15 @@ (module + (type $i64_=>_i32 (func (param i64) (result i32))) (type $i32_f32_f64_=>_f32 (func (param i32 f32 f64) (result f32))) (type $i32_f64_f64_=>_f32 (func (param i32 f64 f64) (result f32))) (type $2 (func)) (type $1 (func (result i32))) (type $0 (func (param i32) (result i32))) - (type $i64_=>_i32 (func (param i64) (result i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $f32_f64_=>_f32 (func (param f32 f64) (result f32))) (type $f64_f64_=>_f32 (func (param f64 f64) (result f32))) (import "env" "puts" (func $puts1 (param i32) (result i32))) + (import "env" "puts" (func $puts2 (param i64) (result i32))) (import "env" "invoke_ffd" (func $invoke_ffd (param i32 f32 f64) (result f32))) (import "env" "invoke_ffd" (func $invoke_ffd2 (param i32 f64 f64) (result f32))) (import "env" "puts" (func $legalimport$puts2 (param i32 i32) (result i32))) diff --git a/test/passes/legalize-js-interface-minimally.txt b/test/passes/legalize-js-interface-minimally.txt index f39a2ce84..18fb60c1f 100644 --- a/test/passes/legalize-js-interface-minimally.txt +++ b/test/passes/legalize-js-interface-minimally.txt @@ -1,10 +1,11 @@ (module (type $none_=>_i64 (func (result i64))) - (type $i32_=>_none (func (param i32))) (type $i64_=>_none (func (param i64))) + (type $i32_=>_none (func (param i32))) (type $i32_i32_=>_none (func (param i32 i32))) (type $none_=>_i32 (func (result i32))) (import "env" "imported" (func $imported (result i64))) + (import "env" "invoke_vj" (func $invoke_vj (param i64))) (import "env" "setTempRet0" (func $setTempRet0 (param i32))) (import "env" "invoke_vj" (func $legalimport$invoke_vj (param i32 i32))) (export "func" (func $func)) diff --git a/test/passes/legalize-js-interface_all-features.txt b/test/passes/legalize-js-interface_all-features.txt index d05d1bc30..05cc43e9b 100644 --- a/test/passes/legalize-js-interface_all-features.txt +++ b/test/passes/legalize-js-interface_all-features.txt @@ -2,16 +2,18 @@ (type $none_=>_i32 (func (result i32))) (type $none_=>_i64 (func (result i64))) (type $i32_i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32 i32))) + (type $i32_i64_i64_=>_none (func (param i32 i64 i64))) (type $none_=>_none (func)) (type $i32_=>_none (func (param i32))) - (type $i32_i64_i64_=>_none (func (param i32 i64 i64))) + (import "env" "imported" (func $imported (result i64))) + (import "env" "other" (func $other (param i32 i64 i64))) (import "env" "ref-func-arg" (func $ref-func-arg (result i64))) (import "env" "setTempRet0" (func $setTempRet0 (param i32))) (import "env" "getTempRet0" (func $getTempRet0 (result i32))) (import "env" "imported" (func $legalimport$imported (result i32))) (import "env" "other" (func $legalimport$other (param i32 i32 i32 i32 i32))) (import "env" "ref-func-arg" (func $legalimport$ref-func-arg (result i32))) - (elem declare func $ref-func-arg) + (elem declare func $legalfunc$ref-func-arg) (export "func" (func $legalstub$func)) (export "ref-func-test" (func $ref-func-test)) (export "imported" (func $legalstub$imported)) @@ -33,7 +35,7 @@ (call $legalfunc$ref-func-arg) ) (drop - (ref.func $ref-func-arg) + (ref.func $legalfunc$ref-func-arg) ) ) (func $legalstub$func (result i32) diff --git a/test/passes/legalize-js-interface_all-features.wast b/test/passes/legalize-js-interface_all-features.wast index 4697a8f18..7f4352f27 100644 --- a/test/passes/legalize-js-interface_all-features.wast +++ b/test/passes/legalize-js-interface_all-features.wast @@ -17,8 +17,7 @@ (unreachable) ) - ;; If an import is used in ref.func, even if it is legalized to another - ;; import, the original import should not be removed. + ;; ref.func must also be updated. (func $ref-func-test (drop (call $ref-func-arg) |