[Pkg-javascript-commits] [uglifyjs] 172/228: output optimal representations of NaN & Infinity (#1723)

Jonas Smedegaard dr at jones.dk
Sat Apr 15 14:25:27 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 09f77c7d4d37350102c36b270b553f45e706d0c8
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Wed Mar 29 18:31:55 2017 +0800

    output optimal representations of NaN & Infinity (#1723)
    
    - move these optimisations out from `Compressor` to `OutputStream`
    - fixes behaviour inconsistency when running uglified code from global or module levels due to redefinition
---
 lib/compress.js               | 33 +++++++----------
 lib/output.js                 | 19 +++++++++-
 test/compress/conditionals.js |  8 ++--
 test/compress/evaluate.js     | 16 ++++----
 test/compress/issue-1105.js   | 17 +++++----
 test/compress/issue-597.js    | 86 ++++++++++++++++++++++++++++++++++++++++++-
 test/compress/properties.js   |  2 +-
 7 files changed, 137 insertions(+), 44 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index 3c0fc45..66a6a18 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -413,18 +413,17 @@ merge(Compressor.prototype, {
                 value: val
             });
           case "number":
-            if (isNaN(val)) {
-                return make_node(AST_NaN, orig);
-            }
-
-            if ((1 / val) < 0) {
-                return make_node(AST_UnaryPrefix, orig, {
+            if (isNaN(val)) return make_node(AST_NaN, orig);
+            if (isFinite(val)) {
+                return 1 / val < 0 ? make_node(AST_UnaryPrefix, orig, {
                     operator: "-",
                     expression: make_node(AST_Number, orig, { value: -val })
-                });
+                }) : make_node(AST_Number, orig, { value: val });
             }
-
-            return make_node(AST_Number, orig, { value: val });
+            return val < 0 ? make_node(AST_UnaryPrefix, orig, {
+                operator: "-",
+                expression: make_node(AST_Infinity, orig)
+            }) : make_node(AST_Infinity, orig);
           case "boolean":
             return make_node(val ? AST_True : AST_False, orig);
           case "undefined":
@@ -3023,7 +3022,9 @@ merge(Compressor.prototype, {
             }
         }
         // avoids infinite recursion of numerals
-        if (self.operator != "-" || !(self.expression instanceof AST_Number)) {
+        if (self.operator != "-"
+            || !(self.expression instanceof AST_Number
+                || self.expression instanceof AST_Infinity)) {
             var ev = self.evaluate(compressor);
             if (ev !== self) {
                 ev = make_node_from_constant(ev, self).optimize(compressor);
@@ -3455,9 +3456,9 @@ merge(Compressor.prototype, {
               case "undefined":
                 return make_node(AST_Undefined, self).optimize(compressor);
               case "NaN":
-                return make_node(AST_NaN, self).optimize(compressor);
+                return make_node(AST_NaN, self);
               case "Infinity":
-                return make_node(AST_Infinity, self).optimize(compressor);
+                return make_node(AST_Infinity, self);
             }
         }
         if (compressor.option("evaluate") && compressor.option("reduce_vars")) {
@@ -3485,14 +3486,6 @@ merge(Compressor.prototype, {
         return self;
     });
 
-    OPT(AST_Infinity, function (self, compressor) {
-        return make_node(AST_Binary, self, {
-            operator : '/',
-            left     : make_node(AST_Number, self, {value: 1}),
-            right    : make_node(AST_Number, self, {value: 0})
-        });
-    });
-
     OPT(AST_Undefined, function(self, compressor){
         if (compressor.option("unsafe")) {
             var scope = compressor.find_parent(AST_Scope);
diff --git a/lib/output.js b/lib/output.js
index 5c11088..d71f6aa 100644
--- a/lib/output.js
+++ b/lib/output.js
@@ -592,6 +592,13 @@ function OutputStream(options) {
             || p instanceof AST_Call && p.expression === this;
     });
 
+    PARENS([ AST_Infinity, AST_NaN ], function(output){
+        var p = output.parent();
+        return p instanceof AST_PropAccess && p.expression === this
+            || p instanceof AST_Call && p.expression === this
+            || p instanceof AST_Unary && p.operator != "+" && p.operator != "-";
+    });
+
     PARENS(AST_Seq, function(output){
         var p = output.parent();
         return p instanceof AST_Call             // (foo, bar)() or foo(1, (2, 3), 4)
@@ -1254,10 +1261,18 @@ function OutputStream(options) {
     });
     DEFPRINT(AST_Hole, noop);
     DEFPRINT(AST_Infinity, function(self, output){
-        output.print("Infinity");
+        output.print("1");
+        output.space();
+        output.print("/");
+        output.space();
+        output.print("0");
     });
     DEFPRINT(AST_NaN, function(self, output){
-        output.print("NaN");
+        output.print("0");
+        output.space();
+        output.print("/");
+        output.space();
+        output.print("0");
     });
     DEFPRINT(AST_This, function(self, output){
         output.print("this");
diff --git a/test/compress/conditionals.js b/test/compress/conditionals.js
index e7ea2bb..54d4264 100644
--- a/test/compress/conditionals.js
+++ b/test/compress/conditionals.js
@@ -840,8 +840,8 @@ equality_conditionals_false: {
         f(0, true, 0),
         f(1, 2, 3),
         f(1, null, 3),
-        f(NaN),
-        f(NaN, "foo");
+        f(0/0),
+        f(0/0, "foo");
     }
     expect_stdout: true
 }
@@ -888,8 +888,8 @@ equality_conditionals_true: {
         f(0, true, 0),
         f(1, 2, 3),
         f(1, null, 3),
-        f(NaN),
-        f(NaN, "foo");
+        f(0/0),
+        f(0/0, "foo");
     }
     expect_stdout: true
 }
diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js
index 7a56205..35b6b92 100644
--- a/test/compress/evaluate.js
+++ b/test/compress/evaluate.js
@@ -52,7 +52,7 @@ and: {
         a = 7;
 
         a = false;
-        a = NaN;
+        a = 0/0;
         a = 0;
         a = void 0;
         a = null;
@@ -67,7 +67,7 @@ and: {
         a = 6 << condition   && -4.5;
 
         a = condition        && false;
-        a = console.log("b") && NaN;
+        a = console.log("b") && 0/0;
         a = console.log("c") && 0;
         a = 2 * condition    && void 0;
         a = condition + 3    && null;
@@ -149,7 +149,7 @@ or: {
         a = 6 << condition   || -4.5;
 
         a = condition        || false;
-        a = console.log("b") || NaN;
+        a = console.log("b") || 0/0;
         a = console.log("c") || 0;
         a = 2 * condition    || void 0;
         a = condition + 3    || null;
@@ -196,8 +196,8 @@ negative_zero: {
         console.log(
             -0,
             0,
-            1 / (-0),
-            1 / (-0)
+            -1/0,
+            -1/0
         );
     }
     expect_stdout: true
@@ -217,8 +217,8 @@ positive_zero: {
         console.log(
             0,
             -0,
-            1 / (0),
-            1 / (0)
+            1/0,
+            1/0
         );
     }
     expect_stdout: true
@@ -533,7 +533,7 @@ unsafe_array: {
             [1, 2, 3, a][0] + 1,
             2,
             3,
-            NaN,
+            0/0,
             "1,21",
             5,
             (void 0)[1] + 1
diff --git a/test/compress/issue-1105.js b/test/compress/issue-1105.js
index 28f1557..f941216 100644
--- a/test/compress/issue-1105.js
+++ b/test/compress/issue-1105.js
@@ -195,11 +195,12 @@ assorted_Infinity_NaN_undefined_in_with_scope: {
         sequences:     false,
     }
     input: {
+        var f = console.log;
         var o = {
             undefined : 3,
             NaN       : 4,
             Infinity  : 5,
-        }
+        };
         if (o) {
             f(undefined, void 0);
             f(NaN, 0/0);
@@ -216,25 +217,25 @@ assorted_Infinity_NaN_undefined_in_with_scope: {
         }
     }
     expect: {
-        var o = {
+        var f = console.log, o = {
             undefined : 3,
             NaN       : 4,
             Infinity  : 5
-        }
+        };
         if (o) {
             f(void 0, void 0);
-            f(NaN, NaN);
+            f(0/0, 0/0);
             f(1/0, 1/0);
-            f(-(1/0), -(1/0));
-            f(NaN, NaN);
+            f(-1/0, -1/0);
+            f(0/0, 0/0);
         }
         with (o) {
             f(undefined, void 0);
             f(NaN, 0/0);
             f(Infinity, 1/0);
-            f(-Infinity, -(1/0));
+            f(-Infinity, -1/0);
             f(9 + undefined, 9 + void 0);
         }
     }
+    expect_stdout: true
 }
-
diff --git a/test/compress/issue-597.js b/test/compress/issue-597.js
index f243223..3a50153 100644
--- a/test/compress/issue-597.js
+++ b/test/compress/issue-597.js
@@ -6,7 +6,7 @@ NaN_and_Infinity_must_have_parens: {
     }
     expect: {
         (1/0).toString();
-        NaN.toString();         // transformation to 0/0 dropped
+        (0/0).toString();
     }
 }
 
@@ -23,3 +23,87 @@ NaN_and_Infinity_should_not_be_replaced_when_they_are_redefined: {
         NaN.toString();
     }
 }
+
+beautify_off_1: {
+    options = {
+        evaluate: true,
+    }
+    beautify = {
+        beautify: false,
+    }
+    input: {
+        var NaN;
+        console.log(
+            null,
+            undefined,
+            Infinity,
+            NaN,
+            Infinity * undefined,
+            Infinity.toString(),
+            NaN.toString(),
+            (Infinity * undefined).toString()
+        );
+    }
+    expect_exact: "var NaN;console.log(null,void 0,1/0,NaN,0/0,(1/0).toString(),NaN.toString(),(0/0).toString());"
+    expect_stdout: true
+}
+
+beautify_off_2: {
+    options = {
+        evaluate: true,
+    }
+    beautify = {
+        beautify: false,
+    }
+    input: {
+        console.log(
+            null.toString(),
+            undefined.toString()
+        );
+    }
+    expect_exact: "console.log(null.toString(),(void 0).toString());"
+}
+
+beautify_on_1: {
+    options = {
+        evaluate: true,
+    }
+    beautify = {
+        beautify: true,
+    }
+    input: {
+        var NaN;
+        console.log(
+            null,
+            undefined,
+            Infinity,
+            NaN,
+            Infinity * undefined,
+            Infinity.toString(),
+            NaN.toString(),
+            (Infinity * undefined).toString()
+        );
+    }
+    expect_exact: [
+        "var NaN;",
+        "",
+        "console.log(null, void 0, 1 / 0, NaN, 0 / 0, (1 / 0).toString(), NaN.toString(), (0 / 0).toString());",
+    ]
+    expect_stdout: true
+}
+
+beautify_on_2: {
+    options = {
+        evaluate: true,
+    }
+    beautify = {
+        beautify: true,
+    }
+    input: {
+        console.log(
+            null.toString(),
+            undefined.toString()
+        );
+    }
+    expect_exact: "console.log(null.toString(), (void 0).toString());"
+}
diff --git a/test/compress/properties.js b/test/compress/properties.js
index 29bdfe2..376fb9e 100644
--- a/test/compress/properties.js
+++ b/test/compress/properties.js
@@ -77,7 +77,7 @@ sub_properties: {
         a[3.14] = 3;
         a.if = 4;
         a["foo bar"] = 5;
-        a[NaN] = 6;
+        a[0/0] = 6;
         a[null] = 7;
         a[void 0] = 8;
     }

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