Chromium Code Reviews| 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 part of dart2js; | 5 part of dart2js; |
| 6 | 6 |
| 7 const DART_CONSTANT_SYSTEM = const DartConstantSystem(); | 7 const DART_CONSTANT_SYSTEM = const DartConstantSystem(); |
| 8 | 8 |
| 9 class BitNotOperation implements UnaryOperation { | 9 class BitNotOperation implements UnaryOperation { |
| 10 final String name = '~'; | 10 final String name = '~'; |
| 11 bool isUserDefinable() => true; | |
| 12 const BitNotOperation(); | 11 const BitNotOperation(); |
| 13 Constant fold(Constant constant) { | 12 Constant fold(Constant constant) { |
| 14 if (constant.isInt()) { | 13 if (constant.isInt()) { |
| 15 IntConstant intConstant = constant; | 14 IntConstant intConstant = constant; |
| 16 return DART_CONSTANT_SYSTEM.createInt(~intConstant.value); | 15 return DART_CONSTANT_SYSTEM.createInt(~intConstant.value); |
| 17 } | 16 } |
| 18 return null; | 17 return null; |
| 19 } | 18 } |
| 20 apply(value) => ~value; | |
|
Johnni Winther
2013/12/03 11:52:31
Remove only together with UnaryOperation.apply.
| |
| 21 } | 19 } |
| 22 | 20 |
| 23 class NegateOperation implements UnaryOperation { | 21 class NegateOperation implements UnaryOperation { |
| 24 final String name = 'negate'; | 22 final String name = 'negate'; |
| 25 bool isUserDefinable() => true; | |
| 26 const NegateOperation(); | 23 const NegateOperation(); |
| 27 Constant fold(Constant constant) { | 24 Constant fold(Constant constant) { |
| 28 if (constant.isInt()) { | 25 if (constant.isInt()) { |
| 29 IntConstant intConstant = constant; | 26 IntConstant intConstant = constant; |
| 30 return DART_CONSTANT_SYSTEM.createInt(-intConstant.value); | 27 return DART_CONSTANT_SYSTEM.createInt(-intConstant.value); |
| 31 } | 28 } |
| 32 if (constant.isDouble()) { | 29 if (constant.isDouble()) { |
| 33 DoubleConstant doubleConstant = constant; | 30 DoubleConstant doubleConstant = constant; |
| 34 return DART_CONSTANT_SYSTEM.createDouble(-doubleConstant.value); | 31 return DART_CONSTANT_SYSTEM.createDouble(-doubleConstant.value); |
| 35 } | 32 } |
| 36 return null; | 33 return null; |
| 37 } | 34 } |
| 38 apply(value) => -value; | |
|
Johnni Winther
2013/12/03 11:52:31
Remove only together with UnaryOperation.apply.
| |
| 39 } | 35 } |
| 40 | 36 |
| 41 class NotOperation implements UnaryOperation { | 37 class NotOperation implements UnaryOperation { |
| 42 final String name = '!'; | 38 final String name = '!'; |
| 43 bool isUserDefinable() => true; | |
| 44 const NotOperation(); | 39 const NotOperation(); |
| 45 Constant fold(Constant constant) { | 40 Constant fold(Constant constant) { |
| 46 if (constant.isBool()) { | 41 if (constant.isBool()) { |
| 47 BoolConstant boolConstant = constant; | 42 BoolConstant boolConstant = constant; |
| 48 return DART_CONSTANT_SYSTEM.createBool(!boolConstant.value); | 43 return DART_CONSTANT_SYSTEM.createBool(!boolConstant.value); |
| 49 } | 44 } |
| 50 return null; | 45 return null; |
| 51 } | 46 } |
| 52 apply(value) => !value; | |
|
Johnni Winther
2013/12/03 11:52:31
Remove only together with UnaryOperation.apply.
| |
| 53 } | 47 } |
| 54 | 48 |
| 55 /** | 49 /** |
| 56 * Operations that only work if both arguments are integers. | 50 * Operations that only work if both arguments are integers. |
| 57 */ | 51 */ |
| 58 abstract class BinaryBitOperation implements BinaryOperation { | 52 abstract class BinaryBitOperation implements BinaryOperation { |
| 59 bool isUserDefinable() => true; | |
| 60 const BinaryBitOperation(); | 53 const BinaryBitOperation(); |
| 61 Constant fold(Constant left, Constant right) { | 54 Constant fold(Constant left, Constant right) { |
| 62 if (left.isInt() && right.isInt()) { | 55 if (left.isInt() && right.isInt()) { |
| 63 IntConstant leftInt = left; | 56 IntConstant leftInt = left; |
| 64 IntConstant rightInt = right; | 57 IntConstant rightInt = right; |
| 65 int resultValue = foldInts(leftInt.value, rightInt.value); | 58 int resultValue = foldInts(leftInt.value, rightInt.value); |
| 66 if (resultValue == null) return null; | 59 if (resultValue == null) return null; |
| 67 return DART_CONSTANT_SYSTEM.createInt(resultValue); | 60 return DART_CONSTANT_SYSTEM.createInt(resultValue); |
| 68 } | 61 } |
| 69 return null; | 62 return null; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 109 final String name = '>>'; | 102 final String name = '>>'; |
| 110 const ShiftRightOperation(); | 103 const ShiftRightOperation(); |
| 111 int foldInts(int left, int right) { | 104 int foldInts(int left, int right) { |
| 112 if (right < 0) return null; | 105 if (right < 0) return null; |
| 113 return left >> right; | 106 return left >> right; |
| 114 } | 107 } |
| 115 apply(left, right) => left >> right; | 108 apply(left, right) => left >> right; |
| 116 } | 109 } |
| 117 | 110 |
| 118 abstract class BinaryBoolOperation implements BinaryOperation { | 111 abstract class BinaryBoolOperation implements BinaryOperation { |
| 119 bool isUserDefinable() => false; | |
| 120 const BinaryBoolOperation(); | 112 const BinaryBoolOperation(); |
| 121 Constant fold(Constant left, Constant right) { | 113 Constant fold(Constant left, Constant right) { |
| 122 if (left.isBool() && right.isBool()) { | 114 if (left.isBool() && right.isBool()) { |
| 123 BoolConstant leftBool = left; | 115 BoolConstant leftBool = left; |
| 124 BoolConstant rightBool = right; | 116 BoolConstant rightBool = right; |
| 125 bool resultValue = foldBools(leftBool.value, rightBool.value); | 117 bool resultValue = foldBools(leftBool.value, rightBool.value); |
| 126 return DART_CONSTANT_SYSTEM.createBool(resultValue); | 118 return DART_CONSTANT_SYSTEM.createBool(resultValue); |
| 127 } | 119 } |
| 128 return null; | 120 return null; |
| 129 } | 121 } |
| 130 | 122 |
| 131 bool foldBools(bool left, bool right); | 123 bool foldBools(bool left, bool right); |
| 132 } | 124 } |
| 133 | 125 |
| 134 class BooleanAndOperation extends BinaryBoolOperation { | 126 class BooleanAndOperation extends BinaryBoolOperation { |
| 135 final String name = '&&'; | 127 final String name = '&&'; |
| 136 const BooleanAndOperation(); | 128 const BooleanAndOperation(); |
| 137 bool foldBools(bool left, bool right) => left && right; | 129 bool foldBools(bool left, bool right) => left && right; |
| 138 apply(left, right) => left && right; | 130 apply(left, right) => left && right; |
| 139 } | 131 } |
| 140 | 132 |
| 141 class BooleanOrOperation extends BinaryBoolOperation { | 133 class BooleanOrOperation extends BinaryBoolOperation { |
| 142 final String name = '||'; | 134 final String name = '||'; |
| 143 const BooleanOrOperation(); | 135 const BooleanOrOperation(); |
| 144 bool foldBools(bool left, bool right) => left || right; | 136 bool foldBools(bool left, bool right) => left || right; |
| 145 apply(left, right) => left || right; | 137 apply(left, right) => left || right; |
| 146 } | 138 } |
| 147 | 139 |
| 148 abstract class ArithmeticNumOperation implements BinaryOperation { | 140 abstract class ArithmeticNumOperation implements BinaryOperation { |
| 149 bool isUserDefinable() => true; | |
| 150 const ArithmeticNumOperation(); | 141 const ArithmeticNumOperation(); |
| 151 Constant fold(Constant left, Constant right) { | 142 Constant fold(Constant left, Constant right) { |
| 152 if (left.isNum() && right.isNum()) { | 143 if (left.isNum() && right.isNum()) { |
| 153 NumConstant leftNum = left; | 144 NumConstant leftNum = left; |
| 154 NumConstant rightNum = right; | 145 NumConstant rightNum = right; |
| 155 num foldedValue; | 146 num foldedValue; |
| 156 if (left.isInt() && right.isInt()) { | 147 if (left.isInt() && right.isInt()) { |
| 157 foldedValue = foldInts(leftNum.value, rightNum.value); | 148 foldedValue = foldInts(leftNum.value, rightNum.value); |
| 158 } else { | 149 } else { |
| 159 foldedValue = foldNums(leftNum.value, rightNum.value); | 150 foldedValue = foldNums(leftNum.value, rightNum.value); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 221 class DivideOperation extends ArithmeticNumOperation { | 212 class DivideOperation extends ArithmeticNumOperation { |
| 222 final String name = '/'; | 213 final String name = '/'; |
| 223 const DivideOperation(); | 214 const DivideOperation(); |
| 224 num foldNums(num left, num right) => left / right; | 215 num foldNums(num left, num right) => left / right; |
| 225 bool isDivide() => true; | 216 bool isDivide() => true; |
| 226 apply(left, right) => left / right; | 217 apply(left, right) => left / right; |
| 227 } | 218 } |
| 228 | 219 |
| 229 class AddOperation implements BinaryOperation { | 220 class AddOperation implements BinaryOperation { |
| 230 final String name = '+'; | 221 final String name = '+'; |
| 231 bool isUserDefinable() => true; | |
| 232 const AddOperation(); | 222 const AddOperation(); |
| 233 Constant fold(Constant left, Constant right) { | 223 Constant fold(Constant left, Constant right) { |
| 234 if (left.isInt() && right.isInt()) { | 224 if (left.isInt() && right.isInt()) { |
| 235 IntConstant leftInt = left; | 225 IntConstant leftInt = left; |
| 236 IntConstant rightInt = right; | 226 IntConstant rightInt = right; |
| 237 int result = leftInt.value + rightInt.value; | 227 int result = leftInt.value + rightInt.value; |
| 238 return DART_CONSTANT_SYSTEM.createInt(result); | 228 return DART_CONSTANT_SYSTEM.createInt(result); |
| 239 } else if (left.isNum() && right.isNum()) { | 229 } else if (left.isNum() && right.isNum()) { |
| 240 NumConstant leftNum = left; | 230 NumConstant leftNum = left; |
| 241 NumConstant rightNum = right; | 231 NumConstant rightNum = right; |
| 242 double result = leftNum.value + rightNum.value; | 232 double result = leftNum.value + rightNum.value; |
| 243 return DART_CONSTANT_SYSTEM.createDouble(result); | 233 return DART_CONSTANT_SYSTEM.createDouble(result); |
| 244 } else { | 234 } else { |
| 245 return null; | 235 return null; |
| 246 } | 236 } |
| 247 } | 237 } |
| 248 apply(left, right) => left + right; | 238 apply(left, right) => left + right; |
| 249 } | 239 } |
| 250 | 240 |
| 251 abstract class RelationalNumOperation implements BinaryOperation { | 241 abstract class RelationalNumOperation implements BinaryOperation { |
| 252 bool isUserDefinable() => true; | |
| 253 const RelationalNumOperation(); | 242 const RelationalNumOperation(); |
| 254 Constant fold(Constant left, Constant right) { | 243 Constant fold(Constant left, Constant right) { |
| 255 if (left.isNum() && right.isNum()) { | 244 if (left.isNum() && right.isNum()) { |
| 256 NumConstant leftNum = left; | 245 NumConstant leftNum = left; |
| 257 NumConstant rightNum = right; | 246 NumConstant rightNum = right; |
| 258 bool foldedValue = foldNums(leftNum.value, rightNum.value); | 247 bool foldedValue = foldNums(leftNum.value, rightNum.value); |
| 259 assert(foldedValue != null); | 248 assert(foldedValue != null); |
| 260 return DART_CONSTANT_SYSTEM.createBool(foldedValue); | 249 return DART_CONSTANT_SYSTEM.createBool(foldedValue); |
| 261 } | 250 } |
| 262 } | 251 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 287 | 276 |
| 288 class GreaterEqualOperation extends RelationalNumOperation { | 277 class GreaterEqualOperation extends RelationalNumOperation { |
| 289 final String name = '>='; | 278 final String name = '>='; |
| 290 const GreaterEqualOperation(); | 279 const GreaterEqualOperation(); |
| 291 bool foldNums(num left, num right) => left >= right; | 280 bool foldNums(num left, num right) => left >= right; |
| 292 apply(left, right) => left >= right; | 281 apply(left, right) => left >= right; |
| 293 } | 282 } |
| 294 | 283 |
| 295 class EqualsOperation implements BinaryOperation { | 284 class EqualsOperation implements BinaryOperation { |
| 296 final String name = '=='; | 285 final String name = '=='; |
| 297 bool isUserDefinable() => true; | |
| 298 const EqualsOperation(); | 286 const EqualsOperation(); |
| 299 Constant fold(Constant left, Constant right) { | 287 Constant fold(Constant left, Constant right) { |
| 300 if (left.isNum() && right.isNum()) { | 288 if (left.isNum() && right.isNum()) { |
| 301 // Numbers need to be treated specially because: NaN != NaN, -0.0 == 0.0, | 289 // Numbers need to be treated specially because: NaN != NaN, -0.0 == 0.0, |
| 302 // and 1 == 1.0. | 290 // and 1 == 1.0. |
| 303 NumConstant leftNum = left; | 291 NumConstant leftNum = left; |
| 304 NumConstant rightNum = right; | 292 NumConstant rightNum = right; |
| 305 bool result = leftNum.value == rightNum.value; | 293 bool result = leftNum.value == rightNum.value; |
| 306 return DART_CONSTANT_SYSTEM.createBool(result); | 294 return DART_CONSTANT_SYSTEM.createBool(result); |
| 307 } | 295 } |
| 308 if (left.isConstructedObject()) { | 296 if (left.isConstructedObject()) { |
| 309 // Unless we know that the user-defined object does not implement the | 297 // Unless we know that the user-defined object does not implement the |
| 310 // equality operator we cannot fold here. | 298 // equality operator we cannot fold here. |
| 311 return null; | 299 return null; |
| 312 } | 300 } |
| 313 return DART_CONSTANT_SYSTEM.createBool(left == right); | 301 return DART_CONSTANT_SYSTEM.createBool(left == right); |
| 314 } | 302 } |
| 315 apply(left, right) => left == right; | 303 apply(left, right) => left == right; |
| 316 } | 304 } |
| 317 | 305 |
| 318 class IdentityOperation implements BinaryOperation { | 306 class IdentityOperation implements BinaryOperation { |
| 319 final String name = '==='; | 307 final String name = '==='; |
| 320 bool isUserDefinable() => false; | |
| 321 const IdentityOperation(); | 308 const IdentityOperation(); |
| 322 BoolConstant fold(Constant left, Constant right) { | 309 BoolConstant fold(Constant left, Constant right) { |
| 323 // In order to preserve runtime semantics which says that NaN !== NaN don't | 310 // In order to preserve runtime semantics which says that NaN !== NaN don't |
| 324 // constant fold NaN === NaN. Otherwise the output depends on inlined | 311 // constant fold NaN === NaN. Otherwise the output depends on inlined |
| 325 // variables and other optimizations. | 312 // variables and other optimizations. |
| 326 if (left.isNaN() && right.isNaN()) return null; | 313 if (left.isNaN() && right.isNaN()) return null; |
| 327 return DART_CONSTANT_SYSTEM.createBool(left == right); | 314 return DART_CONSTANT_SYSTEM.createBool(left == right); |
| 328 } | 315 } |
| 329 apply(left, right) => identical(left, right); | 316 apply(left, right) => identical(left, right); |
| 330 } | 317 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 370 bool isInt(Constant constant) => constant.isInt(); | 357 bool isInt(Constant constant) => constant.isInt(); |
| 371 bool isDouble(Constant constant) => constant.isDouble(); | 358 bool isDouble(Constant constant) => constant.isDouble(); |
| 372 bool isString(Constant constant) => constant.isString(); | 359 bool isString(Constant constant) => constant.isString(); |
| 373 bool isBool(Constant constant) => constant.isBool(); | 360 bool isBool(Constant constant) => constant.isBool(); |
| 374 bool isNull(Constant constant) => constant.isNull(); | 361 bool isNull(Constant constant) => constant.isNull(); |
| 375 | 362 |
| 376 bool isSubtype(Compiler compiler, DartType s, DartType t) { | 363 bool isSubtype(Compiler compiler, DartType s, DartType t) { |
| 377 return compiler.types.isSubtype(s, t); | 364 return compiler.types.isSubtype(s, t); |
| 378 } | 365 } |
| 379 } | 366 } |
| OLD | NEW |