[Pkg-javascript-commits] [uglifyjs] 206/228: improve `pure_getters` (#1786)

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 06cdb74279d01ed9b4b625200882611482333825
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Thu Apr 6 11:18:59 2017 +0800

    improve `pure_getters` (#1786)
    
    - property access to `null` & `undefined` always has side effects
    - utilise `reduce_vars` to determine safe property access
    - may-be cases treated as side effects unless `unsafe`
---
 lib/compress.js                | 34 +++++++++++++----
 test/compress/collapse_vars.js |  1 +
 test/compress/pure_getters.js  | 85 ++++++++++++++++++++++++++++++++++++++++++
 test/ufuzz.json                |  1 -
 4 files changed, 113 insertions(+), 8 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index ef7f044..22c79b8 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -1160,6 +1160,26 @@ merge(Compressor.prototype, {
                 && !node.expression.has_side_effects(compressor);
     }
 
+    (function(def) {
+        def(AST_Node, return_false);
+        def(AST_Null, return_true);
+        def(AST_Undefined, return_true);
+        def(AST_UnaryPrefix, function() {
+            return this.operator == "void";
+        });
+        def(AST_PropAccess, function(compressor) {
+            return !compressor.option("unsafe");
+        });
+        def(AST_SymbolRef, function(compressor) {
+            if (this.is_undefined) return true;
+            if (compressor.option("unsafe")) return false;
+            var fixed = this.fixed_value();
+            return !fixed || fixed.may_eq_null(compressor);
+        });
+    })(function(node, func) {
+        node.DEFMETHOD("may_eq_null", func);
+    });
+
     /* -----[ boolean/negation helpers ]----- */
 
     // methods to determine whether an expression has a boolean result type
@@ -1688,7 +1708,7 @@ merge(Compressor.prototype, {
                 || this.expression.has_side_effects(compressor);
         });
         def(AST_SymbolRef, function(compressor){
-            return this.global() && this.undeclared();
+            return this.undeclared();
         });
         def(AST_Object, function(compressor){
             return any(this.properties, compressor);
@@ -1701,16 +1721,15 @@ merge(Compressor.prototype, {
         });
         def(AST_Dot, function(compressor){
             if (!compressor.option("pure_getters")) return true;
-            return this.expression.has_side_effects(compressor);
+            return this.expression.may_eq_null(compressor)
+                || this.expression.has_side_effects(compressor);
         });
         def(AST_Sub, function(compressor){
             if (!compressor.option("pure_getters")) return true;
-            return this.expression.has_side_effects(compressor)
+            return this.expression.may_eq_null(compressor)
+                || this.expression.has_side_effects(compressor)
                 || this.property.has_side_effects(compressor);
         });
-        def(AST_PropAccess, function(compressor){
-            return !compressor.option("pure_getters");
-        });
         def(AST_Seq, function(compressor){
             return this.car.has_side_effects(compressor)
                 || this.cdr.has_side_effects(compressor);
@@ -2275,10 +2294,12 @@ merge(Compressor.prototype, {
         });
         def(AST_Dot, function(compressor, first_in_statement){
             if (!compressor.option("pure_getters")) return this;
+            if (this.expression.may_eq_null(compressor)) return this;
             return this.expression.drop_side_effect_free(compressor, first_in_statement);
         });
         def(AST_Sub, function(compressor, first_in_statement){
             if (!compressor.option("pure_getters")) return this;
+            if (this.expression.may_eq_null(compressor)) return this;
             var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
             if (!expression) return this.property.drop_side_effect_free(compressor, first_in_statement);
             var property = this.property.drop_side_effect_free(compressor);
@@ -3509,7 +3530,6 @@ merge(Compressor.prototype, {
         // testing against !self.scope.uses_with first is an optimization
         if (compressor.option("screw_ie8")
             && self.undeclared()
-            && !isLHS(self, compressor.parent())
             && (!self.scope.uses_with || !compressor.find_parent(AST_With))) {
             switch (self.name) {
               case "undefined":
diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js
index 4107707..2264783 100644
--- a/test/compress/collapse_vars.js
+++ b/test/compress/collapse_vars.js
@@ -1573,6 +1573,7 @@ var_side_effects_3: {
     options = {
         collapse_vars: true,
         pure_getters: true,
+        unsafe: true,
     }
     input: {
         var print = console.log.bind(console);
diff --git a/test/compress/pure_getters.js b/test/compress/pure_getters.js
new file mode 100644
index 0000000..338f863
--- /dev/null
+++ b/test/compress/pure_getters.js
@@ -0,0 +1,85 @@
+side_effects: {
+    options = {
+        pure_getters: true,
+        reduce_vars: false,
+        side_effects: true,
+        toplevel: true,
+        unsafe: false,
+    }
+    input: {
+        var a, b = null, c = {};
+        a.prop;
+        b.prop;
+        c.prop;
+        d.prop;
+        null.prop;
+        (void 0).prop;
+        undefined.prop;
+    }
+    expect: {
+        var a, b = null, c = {};
+        a.prop;
+        b.prop;
+        c.prop;
+        d.prop;
+        null.prop;
+        (void 0).prop;
+        (void 0).prop;
+    }
+}
+
+side_effects_reduce_vars: {
+    options = {
+        pure_getters: true,
+        reduce_vars: true,
+        side_effects: true,
+        toplevel: true,
+        unsafe: false,
+    }
+    input: {
+        var a, b = null, c = {};
+        a.prop;
+        b.prop;
+        c.prop;
+        d.prop;
+        null.prop;
+        (void 0).prop;
+        undefined.prop;
+    }
+    expect: {
+        var a, b = null, c = {};
+        a.prop;
+        b.prop;
+        d.prop;
+        null.prop;
+        (void 0).prop;
+        (void 0).prop;
+    }
+}
+
+side_effects_unsafe: {
+    options = {
+        pure_getters: true,
+        reduce_vars: false,
+        side_effects: true,
+        toplevel: true,
+        unsafe: true,
+    }
+    input: {
+        var a, b = null, c = {};
+        a.prop;
+        b.prop;
+        c.prop;
+        d.prop;
+        null.prop;
+        (void 0).prop;
+        undefined.prop;
+    }
+    expect: {
+        var a, b = null, c = {};
+        d;
+        null.prop;
+        (void 0).prop;
+        (void 0).prop;
+    }
+}
diff --git a/test/ufuzz.json b/test/ufuzz.json
index fd1084a..4523795 100644
--- a/test/ufuzz.json
+++ b/test/ufuzz.json
@@ -35,7 +35,6 @@
         "compress": {
             "keep_fargs": false,
             "passes": 3,
-            "pure_getters": true,
             "warnings": false
         }
     }

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