Fix test262 failures related to <, <=, in and instanceof

Fixed-by: @kzc
This commit is contained in:
Anthony Van de Gejuchte
2016-06-13 18:19:06 +02:00
parent 5c4cfaa0a7
commit d7971ba0e4
4 changed files with 92 additions and 9 deletions

View File

@@ -291,12 +291,19 @@ to set `true`; it's effectively a shortcut for `foo=true`).
- `unsafe` (default: false) -- apply "unsafe" transformations (discussion below) - `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.
- `conditionals` -- apply optimizations for `if`-s and conditional - `conditionals` -- apply optimizations for `if`-s and conditional
expressions expressions
- `comparisons` -- apply certain optimizations to binary nodes, for example: - `comparisons` -- apply certain optimizations to binary nodes, for example:
`!(a <= b) → a > b` (only when `unsafe`), attempts to negate binary nodes, `!(a <= b) → a > b` (only when `unsafe_comps`), attempts to negate binary
e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc. nodes, e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
- `evaluate` -- attempt to evaluate constant expressions - `evaluate` -- attempt to evaluate constant expressions

View File

@@ -1079,8 +1079,6 @@ merge(Compressor.prototype, {
case "<=" : return ev(left, c) <= ev(right, c); case "<=" : return ev(left, c) <= ev(right, c);
case ">" : return ev(left, c) > ev(right, c); case ">" : return ev(left, c) > ev(right, c);
case ">=" : return ev(left, c) >= ev(right, c); case ">=" : return ev(left, c) >= ev(right, c);
case "in" : return ev(left, c) in ev(right, c);
case "instanceof" : return ev(left, c) instanceof ev(right, c);
} }
throw def; throw def;
}); });
@@ -2502,9 +2500,11 @@ merge(Compressor.prototype, {
}); });
self = best_of(self, negated); self = best_of(self, negated);
} }
switch (self.operator) { if (compressor.option("unsafe_comps")) {
case "<": reverse(">"); break; switch (self.operator) {
case "<=": reverse(">="); break; case "<": reverse(">"); break;
case "<=": reverse(">="); break;
}
} }
} }
if (self.operator == "+" && self.right instanceof AST_String if (self.operator == "+" && self.right instanceof AST_String

View File

@@ -92,7 +92,7 @@ asm_mixed: {
function logSum(start, end) { function logSum(start, end) {
start = 0 | start, end = 0 | end; start = 0 | start, end = 0 | end;
var sum = 0, p = 0, q = 0; var sum = 0, p = 0, q = 0;
for (p = start << 3, q = end << 3; (0 | q) > (0 | p); p = p + 8 | 0) sum += +log(values[p >> 3]); for (p = start << 3, q = end << 3; (0 | p) < (0 | q); p = p + 8 | 0) sum += +log(values[p >> 3]);
return +sum; return +sum;
} }
function geometricMean(start, end) { function geometricMean(start, end) {

View File

@@ -0,0 +1,76 @@
keep_comparisons: {
options = {
comparisons: true,
unsafe_comps: false
}
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;
}
expect: {
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;
}
}
keep_comparisons_with_unsafe_comps: {
options = {
comparisons: 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;
}
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;
}
}
dont_change_in_or_instanceof_expressions: {
input: {
1 in 1;
null in null;
1 instanceof 1;
null instanceof null;
}
expect: {
1 in 1;
null in null;
1 instanceof 1;
null instanceof null;
}
}