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
This commit is contained in:
Alex Lam S.L
2017-03-29 18:31:55 +08:00
committed by GitHub
parent fef0bf9ee0
commit 09f77c7d4d
7 changed files with 137 additions and 44 deletions

View File

@@ -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);