[Pkg-javascript-commits] [uglifyjs] 205/228: implement delayed resolution for `reduce_vars` (#1788)

Jonas Smedegaard dr at jones.dk
Sat Apr 15 14:25:30 UTC 2017


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

js pushed a commit to branch master
in repository uglifyjs.

commit ff289b90a92739641dcb7fc7f6c8ecf8ee74d15f
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Wed Apr 5 21:06:42 2017 +0800

    implement delayed resolution for `reduce_vars` (#1788)
    
    Although it would be nice to enforce `AST_Node` cloning during transformation, that ship has sailed a long time ago.
    
    We now get the assigned value when resolving `AST_SymbolRef` instead of `reset_opt_flags()`, which has the added advantage of improved compressor efficiency.
    
    fixes #1787
---
 lib/compress.js             | 50 ++++++++++++++++++++++++++++-----------------
 test/compress/issue-1609.js |  7 +++----
 test/compress/issue-1787.js | 19 +++++++++++++++++
 3 files changed, 53 insertions(+), 23 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index 14083fe..ef7f044 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -273,7 +273,7 @@ merge(Compressor.prototype, {
                     var d = node.definition();
                     d.references.push(node);
                     if (d.fixed === undefined || !is_safe(d)
-                        || is_modified(node, 0, d.fixed instanceof AST_Lambda)) {
+                        || is_modified(node, 0, node.fixed_value() instanceof AST_Lambda)) {
                         d.fixed = false;
                     }
                 }
@@ -283,7 +283,9 @@ merge(Compressor.prototype, {
                 if (node instanceof AST_VarDef) {
                     var d = node.name.definition();
                     if (d.fixed == null) {
-                        d.fixed = node.value;
+                        d.fixed = node.value && function() {
+                            return node.value;
+                        };
                         mark_as_safe(d);
                     } else if (node.value) {
                         d.fixed = false;
@@ -314,7 +316,9 @@ merge(Compressor.prototype, {
                     // So existing transformation rules can work on them.
                     node.argnames.forEach(function(arg, i) {
                         var d = arg.definition();
-                        d.fixed = iife.args[i] || make_node(AST_Undefined, iife);
+                        d.fixed = function() {
+                            return iife.args[i] || make_node(AST_Undefined, iife);
+                        };
                         mark_as_safe(d);
                     });
                 }
@@ -409,6 +413,12 @@ merge(Compressor.prototype, {
         }
     });
 
+    AST_SymbolRef.DEFMETHOD("fixed_value", function() {
+        var fixed = this.definition().fixed;
+        if (!fixed || fixed instanceof AST_Node) return fixed;
+        return fixed();
+    });
+
     function find_variable(compressor, name) {
         var scope, i = 0;
         while (scope = compressor.parent(i++)) {
@@ -1487,15 +1497,15 @@ merge(Compressor.prototype, {
             if (this._evaluating) throw def;
             this._evaluating = true;
             try {
-                var d = this.definition();
-                if (compressor.option("reduce_vars") && d.fixed) {
+                var fixed = this.fixed_value();
+                if (compressor.option("reduce_vars") && fixed) {
                     if (compressor.option("unsafe")) {
-                        if (!HOP(d.fixed, "_evaluated")) {
-                            d.fixed._evaluated = ev(d.fixed, compressor);
+                        if (!HOP(fixed, "_evaluated")) {
+                            fixed._evaluated = ev(fixed, compressor);
                         }
-                        return d.fixed._evaluated;
+                        return fixed._evaluated;
                     }
-                    return ev(d.fixed, compressor);
+                    return ev(fixed, compressor);
                 }
             } finally {
                 this._evaluating = false;
@@ -2689,11 +2699,12 @@ merge(Compressor.prototype, {
         if (compressor.option("reduce_vars")
             && exp instanceof AST_SymbolRef) {
             var def = exp.definition();
-            if (def.fixed instanceof AST_Defun) {
-                def.fixed = make_node(AST_Function, def.fixed, def.fixed).clone(true);
+            var fixed = exp.fixed_value();
+            if (fixed instanceof AST_Defun) {
+                def.fixed = fixed = make_node(AST_Function, fixed, fixed).clone(true);
             }
-            if (def.fixed instanceof AST_Function) {
-                exp = def.fixed;
+            if (fixed instanceof AST_Function) {
+                exp = fixed;
                 if (compressor.option("unused")
                     && def.references.length == 1
                     && !(def.scope.uses_arguments
@@ -3080,7 +3091,7 @@ merge(Compressor.prototype, {
             && (e.operator == "*" || e.operator == "/" || e.operator == "%")) {
             self.expression = e.left;
             e.left = self;
-            return e.optimize(compressor);
+            return e;
         }
         // avoids infinite recursion of numerals
         if (self.operator != "-"
@@ -3511,12 +3522,13 @@ merge(Compressor.prototype, {
         }
         if (compressor.option("evaluate") && compressor.option("reduce_vars")) {
             var d = self.definition();
-            if (d.fixed) {
+            var fixed = self.fixed_value();
+            if (fixed) {
                 if (d.should_replace === undefined) {
-                    var init = d.fixed.evaluate(compressor);
-                    if (init !== d.fixed) {
-                        init = make_node_from_constant(init, d.fixed).optimize(compressor);
-                        init = best_of_expression(init, d.fixed);
+                    var init = fixed.evaluate(compressor);
+                    if (init !== fixed) {
+                        init = make_node_from_constant(init, fixed).optimize(compressor);
+                        init = best_of_expression(init, fixed);
                         var value = init.print_to_string().length;
                         var name = d.name.length;
                         var freq = d.references.length;
diff --git a/test/compress/issue-1609.js b/test/compress/issue-1609.js
index 577a3ee..da4b54a 100644
--- a/test/compress/issue-1609.js
+++ b/test/compress/issue-1609.js
@@ -45,11 +45,10 @@ chained_evaluation_2: {
     }
     expect: {
         (function() {
-            var a = "long piece of string";
             (function() {
-                var c;
-                c = f(a);
-                c.bar = a;
+                var c, b = "long piece of string";
+                c = f(b);
+                c.bar = b;
             })();
         })();
     }
diff --git a/test/compress/issue-1787.js b/test/compress/issue-1787.js
new file mode 100644
index 0000000..43d1f1b
--- /dev/null
+++ b/test/compress/issue-1787.js
@@ -0,0 +1,19 @@
+unary_prefix: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        console.log(function() {
+            var x = -(2 / 3);
+            return x;
+        }());
+    }
+    expect: {
+        console.log(function() {
+            return -2 / 3;
+        }());
+    }
+    expect_stdout: true
+}

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