From a47b24f29f00ddac7d4afb643ff8b8d31b16673f Mon Sep 17 00:00:00 2001 From: alexlamsl Date: Mon, 26 Feb 2018 13:38:10 +0800 Subject: [PATCH] migrate safe transformations out of `unsafe_comps` fixes #2959 --- README.md | 12 +++----- lib/compress.js | 8 ++---- test/compress/asm.js | 2 +- test/compress/comparing.js | 56 ++++++++++++------------------------- test/compress/issue-1447.js | 2 +- 5 files changed, 27 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 4e30af25..e754e0bc 100644 --- a/README.md +++ b/README.md @@ -605,8 +605,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u side effects permitting. - `comparisons` (default: `true`) -- apply certain optimizations to binary nodes, - e.g. `!(a <= b) → a > b` (only when `unsafe_comps`), attempts to negate binary - nodes, e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc. + e.g. `!(a <= b) → a > b`, attempts to negate binary nodes, e.g. + `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc. - `conditionals` (default: `true`) -- apply optimizations for `if`-s and conditional expressions @@ -730,12 +730,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u - `unsafe` (default: `false`) -- apply "unsafe" transformations (discussion below) -- `unsafe_comps` (default: `false`) -- Reverse `<` and `<=` to `>` and `>=` to - allow improved compression. This might be unsafe when an at least one of two - operands is an object with computed values due the use of methods like `get`, - or `valueOf`. This could cause change in execution order after operands in the - comparison are switching. Compression only works if both `comparisons` and - `unsafe_comps` are both set to true. +- `unsafe_comps` (default: `false`) -- compress expressions like `a <= b` assuming + none of the operands can be (coerced to) `NaN`. - `unsafe_Function` (default: `false`) -- compress and mangle `Function(args, code)` when both `args` and `code` are string literals. diff --git a/lib/compress.js b/lib/compress.js index ed094874..fd17e2dc 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -5033,11 +5033,9 @@ merge(Compressor.prototype, { }); self = best_of(compressor, self, negated); } - if (compressor.option("unsafe_comps")) { - switch (self.operator) { - case "<": reverse(">"); break; - case "<=": reverse(">="); break; - } + switch (self.operator) { + case "<": reverse(">"); break; + case "<=": reverse(">="); break; } } if (self.operator == "+") { diff --git a/test/compress/asm.js b/test/compress/asm.js index a9047c5d..ac91bd13 100644 --- a/test/compress/asm.js +++ b/test/compress/asm.js @@ -91,7 +91,7 @@ asm_mixed: { function logSum(start, end) { start |= 0, end |= 0; var sum = 0, p = 0, q = 0; - for (p = start << 3, q = end << 3; (0 | p) < (0 | q); p = p + 8 | 0) sum += +log(values[p >> 3]); + for (p = start << 3, q = end << 3; (0 | q) > (0 | p); p = p + 8 | 0) sum += +log(values[p >> 3]); return +sum; } function geometricMean(start, end) { diff --git a/test/compress/comparing.js b/test/compress/comparing.js index d56445e0..5d743471 100644 --- a/test/compress/comparing.js +++ b/test/compress/comparing.js @@ -1,62 +1,42 @@ -keep_comparisons: { +comparisons: { options = { comparisons: true, - unsafe_comps: false } input: { - var obj1 = { - valueOf: function() {triggeredFirst();} - } - var obj2 = { - valueOf: function() {triggeredSecond();} - } + var obj1, obj2; var result1 = obj1 <= obj2; var result2 = obj1 < obj2; var result3 = obj1 >= obj2; var result4 = obj1 > obj2; } expect: { - var obj1 = { - valueOf: function() {triggeredFirst();} - } - var obj2 = { - valueOf: function() {triggeredSecond();} - } - var result1 = obj1 <= obj2; - var result2 = obj1 < obj2; + var obj1, obj2; + var result1 = obj2 >= obj1; + var result2 = obj2 > obj1; var result3 = obj1 >= obj2; var result4 = obj1 > obj2; } } -keep_comparisons_with_unsafe_comps: { +unsafe_comps: { options = { comparisons: true, - unsafe_comps: true + conditionals: true, + unsafe_comps: true, } input: { - var obj1 = { - valueOf: function() {triggeredFirst();} - } - var obj2 = { - valueOf: function() {triggeredSecond();} - } - var result1 = obj1 <= obj2; - var result2 = obj1 < obj2; - var result3 = obj1 >= obj2; - var result4 = obj1 > obj2; + var obj1, obj2; + obj1 <= obj2 ? f1() : g1(); + obj1 < obj2 ? f2() : g2(); + obj1 >= obj2 ? f3() : g3(); + obj1 > obj2 ? f4() : g4(); } expect: { - var obj1 = { - valueOf: function() {triggeredFirst();} - } - var obj2 = { - valueOf: function() {triggeredSecond();} - } - var result1 = obj2 >= obj1; - var result2 = obj2 > obj1; - var result3 = obj1 >= obj2; - var result4 = obj1 > obj2; + var obj1, obj2; + obj1 > obj2 ? g1() : f1(); + obj2 > obj1 ? f2() : g2(); + obj2 > obj1 ? g3() : f3(); + obj1 > obj2 ? f4() : g4(); } } diff --git a/test/compress/issue-1447.js b/test/compress/issue-1447.js index 0a765685..30a74c56 100644 --- a/test/compress/issue-1447.js +++ b/test/compress/issue-1447.js @@ -40,6 +40,6 @@ conditional_false_stray_else_in_loop: { console.log(i); } } - expect_exact: "for(var i=1;i<=4;++i)if(!(i<=2))console.log(i);" + expect_exact: "for(var i=1;4>=i;++i)if(!(2>=i))console.log(i);" expect_stdout: true }