Skip to content

Commit

Permalink
fix & enhance unsafe_math (#3537)
Browse files Browse the repository at this point in the history
closes #3535
fixes #3536
  • Loading branch information
alexlamsl committed Oct 28, 2019
1 parent 06e135e commit 2f3b460
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
19 changes: 17 additions & 2 deletions lib/compress.js
Expand Up @@ -2899,7 +2899,19 @@ merge(Compressor.prototype, {
case ">=" : result = left >= right; break;
default : return this;
}
return isNaN(result) && compressor.find_parent(AST_With) ? this : result;
if (isNaN(result)) return compressor.find_parent(AST_With) ? this : result;
if (compressor.option("unsafe_math")
&& typeof result == "number"
&& (this.operator == "+" || this.operator == "-")) {
var digits = Math.max(0, decimals(left), decimals(right));
if (digits < 21) return +result.toFixed(digits);
}
return result;

function decimals(operand) {
var match = /(\.[0-9]*)?(e.+)?$/.exec(+operand);
return (match[1] || ".").length - 1 - (match[2] || "").slice(1);
}
});
def(AST_Conditional, function(compressor, cached, depth) {
var condition = this.condition._eval(compressor, cached, depth);
Expand Down Expand Up @@ -5980,8 +5992,11 @@ merge(Compressor.prototype, {
// a + (b + c) => (a + b) + c
if (self.right instanceof AST_Binary
&& self.right.operator != "%"
&& PRECEDENCE[self.right.operator] == PRECEDENCE[self.operator]
&& self.right.is_number(compressor)
&& PRECEDENCE[self.right.operator] == PRECEDENCE[self.operator]) {
&& (self.operator != "+"
|| self.right.left.is_boolean(compressor)
|| self.right.left.is_number(compressor))) {
self = make_node(AST_Binary, self, {
operator: align(self.operator, self.right.operator),
left: make_node(AST_Binary, self.left, {
Expand Down
20 changes: 19 additions & 1 deletion test/compress/numbers.js
Expand Up @@ -713,7 +713,7 @@ issue_3531_1: {
}
expect: {
var a = "1";
console.log(typeof (a + 1 - (.2 + .1)));
console.log(typeof (a + 1 - .3));
}
expect_stdout: "number"
}
Expand Down Expand Up @@ -747,3 +747,21 @@ issue_3531_3: {
}
expect_stdout: "-22"
}

issue_3536: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var a = 100, b = 10;
var c = --a + ("23" - (b++, 1));
console.log(typeof c, a, b, c);
}
expect: {
var a = 100, b = 10;
var c = --a + ("23" - (b++, 1));
console.log(typeof c, a, b, c);
}
expect_stdout: "number 99 11 121"
}
10 changes: 7 additions & 3 deletions test/ufuzz/index.js
Expand Up @@ -1050,16 +1050,20 @@ function log_rename(options) {
}
}

function orig_code(unsafe_math) {
return unsafe_math ? original_code.replace(/( - 0\.1){3}/g, " - 0.3") : original_code;
}

function log(options) {
options = JSON.parse(options);
if (!ok) errorln("\n\n\n\n\n\n!!!!!!!!!!\n\n\n");
errorln("//=============================================================");
if (!ok) errorln("// !!!!!! Failed... round " + round);
errorln("// original code");
try_beautify(original_code, false, original_result, errorln);
try_beautify(orig_code(options.compress.unsafe_math), options.toplevel, original_result, errorln);
errorln();
errorln();
errorln("//-------------------------------------------------------------");
options = JSON.parse(options);
if (typeof uglify_code == "string") {
errorln("// uglified code");
try_beautify(uglify_code, options.toplevel, uglify_result, errorln);
Expand Down Expand Up @@ -1103,7 +1107,7 @@ for (var round = 1; round <= num_iterations; round++) {
var orig_result = [ sandbox.run_code(original_code) ];
errored = typeof orig_result[0] != "string";
if (!errored) {
orig_result.push(sandbox.run_code(original_code, true), sandbox.run_code(original_code.replace(/( - 0\.1){3}/g, " - 0.3")));
orig_result.push(sandbox.run_code(original_code, true), sandbox.run_code(orig_code(true)));
}
(errored ? fallback_options : minify_options).forEach(function(options) {
var o = JSON.parse(options);
Expand Down

0 comments on commit 2f3b460

Please sign in to comment.