Chromium Code Reviews| Index: pkg/compiler/lib/src/js_backend/constant_emitter.dart |
| diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart |
| index d4e57fb4717df427d4bd7143626ba143052935b1..1561a7d8b726074b87d1c77d52f2b6fd18afaab5 100644 |
| --- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart |
| +++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart |
| @@ -200,6 +200,35 @@ class ConstantLiteralEmitter |
| return new jsAst.LiteralNull(); |
| } |
| + /// Reduces the size of exponential representations when minification is |
| + /// enabled. |
| + /// |
| + /// Removes the "+" after the exponential sign, and removes the "." before the |
| + /// "e". For example `1.23e+5` is changed to `123e3`. |
| + String _shortenExponentialRepresentation(String numberString) { |
| + if (!compiler.enableMinification) return numberString; |
|
sra1
2015/02/20 22:08:25
I would still do this, the cutoff avoids most weir
floitsch
2015/02/23 18:36:23
It was to avoid running it for visitDouble but don
|
| + if (numberString.length < 4) return numberString; |
| + if (numberString[1] == "e" && numberString[2] == "+") { |
| + // For example: "1e+5". Remove the "+". |
| + return "${numberString[0]}e${numberString.substring(2)}"; |
| + } |
| + if (numberString[1] != ".") return numberString; |
| + int digitsAfterDotCount = 0; |
| + int pos = 2; |
|
sra1
2015/02/20 22:08:25
int pos = numberString.indexOf('e', 2);
Or you co
floitsch
2015/02/23 18:36:23
Exponential representations always start with a si
|
| + while (pos < numberString.length && numberString[pos] != "e") { |
| + pos++; |
| + digitsAfterDotCount++; |
| + } |
| + if (pos >= numberString.length) return numberString; |
| + int exponent = int.parse(numberString.substring(pos + 1)); |
| + if (exponent <= digitsAfterDotCount) return numberString; |
| + String digitsAfterDot = numberString.substring(2, pos); |
| + int shiftedExponent = exponent - digitsAfterDotCount; |
| + String result = "${numberString[0]}${digitsAfterDot}e$shiftedExponent"; |
| + assert(double.parse(result) == double.parse(numberString)); |
| + return result; |
| + } |
| + |
| @override |
| jsAst.Expression visitInt(IntConstantValue constant, [_]) { |
| int primitiveValue = constant.primitiveValue; |
| @@ -209,10 +238,12 @@ class ConstantLiteralEmitter |
| // |
| // Note that this shortening apparently loses precision for big numbers |
| // (like 1234567890123456789012345 which becomes 1.2345678901234568e+24). |
|
sra1
2015/02/20 22:08:25
This comment might not be accurate - no +.
floitsch
2015/02/23 18:36:23
Done.
|
| - // However, since JavaScript engines implicitly convert to double, these |
| - // digits are lost anyway. |
| - if (primitiveValue.abs() >= 10000) { |
| - String exponential = primitiveValue.toStringAsExponential(); |
| + // However, since JavaScript engines represent all numbers as doubles, |
| + // these digits are lost anyway. |
| + int cutOffValue = compiler.enableMinification ? 10000 : 1e20.toInt(); |
| + if (primitiveValue.abs() >= cutOffValue) { |
| + String exponential = _shortenExponentialRepresentation( |
| + primitiveValue.toStringAsExponential()); |
| String decimal = primitiveValue.toString(); |
| return new jsAst.LiteralNumber( |
| (exponential.length < decimal.length) ? exponential : decimal); |
| @@ -230,7 +261,8 @@ class ConstantLiteralEmitter |
| } else if (value == -double.INFINITY) { |
| return js("-1/0"); |
| } else { |
| - return new jsAst.LiteralNumber("$value"); |
| + String shortened = _shortenExponentialRepresentation("$value"); |
| + return new jsAst.LiteralNumber(shortened); |
| } |
| } |