extend `reduce_funcs` to cover cross-scope substitutions (#2469)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 11 Nov 2017 07:30:17 +0000 (15:30 +0800)
committerGitHub <noreply@github.com>
Sat, 11 Nov 2017 07:30:17 +0000 (15:30 +0800)
fixes #2468

lib/compress.js
test/compress/reduce_vars.js

index 2b38ed4..fdf3a2b 100644 (file)
@@ -4256,10 +4256,11 @@ merge(Compressor.prototype, {
             var fixed = self.fixed_value();
             if (fixed instanceof AST_Defun) {
                 d.fixed = fixed = make_node(AST_Function, fixed, fixed);
-                if (!compressor.option("reduce_funcs")) d.single_use = false;
             }
             if (d.single_use && fixed instanceof AST_Function) {
-                if (d.escaped && d.scope !== self.scope || recursive_ref(compressor, d)) {
+                if (!compressor.option("reduce_funcs") && d.scope !== self.scope) {
+                    d.single_use = false;
+                } else if (d.escaped && d.scope !== self.scope || recursive_ref(compressor, d)) {
                     d.single_use = false;
                 } else if (d.scope !== self.scope || d.orig[0] instanceof AST_SymbolFunarg) {
                     d.single_use = fixed.is_constant_expression(self.scope);
index 76ed460..e718949 100644 (file)
@@ -4208,7 +4208,6 @@ issue_2449: {
 
 perf_1: {
     options = {
-        passes: 10,
         reduce_funcs: true,
         reduce_vars: true,
         toplevel: true,
@@ -4223,7 +4222,7 @@ perf_1: {
         }
         var sum = 0;
         for (var i = 0; i < 100; ++i) {
-            sum += indirect_foo(i, i+1, i*3);
+            sum += indirect_foo(i, i + 1, 3 * i);
         }
         console.log(sum);
     }
@@ -4243,7 +4242,6 @@ perf_1: {
 
 perf_2: {
     options = {
-        passes: 10,
         reduce_funcs: false,
         reduce_vars: true,
         toplevel: true,
@@ -4258,7 +4256,7 @@ perf_2: {
         }
         var sum = 0;
         for (var i = 0; i < 100; ++i) {
-            sum += indirect_foo(i, i+1, i*3);
+            sum += indirect_foo(i, i + 1, 3 * i);
         }
         console.log(sum);
     }
@@ -4276,3 +4274,206 @@ perf_2: {
     }
     expect_stdout: "348150"
 }
+
+perf_3: {
+    options = {
+        reduce_funcs: true,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        var foo = function(x, y, z) {
+            return x < y ? x * y + z : x * z - y;
+        }
+        var indirect_foo = function(x, y, z) {
+            return foo(x, y, z);
+        }
+        var sum = 0;
+        for (var i = 0; i < 100; ++i)
+            sum += indirect_foo(i, i + 1, 3 * i);
+        console.log(sum);
+    }
+    expect: {
+        var indirect_foo = function(x, y, z) {
+            return function(x, y, z) {
+                return x < y ? x * y + z : x * z - y;
+            }(x, y, z);
+        }
+        var sum = 0;
+        for (var i = 0; i < 100; ++i)
+            sum += indirect_foo(i, i + 1, 3 * i);
+        console.log(sum);
+    }
+    expect_stdout: "348150"
+}
+
+perf_4: {
+    options = {
+        reduce_funcs: false,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        var foo = function(x, y, z) {
+            return x < y ? x * y + z : x * z - y;
+        }
+        var indirect_foo = function(x, y, z) {
+            return foo(x, y, z);
+        }
+        var sum = 0;
+        for (var i = 0; i < 100; ++i)
+            sum += indirect_foo(i, i + 1, 3 * i);
+        console.log(sum);
+    }
+    expect: {
+        var foo = function(x, y, z) {
+            return x < y ? x * y + z : x * z - y;
+        }
+        var indirect_foo = function(x, y, z) {
+            return foo(x, y, z);
+        }
+        var sum = 0;
+        for (var i = 0; i < 100; ++i)
+            sum += indirect_foo(i, i + 1, 3 * i);
+        console.log(sum);
+    }
+    expect_stdout: "348150"
+}
+
+perf_5: {
+    options = {
+        passes: 10,
+        reduce_funcs: true,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        function indirect_foo(x, y, z) {
+            function foo(x, y, z) {
+                return x < y ? x * y + z : x * z - y;
+            }
+            return foo(x, y, z);
+        }
+        var sum = 0;
+        for (var i = 0; i < 100; ++i) {
+            sum += indirect_foo(i, i + 1, 3 * i);
+        }
+        console.log(sum);
+    }
+    expect: {
+        function indirect_foo(x, y, z) {
+            return function(x, y, z) {
+                return x < y ? x * y + z : x * z - y;
+            }(x, y, z);
+        }
+        var sum = 0;
+        for (var i = 0; i < 100; ++i)
+            sum += indirect_foo(i, i + 1, 3 * i);
+        console.log(sum);
+    }
+    expect_stdout: "348150"
+}
+
+perf_6: {
+    options = {
+        passes: 10,
+        reduce_funcs: false,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        function indirect_foo(x, y, z) {
+            function foo(x, y, z) {
+                return x < y ? x * y + z : x * z - y;
+            }
+            return foo(x, y, z);
+        }
+        var sum = 0;
+        for (var i = 0; i < 100; ++i) {
+            sum += indirect_foo(i, i + 1, 3 * i);
+        }
+        console.log(sum);
+    }
+    expect: {
+        function indirect_foo(x, y, z) {
+            return function(x, y, z) {
+                return x < y ? x * y + z : x * z - y;
+            }(x, y, z);
+        }
+        var sum = 0;
+        for (var i = 0; i < 100; ++i)
+            sum += indirect_foo(i, i + 1, 3 * i);
+        console.log(sum);
+    }
+    expect_stdout: "348150"
+}
+
+perf_7: {
+    options = {
+        reduce_funcs: true,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        var indirect_foo = function(x, y, z) {
+            var foo = function(x, y, z) {
+                return x < y ? x * y + z : x * z - y;
+            }
+            return foo(x, y, z);
+        }
+        var sum = 0;
+        for (var i = 0; i < 100; ++i)
+            sum += indirect_foo(i, i + 1, 3 * i);
+        console.log(sum);
+    }
+    expect: {
+        var indirect_foo = function(x, y, z) {
+            return function(x, y, z) {
+                return x < y ? x * y + z : x * z - y;
+            }(x, y, z);
+        }
+        var sum = 0;
+        for (var i = 0; i < 100; ++i)
+            sum += indirect_foo(i, i + 1, 3 * i);
+        console.log(sum);
+    }
+    expect_stdout: "348150"
+}
+
+perf_8: {
+    options = {
+        reduce_funcs: false,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        var indirect_foo = function(x, y, z) {
+            var foo = function(x, y, z) {
+                return x < y ? x * y + z : x * z - y;
+            }
+            return foo(x, y, z);
+        }
+        var sum = 0;
+        for (var i = 0; i < 100; ++i)
+            sum += indirect_foo(i, i + 1, 3 * i);
+        console.log(sum);
+    }
+    expect: {
+        var indirect_foo = function(x, y, z) {
+            return function(x, y, z) {
+                return x < y ? x * y + z : x * z - y;
+            }(x, y, z);
+        }
+        var sum = 0;
+        for (var i = 0; i < 100; ++i)
+            sum += indirect_foo(i, i + 1, 3 * i);
+        console.log(sum);
+    }
+    expect_stdout: "348150"
+}