| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart2js.constant_system.js; | 5 library dart2js.constant_system.js; |
| 6 | 6 |
| 7 import '../compiler.dart' show Compiler; | 7 import '../compiler.dart' show Compiler; |
| 8 import '../constant_system_dart.dart'; | 8 import '../constant_system_dart.dart'; |
| 9 import '../constants/constant_system.dart'; | 9 import '../constants/constant_system.dart'; |
| 10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 double leftDouble = leftNum.primitiveValue.toDouble(); | 158 double leftDouble = leftNum.primitiveValue.toDouble(); |
| 159 double rightDouble = rightNum.primitiveValue.toDouble(); | 159 double rightDouble = rightNum.primitiveValue.toDouble(); |
| 160 return new BoolConstantValue(leftDouble == rightDouble); | 160 return new BoolConstantValue(leftDouble == rightDouble); |
| 161 } | 161 } |
| 162 return result; | 162 return result; |
| 163 } | 163 } |
| 164 | 164 |
| 165 apply(left, right) => identical(left, right); | 165 apply(left, right) => identical(left, right); |
| 166 } | 166 } |
| 167 | 167 |
| 168 class JavaScriptRoundOperation implements UnaryOperation { |
| 169 const JavaScriptRoundOperation(); |
| 170 String get name => DART_CONSTANT_SYSTEM.round.name; |
| 171 ConstantValue fold(ConstantValue constant) { |
| 172 // Be careful to round() only values that do not throw on either the host or |
| 173 // target platform. |
| 174 ConstantValue tryToRound(num value) { |
| 175 // Due to differences between browsers, only 'round' easy cases. Avoid |
| 176 // cases where nudging the value up or down changes the answer. |
| 177 // 13 digits is safely within the ~15 digit precision of doubles. |
| 178 const severalULP = 0.0000000000001; |
| 179 // Use 'roundToDouble()' to avoid exceptions on rounding the nudged value. |
| 180 double rounded = value.roundToDouble(); |
| 181 double rounded1 = (value * (1.0 + severalULP)).roundToDouble(); |
| 182 double rounded2 = (value * (1.0 - severalULP)).roundToDouble(); |
| 183 if (rounded != rounded1 || rounded != rounded2) return null; |
| 184 return JAVA_SCRIPT_CONSTANT_SYSTEM |
| 185 .convertToJavaScriptConstant(new IntConstantValue(value.round())); |
| 186 } |
| 187 |
| 188 if (constant.isInt) { |
| 189 IntConstantValue intConstant = constant; |
| 190 int value = intConstant.primitiveValue; |
| 191 if (value >= -double.MAX_FINITE && value <= double.MAX_FINITE) { |
| 192 return tryToRound(value); |
| 193 } |
| 194 } |
| 195 if (constant.isDouble) { |
| 196 DoubleConstantValue doubleConstant = constant; |
| 197 double value = doubleConstant.primitiveValue; |
| 198 // NaN and infinities will throw. |
| 199 if (value.isNaN) return null; |
| 200 if (value.isInfinite) return null; |
| 201 return tryToRound(value); |
| 202 } |
| 203 return null; |
| 204 } |
| 205 } |
| 206 |
| 168 /** | 207 /** |
| 169 * Constant system following the semantics for Dart code that has been | 208 * Constant system following the semantics for Dart code that has been |
| 170 * compiled to JavaScript. | 209 * compiled to JavaScript. |
| 171 */ | 210 */ |
| 172 class JavaScriptConstantSystem extends ConstantSystem { | 211 class JavaScriptConstantSystem extends ConstantSystem { |
| 173 final int BITS31 = 0x8FFFFFFF; | |
| 174 final int BITS32 = 0xFFFFFFFF; | 212 final int BITS32 = 0xFFFFFFFF; |
| 175 | 213 |
| 176 final add = const JavaScriptAddOperation(); | 214 final add = const JavaScriptAddOperation(); |
| 177 final bitAnd = const JavaScriptBinaryBitOperation(const BitAndOperation()); | 215 final bitAnd = const JavaScriptBinaryBitOperation(const BitAndOperation()); |
| 178 final bitNot = const JavaScriptBitNotOperation(); | 216 final bitNot = const JavaScriptBitNotOperation(); |
| 179 final bitOr = const JavaScriptBinaryBitOperation(const BitOrOperation()); | 217 final bitOr = const JavaScriptBinaryBitOperation(const BitOrOperation()); |
| 180 final bitXor = const JavaScriptBinaryBitOperation(const BitXorOperation()); | 218 final bitXor = const JavaScriptBinaryBitOperation(const BitXorOperation()); |
| 181 final booleanAnd = const BooleanAndOperation(); | 219 final booleanAnd = const BooleanAndOperation(); |
| 182 final booleanOr = const BooleanOrOperation(); | 220 final booleanOr = const BooleanOrOperation(); |
| 183 final divide = | 221 final divide = |
| (...skipping 12 matching lines...) Expand all Loading... |
| 196 final negate = const JavaScriptNegateOperation(); | 234 final negate = const JavaScriptNegateOperation(); |
| 197 final not = const NotOperation(); | 235 final not = const NotOperation(); |
| 198 final shiftLeft = | 236 final shiftLeft = |
| 199 const JavaScriptBinaryBitOperation(const ShiftLeftOperation()); | 237 const JavaScriptBinaryBitOperation(const ShiftLeftOperation()); |
| 200 final shiftRight = const JavaScriptShiftRightOperation(); | 238 final shiftRight = const JavaScriptShiftRightOperation(); |
| 201 final subtract = | 239 final subtract = |
| 202 const JavaScriptBinaryArithmeticOperation(const SubtractOperation()); | 240 const JavaScriptBinaryArithmeticOperation(const SubtractOperation()); |
| 203 final truncatingDivide = const JavaScriptBinaryArithmeticOperation( | 241 final truncatingDivide = const JavaScriptBinaryArithmeticOperation( |
| 204 const TruncatingDivideOperation()); | 242 const TruncatingDivideOperation()); |
| 205 final codeUnitAt = const CodeUnitAtRuntimeOperation(); | 243 final codeUnitAt = const CodeUnitAtRuntimeOperation(); |
| 244 final round = const JavaScriptRoundOperation(); |
| 206 | 245 |
| 207 const JavaScriptConstantSystem(); | 246 const JavaScriptConstantSystem(); |
| 208 | 247 |
| 209 /** | 248 /** |
| 210 * Returns true if [value] will turn into NaN or infinity | 249 * Returns true if [value] will turn into NaN or infinity |
| 211 * at runtime. | 250 * at runtime. |
| 212 */ | 251 */ |
| 213 bool integerBecomesNanOrInfinity(int value) { | 252 bool integerBecomesNanOrInfinity(int value) { |
| 214 double doubleValue = value.toDouble(); | 253 double doubleValue = value.toDouble(); |
| 215 return doubleValue.isNaN || doubleValue.isInfinite; | 254 return doubleValue.isNaN || doubleValue.isInfinite; |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 result.add(keyList); | 439 result.add(keyList); |
| 401 } else { | 440 } else { |
| 402 // Add the keys individually to avoid generating an unused list constant | 441 // Add the keys individually to avoid generating an unused list constant |
| 403 // for the keys. | 442 // for the keys. |
| 404 result.addAll(keys); | 443 result.addAll(keys); |
| 405 } | 444 } |
| 406 result.addAll(values); | 445 result.addAll(values); |
| 407 return result; | 446 return result; |
| 408 } | 447 } |
| 409 } | 448 } |
| OLD | NEW |