fix corner case in evaluate (#4138)

fixes #4137
This commit is contained in:
Alex Lam S.L
2020-09-21 23:49:32 +01:00
committed by GitHub
parent 8fa470c17c
commit 13cdc167a2
3 changed files with 264 additions and 203 deletions

View File

@@ -3106,7 +3106,12 @@ merge(Compressor.prototype, {
(function(def) {
def(AST_Node, return_false);
def(AST_Assign, function(compressor) {
return (this.operator == "=" || this.operator == "+=") && this.right.is_string(compressor);
switch (this.operator) {
case "+=":
if (this.left.is_string(compressor)) return true;
case "=":
return this.right.is_string(compressor);
}
});
def(AST_Binary, function(compressor) {
return this.operator == "+" &&
@@ -7365,10 +7370,9 @@ merge(Compressor.prototype, {
var indexFns = makePredicate("indexOf lastIndexOf");
var commutativeOperators = makePredicate("== === != !== * & | ^");
function is_object(node) {
while ((node = node.tail_node()) instanceof AST_SymbolRef) {
node = node.fixed_value();
if (!node) return false;
}
if (node instanceof AST_Assign) return node.operator == "=" && is_object(node.right);
if (node instanceof AST_Sequence) return is_object(node.tail_node());
if (node instanceof AST_SymbolRef) return is_object(node.fixed_value());
return node instanceof AST_Array
|| node instanceof AST_Lambda
|| node instanceof AST_New
@@ -7760,14 +7764,16 @@ merge(Compressor.prototype, {
associative = compressor.option("unsafe_math");
// +a - b => a - b
// a - +b => a - b
if (self.operator != "+") {
if (self.left instanceof AST_UnaryPrefix && self.left.operator == "+") {
self.left = self.left.expression;
}
if (self.right instanceof AST_UnaryPrefix && self.right.operator == "+") {
self.right = self.right.expression;
[ "left", "right" ].forEach(function(operand) {
var node = self[operand];
if (node instanceof AST_UnaryPrefix && node.operator == "+") {
var exp = node.expression;
if (exp.is_boolean(compressor) || exp.is_number(compressor)
|| self.operator != "+" && exp.is_string(compressor)) {
self[operand] = exp;
}
}
});
case "&":
case "|":
case "^":

View File

@@ -95,7 +95,7 @@ asm_mixed: {
return +sum;
}
function geometricMean(start, end) {
return start |= 0, end |= 0, +exp(logSum(start, end) / (end - start | 0));
return start |= 0, end |= 0, +exp(+logSum(start, end) / (end - start | 0));
}
var exp = stdlib.Math.exp, log = stdlib.Math.log, values = new stdlib.Float64Array(buffer);
return { geometricMean: geometricMean };

View File

@@ -91,7 +91,7 @@ evaluate_1: {
expect: {
console.log(
x + 1 + 2,
2 * x,
2 * +x,
+x + 1 + 2,
1 + x + 2 + 3,
3 | x,
@@ -130,7 +130,7 @@ evaluate_1_unsafe_math: {
expect: {
console.log(
x + 1 + 2,
2 * x,
2 * +x,
+x + 3,
1 + x + 2 + 3,
3 | x,
@@ -148,10 +148,12 @@ evaluate_1_unsafe_math: {
evaluate_2: {
options = {
evaluate: true,
reduce_vars: true,
unsafe_math: false,
}
input: {
var x = "42", y = null;
function f(num) {
var x = "" + num, y = null;
[
x + 1 + 2,
x * 1 * 2,
@@ -169,25 +171,30 @@ evaluate_2: {
console.log(typeof n, n);
});
}
f(42);
}
expect: {
var x = "42", y = null;
function f(num) {
var x = "" + num, y = null;
[
x + 1 + 2,
x + "12",
2 * x,
+x + 1 + 2,
1 + x + 2 + 3,
1 + x + "23",
3 | x,
1 + x-- + 2 + 3,
x*y + 2 + 1 + 3,
1 + (2 + x + 3),
2 + x + 3 + 1,
2 + ~x + 3 + 1,
2 + ~x + 3 - y,
2 + ~x + 3,
0 & x,
2 + (x |= 0) + 3 + 1,
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(42);
}
expect_stdout: [
"string 4212",
"number 84",
@@ -207,10 +214,12 @@ evaluate_2: {
evaluate_2_unsafe_math: {
options = {
evaluate: true,
reduce_vars: true,
unsafe_math: true,
}
input: {
var x = "42", y = null;
function f(num) {
var x = "" + num, y = null;
[
x + 1 + 2,
x * 1 * 2,
@@ -228,25 +237,30 @@ evaluate_2_unsafe_math: {
console.log(typeof n, n);
});
}
f(42);
}
expect: {
var x = "42", y = null;
function f(num) {
var x = "" + num, y = null;
[
x + 1 + 2,
x + "12",
2 * x,
+x + 3,
1 + x + 2 + 3,
1 + x + "23",
3 | x,
6 + x--,
x*y + 6,
1 + (2 + x + 3),
6 + x,
6 + ~x,
5 + ~x - y,
5 + ~x,
0 & x,
6 + (x |= 0),
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(42);
}
expect_stdout: [
"string 4212",
"number 84",
@@ -310,10 +324,12 @@ evaluate_4: {
evaluate_5: {
options = {
evaluate: true,
reduce_vars: true,
unsafe_math: false,
}
input: {
var a = "1";
function f(num) {
var a = "" + num;
[
+a + 2 + 3,
+a + 2 - 3,
@@ -331,8 +347,11 @@ evaluate_5: {
console.log(typeof n, n);
});
}
f(1);
}
expect: {
var a = "1";
function f(num) {
var a = "" + num;
[
+a + 2 + 3,
+a + 2 - 3,
@@ -350,6 +369,8 @@ evaluate_5: {
console.log(typeof n, n);
});
}
f(1);
}
expect_stdout: [
"number 6",
"number 0",
@@ -369,10 +390,12 @@ evaluate_5: {
evaluate_5_unsafe_math: {
options = {
evaluate: true,
reduce_vars: true,
unsafe_math: true,
}
input: {
var a = "1";
function f(num) {
var a = "" + num;
[
+a + 2 + 3,
+a + 2 - 3,
@@ -390,8 +413,11 @@ evaluate_5_unsafe_math: {
console.log(typeof n, n);
});
}
f(1);
}
expect: {
var a = "1";
function f(num) {
var a = "" + num;
[
+a + 5,
+a + -1,
@@ -409,6 +435,8 @@ evaluate_5_unsafe_math: {
console.log(typeof n, n);
});
}
f(1);
}
expect_stdout: [
"number 6",
"number 0",
@@ -546,10 +574,12 @@ evaluate_6_unsafe_math: {
evaluate_7: {
options = {
evaluate: true,
reduce_vars: true,
unsafe_math: false,
}
input: {
var x = "42", y;
function f(num, y) {
var x = "" + num;
[
+x + 2 + (3 + !y),
+x + 2 + (3 - !y),
@@ -563,8 +593,11 @@ evaluate_7: {
console.log(typeof n, n);
});
}
f(42);
}
expect: {
var x = "42", y;
function f(num, y) {
var x = "" + num;
[
+x + 2 + (3 + !y),
+x + 2 + (3 - !y),
@@ -578,6 +611,8 @@ evaluate_7: {
console.log(typeof n, n);
});
}
f(42);
}
expect_stdout: [
"number 48",
"number 46",
@@ -593,10 +628,12 @@ evaluate_7: {
evaluate_7_unsafe_math: {
options = {
evaluate: true,
reduce_vars: true,
unsafe_math: true,
}
input: {
var x = "42", y;
function f(num, y) {
var x = "" + num;
[
+x + 2 + (3 + !y),
+x + 2 + (3 - !y),
@@ -610,8 +647,11 @@ evaluate_7_unsafe_math: {
console.log(typeof n, n);
});
}
f(42);
}
expect: {
var x = "42", y;
function f(num, y) {
var x = "" + num;
[
+x + 5 + !y,
+x + 5 - !y,
@@ -625,6 +665,8 @@ evaluate_7_unsafe_math: {
console.log(typeof n, n);
});
}
f(42);
}
expect_stdout: [
"number 48",
"number 46",
@@ -1267,3 +1309,16 @@ issue_3695: {
}
expect_stdout: "NaN"
}
issue_4137: {
options = {
evaluate: true,
}
input: {
console.log(+(A = []) * (A[0] = 1));
}
expect: {
console.log(+(A = []) * (A[0] = 1));
}
expect_stdout: "0"
}