diff options
-rw-r--r-- | src/passes/Inlining.cpp | 8 | ||||
-rw-r--r-- | test/passes/inlining_all-features.txt | 12 | ||||
-rw-r--r-- | test/passes/inlining_all-features.wast | 11 |
3 files changed, 30 insertions, 1 deletions
diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index d7f132879..43addff8b 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -326,7 +326,6 @@ struct Inlining : public Pass { PassRunner runner(module); FunctionInfoScanner(&infos).run(&runner, module); // fill in global uses - // anything exported or used in a table should not be inlined for (auto& ex : module->exports) { if (ex->kind == ExternalKind::Function) { infos[ex->value].usedGlobally = true; @@ -337,6 +336,13 @@ struct Inlining : public Pass { infos[name].usedGlobally = true; } } + for (auto& global : module->globals) { + if (!global->imported()) { + for (auto* ref : FindAll<RefFunc>(global->init).list) { + infos[ref->func].usedGlobally = true; + } + } + } } bool iteration(PassRunner* runner, Module* module) { diff --git a/test/passes/inlining_all-features.txt b/test/passes/inlining_all-features.txt index b2f483d3d..2141d3d34 100644 --- a/test/passes/inlining_all-features.txt +++ b/test/passes/inlining_all-features.txt @@ -47,3 +47,15 @@ ) ) ) +(module + (type $none_=>_i32 (func (result i32))) + (global $global$0 (mut funcref) (ref.func $0)) + (func $0 (result i32) + (i32.const 1337) + ) + (func $1 (result i32) + (block $__inlined_func$0 (result i32) + (i32.const 1337) + ) + ) +) diff --git a/test/passes/inlining_all-features.wast b/test/passes/inlining_all-features.wast index 47ac3ddb9..f86ad8926 100644 --- a/test/passes/inlining_all-features.wast +++ b/test/passes/inlining_all-features.wast @@ -36,3 +36,14 @@ ) ) ) +(module + ;; a function reference in a global's init should be noticed, and prevent us + ;; from removing an inlined function + (global $global$0 (mut funcref) (ref.func $0)) + (func $0 (result i32) + (i32.const 1337) + ) + (func $1 (result i32) + (call $0) + ) +) |