diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2017-03-29 18:31:55 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-29 18:31:55 +0800 |
commit | 09f77c7d4d37350102c36b270b553f45e706d0c8 (patch) | |
tree | 39d2af90ff895ad55db168069f6b3c8ac4bc959f /lib | |
parent | fef0bf9ee0367f07dfbca26b144c2995c2b5db5f (diff) | |
download | tracifyjs-09f77c7d4d37350102c36b270b553f45e706d0c8.tar.gz tracifyjs-09f77c7d4d37350102c36b270b553f45e706d0c8.zip |
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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compress.js | 33 | ||||
-rw-r--r-- | lib/output.js | 19 |
2 files changed, 30 insertions, 22 deletions
diff --git a/lib/compress.js b/lib/compress.js index 3c0fc452..66a6a18b 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 5c11088b..d71f6aac 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"); |