[Pkg-javascript-commits] [uglifyjs] 11/491: support safe reassignments in `reduce_vars` (#1823)

Jonas Smedegaard dr at jones.dk
Wed Feb 14 19:51:17 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 5d9f1da3abc58bce95dd240bd586bedb4eb04771
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Tue Apr 18 13:38:42 2017 +0800

    support safe reassignments in `reduce_vars` (#1823)
    
    `var a=1;a=2;x(a)` => `x(2)`
    
    fix pre-existing issues
    - reference counting on assignment
    - walking of anonymous functions
    - chained assignment
---
 lib/compress.js                |  51 +++++++++++++++------
 test/compress/collapse_vars.js |  22 +++++++++
 test/compress/reduce_vars.js   | 102 ++++++++++++++++++++++++++++++++++-------
 3 files changed, 145 insertions(+), 30 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index 0dfe2a3..596b03f 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -267,7 +267,7 @@ merge(Compressor.prototype, {
                 if (node instanceof AST_SymbolRef) {
                     var d = node.definition();
                     d.references.push(node);
-                    if (d.fixed === undefined || !is_safe(d)
+                    if (d.fixed === undefined || !safe_to_read(d)
                         || is_modified(node, 0, is_immutable(node.fixed_value()))) {
                         d.fixed = false;
                     }
@@ -277,7 +277,7 @@ merge(Compressor.prototype, {
                 }
                 if (node instanceof AST_VarDef) {
                     var d = node.name.definition();
-                    if (d.fixed == null) {
+                    if (d.fixed === undefined || safe_to_assign(d, node.value)) {
                         if (node.value) {
                             d.fixed = function() {
                                 return node.value;
@@ -297,7 +297,8 @@ merge(Compressor.prototype, {
                     && node.operator == "="
                     && node.left instanceof AST_SymbolRef) {
                     var d = node.left.definition();
-                    if (HOP(safe_ids, d.id) && d.fixed == null) {
+                    if (safe_to_assign(d, node.right)) {
+                        d.references.push(node.left);
                         d.fixed = function() {
                             return node.right;
                         };
@@ -309,7 +310,7 @@ merge(Compressor.prototype, {
                 }
                 if (node instanceof AST_Defun) {
                     var d = node.name.definition();
-                    if (!toplevel && d.global || is_safe(d)) {
+                    if (!toplevel && d.global || safe_to_read(d)) {
                         d.fixed = false;
                     } else {
                         d.fixed = node;
@@ -321,13 +322,12 @@ merge(Compressor.prototype, {
                     safe_ids = save_ids;
                     return true;
                 }
-                var iife;
-                if (node instanceof AST_Function
-                    && (iife = tw.parent()) instanceof AST_Call
-                    && iife.expression === node) {
-                    if (node.name) {
-                        node.name.definition().fixed = node;
-                    } else {
+                if (node instanceof AST_Function) {
+                    push();
+                    var iife;
+                    if (!node.name
+                        && (iife = tw.parent()) instanceof AST_Call
+                        && iife.expression === node) {
                         // Virtually turn IIFE parameters into variable definitions:
                         //   (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})()
                         // So existing transformation rules can work on them.
@@ -339,6 +339,9 @@ merge(Compressor.prototype, {
                             mark(d, true);
                         });
                     }
+                    descend();
+                    pop();
+                    return true;
                 }
                 if (node instanceof AST_Binary
                     && (node.operator == "&&" || node.operator == "||")) {
@@ -385,11 +388,19 @@ merge(Compressor.prototype, {
                 }
                 if (node instanceof AST_For) {
                     if (node.init) node.init.walk(tw);
+                    if (node.condition) {
+                        push();
+                        node.condition.walk(tw);
+                        pop();
+                    }
                     push();
-                    if (node.condition) node.condition.walk(tw);
                     node.body.walk(tw);
-                    if (node.step) node.step.walk(tw);
                     pop();
+                    if (node.step) {
+                        push();
+                        node.step.walk(tw);
+                        pop();
+                    }
                     return true;
                 }
                 if (node instanceof AST_ForIn) {
@@ -426,7 +437,7 @@ merge(Compressor.prototype, {
             safe_ids[def.id] = safe;
         }
 
-        function is_safe(def) {
+        function safe_to_read(def) {
             if (safe_ids[def.id]) {
                 if (def.fixed == null) {
                     var orig = def.orig[0];
@@ -437,6 +448,18 @@ merge(Compressor.prototype, {
             }
         }
 
+        function safe_to_assign(def, value) {
+            if (!HOP(safe_ids, def.id)) return false;
+            if (!safe_to_read(def)) return false;
+            if (def.fixed === false) return false;
+            if (def.fixed != null && (!value || def.references.length > 0)) return false;
+            return !def.orig.some(function(sym) {
+                return sym instanceof AST_SymbolConst
+                    || sym instanceof AST_SymbolDefun
+                    || sym instanceof AST_SymbolLambda;
+            });
+        }
+
         function push() {
             safe_ids = Object.create(safe_ids);
         }
diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js
index 2264783..c01572d 100644
--- a/test/compress/collapse_vars.js
+++ b/test/compress/collapse_vars.js
@@ -1592,3 +1592,25 @@ var_side_effects_3: {
     }
     expect_stdout: true
 }
+
+reduce_vars_assign: {
+    options = {
+        collapse_vars: true,
+        reduce_vars: true,
+    }
+    input: {
+        !function() {
+            var a = 1;
+            a = [].length,
+            console.log(a);
+        }();
+    }
+    expect: {
+        !function() {
+            var a = 1;
+            a = [].length,
+            console.log(a);
+        }();
+    }
+    expect_stdout: "0"
+}
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index ad2c90b..c5f2690 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -66,7 +66,7 @@ modified: {
         conditionals  : true,
         evaluate      : true,
         reduce_vars   : true,
-        unused        : true
+        unused        : true,
     }
     input: {
         function f0() {
@@ -136,12 +136,11 @@ modified: {
         }
 
         function f2() {
-            var b = 2;
-            b = 3;
-            console.log(1 + b);
-            console.log(b + 3);
+            3;
             console.log(4);
-            console.log(1 + b + 3);
+            console.log(6);
+            console.log(4);
+            console.log(7);
         }
 
         function f3() {
@@ -375,12 +374,11 @@ passes: {
     }
     expect: {
         function f() {
-            var b = 2;
-            b = 3;
-            console.log(1 + b);
-            console.log(b + 3);
+            3;
             console.log(4);
-            console.log(1 + b + 3);
+            console.log(6);
+            console.log(4);
+            console.log(7);
         }
     }
 }
@@ -573,7 +571,7 @@ inner_var_label: {
     }
 }
 
-inner_var_for: {
+inner_var_for_1: {
     options = {
         evaluate: true,
         reduce_vars: true,
@@ -602,6 +600,29 @@ inner_var_for: {
     }
 }
 
+inner_var_for_2: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        !function() {
+            var a = 1;
+            for (var b = 1; --b;) var a = 2;
+            console.log(a);
+        }();
+    }
+    expect: {
+        !function() {
+            a = 1;
+            for (var b = 1; --b;) var a = 2;
+            console.log(a);
+        }();
+    }
+    expect_stdout: "1"
+}
+
 inner_var_for_in_1: {
     options = {
         evaluate: true,
@@ -1828,10 +1849,7 @@ redefine_farg_3: {
         console.log(function(a) {
             var a;
             return typeof a;
-        }([]), "number", function(a) {
-            var a = void 0;
-            return typeof a;
-        }([]));
+        }([]), "number", "undefined");
     }
     expect_stdout: "object number undefined"
 }
@@ -2115,6 +2133,27 @@ var_assign_5: {
     expect_stdout: "2 undefined"
 }
 
+var_assign_6: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        !function() {
+            var a = function(){}(a = 1);
+            console.log(a);
+        }();
+    }
+    expect: {
+        !function() {
+            var a = function(){}(a = 1);
+            console.log(a);
+        }();
+    }
+    expect_stdout: "undefined"
+}
+
 immutable: {
     options = {
         evaluate: true,
@@ -2263,3 +2302,34 @@ cond_assign: {
     }
     expect_stdout: "undefined"
 }
+
+iife_assign: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        !function() {
+            var a = 1, b = 0;
+            !function() {
+                b++;
+                return;
+                a = 2;
+            }();
+            console.log(a);
+        }();
+    }
+    expect: {
+        !function() {
+            var a = 1, b = 0;
+            !function() {
+                b++;
+                return;
+                a = 2;
+            }();
+            console.log(a);
+        }();
+    }
+    expect_stdout: "1"
+}

-- 
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