[Pkg-javascript-commits] [uglifyjs] 44/228: consolidate `evaluate` & `reduce_vars` (#1505)

Jonas Smedegaard dr at jones.dk
Sat Apr 15 14:25:15 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 16cd5d57a5cf7f5750104df0e5af246708fd493f
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Sun Feb 26 00:40:33 2017 +0800

    consolidate `evaluate` & `reduce_vars` (#1505)
    
    - improve marking efficiency
    - apply smarter `const` replacement to `var`
    
    fixes #1501
---
 lib/compress.js                       | 81 +++++++++++++++++++----------------
 lib/scope.js                          |  2 -
 test/compress/evaluate.js             |  2 +-
 test/compress/reduce_vars.js          | 16 +++----
 test/mocha/comment_before_constant.js |  6 +--
 5 files changed, 57 insertions(+), 50 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index 2bc1c5a..ccd6e23 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -118,7 +118,7 @@ merge(Compressor.prototype, {
         var passes = +this.options.passes || 1;
         for (var pass = 0; pass < passes && pass < 3; ++pass) {
             if (pass > 0 || this.option("reduce_vars"))
-                node.reset_opt_flags(this);
+                node.reset_opt_flags(this, true);
             node = node.transform(this);
         }
         return node;
@@ -177,28 +177,26 @@ merge(Compressor.prototype, {
         return this.print_to_string() == node.print_to_string();
     });
 
-    AST_Node.DEFMETHOD("reset_opt_flags", function(compressor){
-        var reduce_vars = compressor.option("reduce_vars");
+    AST_Node.DEFMETHOD("reset_opt_flags", function(compressor, rescan){
+        var reduce_vars = rescan && compressor.option("reduce_vars");
+        var unsafe = compressor.option("unsafe");
         var tw = new TreeWalker(function(node){
-            if (reduce_vars && node instanceof AST_Scope) {
-                node.variables.each(function(def) {
-                    delete def.modified;
-                });
-            }
-            if (node instanceof AST_SymbolRef) {
-                var d = node.definition();
-                if (d.init) {
-                    delete d.init._evaluated;
+            if (reduce_vars) {
+                if (node instanceof AST_Toplevel) node.globals.each(reset_def);
+                if (node instanceof AST_Scope) node.variables.each(reset_def);
+                if (node instanceof AST_SymbolRef) {
+                    var d = node.definition();
+                    d.references.push(node);
+                    if (!d.modified && (d.orig.length > 1 || isModified(node, 0))) {
+                        d.modified = true;
+                    }
                 }
-                if (reduce_vars && (d.orig.length > 1 || isModified(node, 0))) {
-                    d.modified = true;
+                if (node instanceof AST_Call && node.expression instanceof AST_Function) {
+                    node.expression.argnames.forEach(function(arg, i) {
+                        arg.definition().init = node.args[i] || make_node(AST_Undefined, node);
+                    });
                 }
             }
-            if (reduce_vars && node instanceof AST_Call && node.expression instanceof AST_Function) {
-                node.expression.argnames.forEach(function(arg, i) {
-                    arg.definition().init = node.args[i] || make_node(AST_Undefined, node);
-                });
-            }
             if (!(node instanceof AST_Directive || node instanceof AST_Constant)) {
                 node._squeezed = false;
                 node._optimized = false;
@@ -206,10 +204,18 @@ merge(Compressor.prototype, {
         });
         this.walk(tw);
 
+        function reset_def(def) {
+            def.modified = false;
+            def.references = [];
+            def.should_replace = undefined;
+            if (unsafe && def.init) {
+                def.init._evaluated = undefined;
+            }
+        }
+
         function isModified(node, level) {
             var parent = tw.parent(level);
-            if (parent instanceof AST_Unary && (parent.operator === "++" || parent.operator === "--")
-                || parent instanceof AST_Assign && parent.left === node
+            if (isLHS(node, parent)
                 || parent instanceof AST_Call && parent.expression === node) {
                 return true;
             } else if (parent instanceof AST_PropAccess && parent.expression === node) {
@@ -1254,7 +1260,7 @@ merge(Compressor.prototype, {
                 var d = this.definition();
                 if (compressor.option("reduce_vars") && !d.modified && d.init) {
                     if (compressor.option("unsafe")) {
-                        if (!HOP(d.init, '_evaluated')) {
+                        if (d.init._evaluated === undefined) {
                             d.init._evaluated = ev(d.init, compressor);
                         }
                         return d.init._evaluated;
@@ -2403,9 +2409,6 @@ merge(Compressor.prototype, {
     });
 
     OPT(AST_Call, function(self, compressor){
-        self.args = self.args.map(function(arg) {
-            return arg.evaluate(compressor)[0];
-        });
         if (compressor.option("unsafe")) {
             var exp = self.expression;
             if (exp instanceof AST_SymbolRef && exp.undeclared()) {
@@ -3025,18 +3028,24 @@ merge(Compressor.prototype, {
                 return make_node(AST_Infinity, self).transform(compressor);
             }
         }
-        if (compressor.option("evaluate")
-            && compressor.option("reduce_vars")
-            && !isLHS(self, compressor.parent())) {
+        if (compressor.option("evaluate") && compressor.option("reduce_vars")) {
             var d = self.definition();
-            if (d.constant && !d.modified && d.init && d.init.is_constant(compressor)) {
-                var original_as_string = self.print_to_string();
-                var const_node = make_node_from_constant(compressor, d.init.constant_value(compressor), self);
-                var const_node_as_string = const_node.print_to_string();
-                var per_const_overhead = d.global || !d.references.length ? 0
-                    : (d.name.length + 2 + const_node_as_string.length) / d.references.length;
-                if (const_node_as_string.length <= original_as_string.length + per_const_overhead)
-                    return const_node;
+            if (!d.modified && d.init) {
+                if (d.should_replace === undefined) {
+                    var init = d.init.evaluate(compressor);
+                    if (init.length > 1) {
+                        var value = init[0].print_to_string().length;
+                        var name = d.name.length;
+                        var freq = d.references.length;
+                        var overhead = d.global || !freq ? 0 : (name + 2 + value) / freq;
+                        d.should_replace = value <= name + overhead ? init[0] : false;
+                    } else {
+                        d.should_replace = false;
+                    }
+                }
+                if (d.should_replace) {
+                    return d.should_replace;
+                }
             }
         }
         return self;
diff --git a/lib/scope.js b/lib/scope.js
index 29e4103..ae0c577 100644
--- a/lib/scope.js
+++ b/lib/scope.js
@@ -51,7 +51,6 @@ function SymbolDef(scope, index, orig) {
     this.global = false;
     this.mangled_name = null;
     this.undeclared = false;
-    this.constant = false;
     this.index = index;
     this.id = SymbolDef.next_id++;
 };
@@ -156,7 +155,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
         else if (node instanceof AST_SymbolVar
                  || node instanceof AST_SymbolConst) {
             var def = defun.def_variable(node);
-            def.constant = node instanceof AST_SymbolConst;
             def.init = tw.parent().value;
         }
         else if (node instanceof AST_SymbolCatch) {
diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js
index ae5e58d..5cefadc 100644
--- a/test/compress/evaluate.js
+++ b/test/compress/evaluate.js
@@ -615,7 +615,7 @@ call_args: {
         const a = 1;
         console.log(1);
         +function(a) {
-            return a;
+            return 1;
         }(1);
     }
 }
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index d9d02ef..0ee201c 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -134,8 +134,8 @@ modified: {
         }
 
         function f2() {
-            var b = 2, c = 3;
-            b = c;
+            var b = 2;
+            b = 3;
             console.log(1 + b);
             console.log(b + 3);
             console.log(4);
@@ -143,8 +143,8 @@ modified: {
         }
 
         function f3() {
-            var b = 2, c = 3;
-            b *= c;
+            var b = 2;
+            b *= 3;
             console.log(1 + b);
             console.log(b + 3);
             console.log(4);
@@ -236,7 +236,7 @@ unsafe_evaluate_object: {
         function f0(){
             var a = 1;
             var b = {};
-            b[a] = 2;
+            b[1] = 2;
             console.log(4);
         }
 
@@ -280,7 +280,7 @@ unsafe_evaluate_array: {
         function f0(){
             var a = 1;
             var b = [];
-            b[a] = 2;
+            b[1] = 2;
             console.log(4);
         }
 
@@ -373,8 +373,8 @@ passes: {
     }
     expect: {
         function f() {
-            var b = 2, c = 3;
-            b = c;
+            var b = 2;
+            b = 3;
             console.log(1 + b);
             console.log(b + 3);
             console.log(4);
diff --git a/test/mocha/comment_before_constant.js b/test/mocha/comment_before_constant.js
index cfdb6da..eaa8691 100644
--- a/test/mocha/comment_before_constant.js
+++ b/test/mocha/comment_before_constant.js
@@ -7,7 +7,7 @@ describe("comment before constant", function() {
     it("Should test comment before constant is retained and output after mangle.", function() {
         var result = Uglify.minify(js, {
             fromString: true,
-            compress: { collapse_vars: false },
+            compress: { collapse_vars: false, reduce_vars: false },
             mangle: {},
             output: { comments: true },
         });
@@ -17,9 +17,9 @@ describe("comment before constant", function() {
     it("Should test code works when comments disabled.", function() {
         var result = Uglify.minify(js, {
             fromString: true,
-            compress: { collapse_vars: false },
+            compress: { collapse_vars: false, reduce_vars: false },
             mangle: {},
-            output: {},
+            output: { comments: false },
         });
         assert.strictEqual(result.code, 'function f(){var n=!1;return n}');
     });

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