[Pkg-javascript-commits] [uglifyjs] 388/491: drop `unused` assignment based on `reduce_vars` (#2709)

Jonas Smedegaard dr at jones.dk
Wed Feb 14 19:51:55 UTC 2018


This is an automated email from the git hooks/post-receive script.

js pushed a commit to annotated tag debian/3.3.10-1
in repository uglifyjs.

commit cfe3a98ce50a1eb844654da57b4ef47a750feda5
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Thu Jan 4 01:03:33 2018 +0800

    drop `unused` assignment based on `reduce_vars` (#2709)
---
 lib/compress.js              |  45 +++++++++++-----
 lib/scope.js                 |   5 +-
 test/compress/drop-unused.js | 122 +++++++++++++++++++++++++++++++++++++++++++
 test/compress/reduce_vars.js |  41 ++++++++++++++-
 test/compress/typeof.js      |  40 ++++++++++++++
 5 files changed, 238 insertions(+), 15 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index 1e096ad..fd59fb3 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -311,6 +311,7 @@ merge(Compressor.prototype, {
         def(AST_Node, noop);
 
         function reset_def(compressor, def) {
+            def.assignments = 0;
             def.direct_access = false;
             def.escaped = false;
             if (def.scope.uses_eval || def.scope.uses_with) {
@@ -364,6 +365,7 @@ merge(Compressor.prototype, {
         }
 
         function safe_to_assign(tw, def, value) {
+            if (def.fixed === undefined) return true;
             if (def.fixed === null && def.safe_ids) {
                 def.safe_ids[def.id] = false;
                 delete def.safe_ids;
@@ -372,7 +374,7 @@ merge(Compressor.prototype, {
             if (!HOP(tw.safe_ids, def.id)) return false;
             if (!safe_to_read(tw, def)) return false;
             if (def.fixed === false) return false;
-            if (def.fixed != null && (!value || def.references.length > 0)) return false;
+            if (def.fixed != null && (!value || def.references.length > def.assignments)) return false;
             return all(def.orig, function(sym) {
                 return !(sym instanceof AST_SymbolDefun
                     || sym instanceof AST_SymbolLambda);
@@ -477,6 +479,7 @@ merge(Compressor.prototype, {
             var d = node.left.definition();
             if (safe_to_assign(tw, d, node.right)) {
                 d.references.push(node.left);
+                d.assignments++;
                 d.fixed = function() {
                     return node.right;
                 };
@@ -662,7 +665,7 @@ merge(Compressor.prototype, {
         def(AST_VarDef, function(tw, descend) {
             var node = this;
             var d = node.name.definition();
-            if (d.fixed === undefined || safe_to_assign(tw, d, node.value)) {
+            if (safe_to_assign(tw, d, node.value)) {
                 if (node.value) {
                     d.fixed = function() {
                         return node.value;
@@ -2717,6 +2720,7 @@ merge(Compressor.prototype, {
         };
         var in_use = [];
         var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
+        var fixed_ids = Object.create(null);
         if (self instanceof AST_Toplevel && compressor.top_retain) {
             self.variables.each(function(def) {
                 if (compressor.top_retain(def) && !(def.id in in_use_ids)) {
@@ -2763,6 +2767,9 @@ merge(Compressor.prototype, {
                         if (def.value.has_side_effects(compressor)) {
                             def.value.walk(tw);
                         }
+                        if (def.name.fixed_value() === def.value) {
+                            fixed_ids[node_def.id] = true;
+                        }
                     }
                 });
                 return true;
@@ -2786,12 +2793,16 @@ merge(Compressor.prototype, {
                 var parent = tt.parent();
                 if (drop_vars) {
                     var sym = assign_as_unused(node);
-                    if (sym instanceof AST_SymbolRef
-                        && !(sym.definition().id in in_use_ids)) {
+                    if (sym instanceof AST_SymbolRef) {
+                        var def = sym.definition();
+                        var in_use = def.id in in_use_ids;
                         if (node instanceof AST_Assign) {
-                            return maintain_this_binding(parent, node, node.right.transform(tt));
-                        }
-                        return make_node(AST_Number, node, {
+                            if (!in_use
+                                || def.id in fixed_ids
+                                    && node.left.fixed_value() !== node.right) {
+                                return maintain_this_binding(parent, node, node.right.transform(tt));
+                            }
+                        } else if (!in_use) return make_node(AST_Number, node, {
                             value: 0
                         });
                     }
@@ -2851,13 +2862,16 @@ merge(Compressor.prototype, {
                                             operator: "=",
                                             left: make_node(AST_SymbolRef, def.name, def.name),
                                             right: def.value
-                                        }));
+                                        }).transform(tt));
                                     }
                                     remove(var_defs, def);
                                     sym.eliminated++;
                                     return;
                                 }
                             }
+                            if (def.value && sym.id in fixed_ids && def.name.fixed_value() !== def.value) {
+                                def.value = def.value.drop_side_effect_free(compressor);
+                            }
                             if (def.value) {
                                 if (side_effects.length > 0) {
                                     if (tail.length > 0) {
@@ -2962,14 +2976,19 @@ merge(Compressor.prototype, {
         self.transform(tt);
 
         function scan_ref_scoped(node, descend) {
-            var sym;
-            if ((sym = assign_as_unused(node)) instanceof AST_SymbolRef
-                && self.variables.get(sym.name) === sym.definition()) {
-                if (node instanceof AST_Assign) node.right.walk(tw);
+            var node_def, sym = assign_as_unused(node);
+            if (sym instanceof AST_SymbolRef
+                && self.variables.get(sym.name) === (node_def = sym.definition())) {
+                if (node instanceof AST_Assign) {
+                    node.right.walk(tw);
+                    if (node.left.fixed_value() === node.right) {
+                        fixed_ids[node_def.id] = true;
+                    }
+                }
                 return true;
             }
             if (node instanceof AST_SymbolRef) {
-                var node_def = node.definition();
+                node_def = node.definition();
                 if (!(node_def.id in in_use_ids)) {
                     in_use_ids[node_def.id] = true;
                     in_use.push(node_def);
diff --git a/lib/scope.js b/lib/scope.js
index 79b2475..de92fc9 100644
--- a/lib/scope.js
+++ b/lib/scope.js
@@ -151,7 +151,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
             node.references = [];
         }
         if (node instanceof AST_SymbolLambda) {
-            defun.def_function(node);
+            defun.def_function(node, defun);
         }
         else if (node instanceof AST_SymbolDefun) {
             // Careful here, the scope where this should be defined is
@@ -318,6 +318,9 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol, init){
     var def = this.variables.get(symbol.name);
     if (def) {
         def.orig.push(symbol);
+        if (def.init && (def.scope !== symbol.scope || def.init instanceof AST_Function)) {
+            def.init = init;
+        }
     } else {
         def = new SymbolDef(this, symbol, init);
         this.variables.set(symbol.name, def);
diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js
index 21d4b7c..5ad489b 100644
--- a/test/compress/drop-unused.js
+++ b/test/compress/drop-unused.js
@@ -1522,3 +1522,125 @@ issue_2665: {
     }
     expect_stdout: "-1"
 }
+
+double_assign_1: {
+    options = {
+        passes: 2,
+        reduce_vars: true,
+        side_effects: true,
+        unused: true,
+    }
+    input: {
+        function f1() {
+            var a = {};
+            var a = [];
+            return a;
+        }
+        function f2() {
+            var a = {};
+            a = [];
+            return a;
+        }
+        function f3() {
+            a = {};
+            var a = [];
+            return a;
+        }
+        function f4(a) {
+            a = {};
+            a = [];
+            return a;
+        }
+        function f5(a) {
+            var a = {};
+            a = [];
+            return a;
+        }
+        function f6(a) {
+            a = {};
+            var a = [];
+            return a;
+        }
+        console.log(f1(), f2(), f3(), f4(), f5(), f6());
+    }
+    expect: {
+        function f1() {
+            return [];
+        }
+        function f2() {
+            var a;
+            a = [];
+            return a;
+        }
+        function f3() {
+            return [];
+        }
+        function f4(a) {
+            a = [];
+            return a;
+        }
+        function f5(a) {
+            a = [];
+            return a;
+        }
+        function f6(a) {
+            a = [];
+            return a;
+        }
+        console.log(f1(), f2(), f3(), f4(), f5(), f6());
+    }
+    expect_stdout: true
+}
+
+double_assign_2: {
+    options = {
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        for (var i = 0; i < 2; i++)
+            a = void 0, a = {}, console.log(a);
+        var a;
+    }
+    expect: {
+        for (var i = 0; i < 2; i++)
+            void 0, a = {}, console.log(a);
+        var a;
+    }
+}
+
+double_assign_3: {
+    options = {
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        for (var i = 0; i < 2; i++)
+            a = void 0, a = { a: a }, console.log(a);
+        var a;
+    }
+    expect: {
+        for (var i = 0; i < 2; i++)
+            a = void 0, a = { a: a }, console.log(a);
+        var a;
+    }
+}
+
+cascade_drop_assign: {
+    options = {
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        var a, b = a = "PASS";
+        console.log(b);
+    }
+    expect: {
+        var b = "PASS";
+        console.log(b);
+    }
+    expect_stdout: "PASS"
+}
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index e370e5b..3d993b9 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -299,7 +299,7 @@ unsafe_evaluate_modified: {
         console.log(function(){ var o={p:1}; o.p++; console.log(o.p); return o.p; }());
         console.log(function(){ var o={p:2}; --o.p; console.log(o.p); return o.p; }());
         console.log(function(){ var o={p:3}; o.p += ""; console.log(o.p); return o.p; }());
-        console.log(function(){ var o={p:4}; o = {}; console.log(o.p); return o.p; }());
+        console.log(function(){ var o; o = {}; console.log(o.p); return o.p; }());
         console.log(function(){ var o={p:5}; o.p = -9; console.log(o.p); return o.p; }());
         function inc() { this.p++; }
         console.log(function(){ var o={p:6}; inc.call(o); console.log(o.p); return o.p; }());
@@ -5237,3 +5237,42 @@ defun_catch_6: {
     }
     expect_stdout: "42"
 }
+
+duplicate_lambda_defun_name_1: {
+    options = {
+        reduce_vars: true,
+    }
+    input: {
+        console.log(function f(a) {
+            function f() {}
+            return f.length;
+        }());
+    }
+    expect: {
+        console.log(function f(a) {
+            function f() {}
+            return f.length;
+        }());
+    }
+    expect_stdout: "0"
+}
+
+duplicate_lambda_defun_name_2: {
+    options = {
+        passes: 2,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        console.log(function f(a) {
+            function f() {}
+            return f.length;
+        }());
+    }
+    expect: {
+        console.log(function(a) {
+            return function() {}.length;
+        }());
+    }
+    expect_stdout: "0"
+}
diff --git a/test/compress/typeof.js b/test/compress/typeof.js
index 9eaf05e..72e77be 100644
--- a/test/compress/typeof.js
+++ b/test/compress/typeof.js
@@ -138,3 +138,43 @@ typeof_defun_2: {
         "2",
     ]
 }
+
+duplicate_defun_arg_name: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        typeofs: true,
+    }
+    input: {
+        function long_name(long_name) {
+            return typeof long_name;
+        }
+        console.log(typeof long_name, long_name());
+    }
+    expect: {
+        function long_name(long_name) {
+            return typeof long_name;
+        }
+        console.log(typeof long_name, long_name());
+    }
+    expect_stdout: "function undefined"
+}
+
+duplicate_lambda_arg_name: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        typeofs: true,
+    }
+    input: {
+        console.log(function long_name(long_name) {
+            return typeof long_name;
+        }());
+    }
+    expect: {
+        console.log(function long_name(long_name) {
+            return typeof long_name;
+        }());
+    }
+    expect_stdout: "undefined"
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git



More information about the Pkg-javascript-commits mailing list