| 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 abstract class ConstantVisitor<R> { | 7 abstract class ConstantVisitor<R> { |
| 8 R visitFunction(FunctionConstant constant); | 8 R visitFunction(FunctionConstant constant); |
| 9 R visitNull(NullConstant constant); | 9 R visitNull(NullConstant constant); |
| 10 R visitInt(IntConstant constant); | 10 R visitInt(IntConstant constant); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 bool isType() => false; | 41 bool isType() => false; |
| 42 bool isSentinel() => false; | 42 bool isSentinel() => false; |
| 43 bool isInterceptor() => false; | 43 bool isInterceptor() => false; |
| 44 | 44 |
| 45 bool isNaN() => false; | 45 bool isNaN() => false; |
| 46 bool isMinusZero() => false; | 46 bool isMinusZero() => false; |
| 47 | 47 |
| 48 // TODO(johnniwinther): Replace with a 'type' getter. | 48 // TODO(johnniwinther): Replace with a 'type' getter. |
| 49 DartType computeType(Compiler compiler); | 49 DartType computeType(Compiler compiler); |
| 50 | 50 |
| 51 ti.TypeMask computeMask(Compiler compiler); |
| 52 |
| 51 List<Constant> getDependencies(); | 53 List<Constant> getDependencies(); |
| 52 | 54 |
| 53 accept(ConstantVisitor visitor); | 55 accept(ConstantVisitor visitor); |
| 54 } | 56 } |
| 55 | 57 |
| 56 class FunctionConstant extends Constant { | 58 class FunctionConstant extends Constant { |
| 57 Element element; | 59 Element element; |
| 58 | 60 |
| 59 FunctionConstant(this.element); | 61 FunctionConstant(this.element); |
| 60 | 62 |
| 61 bool isFunction() => true; | 63 bool isFunction() => true; |
| 62 | 64 |
| 63 bool operator ==(var other) { | 65 bool operator ==(var other) { |
| 64 if (other is !FunctionConstant) return false; | 66 if (other is !FunctionConstant) return false; |
| 65 return identical(other.element, element); | 67 return identical(other.element, element); |
| 66 } | 68 } |
| 67 | 69 |
| 68 String toString() => element.toString(); | 70 String toString() => element.toString(); |
| 69 List<Constant> getDependencies() => const <Constant>[]; | 71 List<Constant> getDependencies() => const <Constant>[]; |
| 70 DartString toDartString() { | 72 DartString toDartString() { |
| 71 return new DartString.literal(element.name); | 73 return new DartString.literal(element.name); |
| 72 } | 74 } |
| 73 | 75 |
| 74 DartType computeType(Compiler compiler) { | 76 DartType computeType(Compiler compiler) { |
| 75 return compiler.functionClass.computeType(compiler); | 77 return compiler.functionClass.computeType(compiler); |
| 76 } | 78 } |
| 77 | 79 |
| 80 ti.TypeMask computeMask(Compiler compiler) { |
| 81 return compiler.typesTask.functionType; |
| 82 } |
| 83 |
| 78 int get hashCode => (17 * element.hashCode) & 0x7fffffff; | 84 int get hashCode => (17 * element.hashCode) & 0x7fffffff; |
| 79 | 85 |
| 80 accept(ConstantVisitor visitor) => visitor.visitFunction(this); | 86 accept(ConstantVisitor visitor) => visitor.visitFunction(this); |
| 81 } | 87 } |
| 82 | 88 |
| 83 abstract class PrimitiveConstant extends Constant { | 89 abstract class PrimitiveConstant extends Constant { |
| 84 get value; | 90 get value; |
| 85 const PrimitiveConstant(); | 91 const PrimitiveConstant(); |
| 86 bool isPrimitive() => true; | 92 bool isPrimitive() => true; |
| 87 | 93 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 106 | 112 |
| 107 factory NullConstant() => const NullConstant._internal(); | 113 factory NullConstant() => const NullConstant._internal(); |
| 108 const NullConstant._internal(); | 114 const NullConstant._internal(); |
| 109 bool isNull() => true; | 115 bool isNull() => true; |
| 110 get value => null; | 116 get value => null; |
| 111 | 117 |
| 112 DartType computeType(Compiler compiler) { | 118 DartType computeType(Compiler compiler) { |
| 113 return compiler.nullClass.computeType(compiler); | 119 return compiler.nullClass.computeType(compiler); |
| 114 } | 120 } |
| 115 | 121 |
| 122 ti.TypeMask computeMask(Compiler compiler) { |
| 123 return compiler.typesTask.nullType; |
| 124 } |
| 125 |
| 116 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { | 126 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { |
| 117 buffer.write(JsNull); | 127 buffer.write(JsNull); |
| 118 } | 128 } |
| 119 | 129 |
| 120 // The magic constant has no meaning. It is just a random value. | 130 // The magic constant has no meaning. It is just a random value. |
| 121 int get hashCode => 785965825; | 131 int get hashCode => 785965825; |
| 122 DartString toDartString() => const LiteralDartString("null"); | 132 DartString toDartString() => const LiteralDartString("null"); |
| 123 | 133 |
| 124 accept(ConstantVisitor visitor) => visitor.visitNull(this); | 134 accept(ConstantVisitor visitor) => visitor.visitNull(this); |
| 125 } | 135 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 145 case 8: return const IntConstant._internal(8); | 155 case 8: return const IntConstant._internal(8); |
| 146 case 9: return const IntConstant._internal(9); | 156 case 9: return const IntConstant._internal(9); |
| 147 case 10: return const IntConstant._internal(10); | 157 case 10: return const IntConstant._internal(10); |
| 148 case -1: return const IntConstant._internal(-1); | 158 case -1: return const IntConstant._internal(-1); |
| 149 case -2: return const IntConstant._internal(-2); | 159 case -2: return const IntConstant._internal(-2); |
| 150 default: return new IntConstant._internal(value); | 160 default: return new IntConstant._internal(value); |
| 151 } | 161 } |
| 152 } | 162 } |
| 153 const IntConstant._internal(this.value); | 163 const IntConstant._internal(this.value); |
| 154 bool isInt() => true; | 164 bool isInt() => true; |
| 165 bool isUInt31() => value >= 0 && value < (1 << 31); |
| 166 bool isUInt32() => value >= 0 && value < (1 << 32); |
| 155 | 167 |
| 156 DartType computeType(Compiler compiler) { | 168 DartType computeType(Compiler compiler) { |
| 157 return compiler.intClass.computeType(compiler); | 169 return compiler.intClass.computeType(compiler); |
| 158 } | 170 } |
| 159 | 171 |
| 172 ti.TypeMask computeMask(Compiler compiler) { |
| 173 if (isUInt31()) return compiler.typesTask.uint31Type; |
| 174 if (isUInt32()) return compiler.typesTask.uint32Type; |
| 175 return compiler.typesTask.intType; |
| 176 } |
| 177 |
| 160 // We have to override the equality operator so that ints and doubles are | 178 // We have to override the equality operator so that ints and doubles are |
| 161 // treated as separate constants. | 179 // treated as separate constants. |
| 162 // The is [:!IntConstant:] check at the beginning of the function makes sure | 180 // The is [:!IntConstant:] check at the beginning of the function makes sure |
| 163 // that we compare only equal to integer constants. | 181 // that we compare only equal to integer constants. |
| 164 bool operator ==(var other) { | 182 bool operator ==(var other) { |
| 165 if (other is !IntConstant) return false; | 183 if (other is !IntConstant) return false; |
| 166 IntConstant otherInt = other; | 184 IntConstant otherInt = other; |
| 167 return value == otherInt.value; | 185 return value == otherInt.value; |
| 168 } | 186 } |
| 169 | 187 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 193 const DoubleConstant._internal(this.value); | 211 const DoubleConstant._internal(this.value); |
| 194 bool isDouble() => true; | 212 bool isDouble() => true; |
| 195 bool isNaN() => value.isNaN; | 213 bool isNaN() => value.isNaN; |
| 196 // We need to check for the negative sign since -0.0 == 0.0. | 214 // We need to check for the negative sign since -0.0 == 0.0. |
| 197 bool isMinusZero() => value == 0.0 && value.isNegative; | 215 bool isMinusZero() => value == 0.0 && value.isNegative; |
| 198 | 216 |
| 199 DartType computeType(Compiler compiler) { | 217 DartType computeType(Compiler compiler) { |
| 200 return compiler.doubleClass.computeType(compiler); | 218 return compiler.doubleClass.computeType(compiler); |
| 201 } | 219 } |
| 202 | 220 |
| 221 ti.TypeMask computeMask(Compiler compiler) { |
| 222 return compiler.typesTask.doubleType; |
| 223 } |
| 224 |
| 203 bool operator ==(var other) { | 225 bool operator ==(var other) { |
| 204 if (other is !DoubleConstant) return false; | 226 if (other is !DoubleConstant) return false; |
| 205 DoubleConstant otherDouble = other; | 227 DoubleConstant otherDouble = other; |
| 206 double otherValue = otherDouble.value; | 228 double otherValue = otherDouble.value; |
| 207 if (value == 0.0 && otherValue == 0.0) { | 229 if (value == 0.0 && otherValue == 0.0) { |
| 208 return value.isNegative == otherValue.isNegative; | 230 return value.isNegative == otherValue.isNegative; |
| 209 } else if (value.isNaN) { | 231 } else if (value.isNaN) { |
| 210 return otherValue.isNaN; | 232 return otherValue.isNaN; |
| 211 } else { | 233 } else { |
| 212 return value == otherValue; | 234 return value == otherValue; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 223 factory BoolConstant(value) { | 245 factory BoolConstant(value) { |
| 224 return value ? new TrueConstant() : new FalseConstant(); | 246 return value ? new TrueConstant() : new FalseConstant(); |
| 225 } | 247 } |
| 226 const BoolConstant._internal(); | 248 const BoolConstant._internal(); |
| 227 bool isBool() => true; | 249 bool isBool() => true; |
| 228 | 250 |
| 229 DartType computeType(Compiler compiler) { | 251 DartType computeType(Compiler compiler) { |
| 230 return compiler.boolClass.computeType(compiler); | 252 return compiler.boolClass.computeType(compiler); |
| 231 } | 253 } |
| 232 | 254 |
| 255 ti.TypeMask computeMask(Compiler compiler) { |
| 256 return compiler.typesTask.boolType; |
| 257 } |
| 258 |
| 233 BoolConstant negate(); | 259 BoolConstant negate(); |
| 234 } | 260 } |
| 235 | 261 |
| 236 class TrueConstant extends BoolConstant { | 262 class TrueConstant extends BoolConstant { |
| 237 final bool value = true; | 263 final bool value = true; |
| 238 | 264 |
| 239 factory TrueConstant() => const TrueConstant._internal(); | 265 factory TrueConstant() => const TrueConstant._internal(); |
| 240 const TrueConstant._internal() : super._internal(); | 266 const TrueConstant._internal() : super._internal(); |
| 241 bool isTrue() => true; | 267 bool isTrue() => true; |
| 242 | 268 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 // DartString. | 305 // DartString. |
| 280 StringConstant(DartString value, this.node) | 306 StringConstant(DartString value, this.node) |
| 281 : this.value = value, | 307 : this.value = value, |
| 282 this.hashCode = value.slowToString().hashCode; | 308 this.hashCode = value.slowToString().hashCode; |
| 283 bool isString() => true; | 309 bool isString() => true; |
| 284 | 310 |
| 285 DartType computeType(Compiler compiler) { | 311 DartType computeType(Compiler compiler) { |
| 286 return compiler.stringClass.computeType(compiler); | 312 return compiler.stringClass.computeType(compiler); |
| 287 } | 313 } |
| 288 | 314 |
| 315 ti.TypeMask computeMask(Compiler compiler) { |
| 316 return compiler.typesTask.stringType; |
| 317 } |
| 318 |
| 289 bool operator ==(var other) { | 319 bool operator ==(var other) { |
| 290 if (other is !StringConstant) return false; | 320 if (other is !StringConstant) return false; |
| 291 StringConstant otherString = other; | 321 StringConstant otherString = other; |
| 292 return (hashCode == otherString.hashCode) && (value == otherString.value); | 322 return (hashCode == otherString.hashCode) && (value == otherString.value); |
| 293 } | 323 } |
| 294 | 324 |
| 295 DartString toDartString() => value; | 325 DartString toDartString() => value; |
| 296 int get length => value.length; | 326 int get length => value.length; |
| 297 | 327 |
| 298 accept(ConstantVisitor visitor) => visitor.visitString(this); | 328 accept(ConstantVisitor visitor) => visitor.visitString(this); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 316 final DartType representedType; | 346 final DartType representedType; |
| 317 | 347 |
| 318 TypeConstant(this.representedType, type) : super(type); | 348 TypeConstant(this.representedType, type) : super(type); |
| 319 | 349 |
| 320 bool isType() => true; | 350 bool isType() => true; |
| 321 | 351 |
| 322 bool operator ==(other) { | 352 bool operator ==(other) { |
| 323 return other is TypeConstant && representedType == other.representedType; | 353 return other is TypeConstant && representedType == other.representedType; |
| 324 } | 354 } |
| 325 | 355 |
| 356 ti.TypeMask computeMask(Compiler compiler) { |
| 357 return compiler.typesTask.typeType; |
| 358 } |
| 359 |
| 326 int get hashCode => representedType.hashCode * 13; | 360 int get hashCode => representedType.hashCode * 13; |
| 327 | 361 |
| 328 List<Constant> getDependencies() => const <Constant>[]; | 362 List<Constant> getDependencies() => const <Constant>[]; |
| 329 | 363 |
| 330 accept(ConstantVisitor visitor) => visitor.visitType(this); | 364 accept(ConstantVisitor visitor) => visitor.visitType(this); |
| 331 | 365 |
| 332 String toString() => 'TypeConstant(${Error.safeToString(representedType)})'; | 366 String toString() => 'TypeConstant(${Error.safeToString(representedType)})'; |
| 333 } | 367 } |
| 334 | 368 |
| 335 class ListConstant extends ObjectConstant { | 369 class ListConstant extends ObjectConstant { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 361 for (int i = 0; i < entries.length; i++) { | 395 for (int i = 0; i < entries.length; i++) { |
| 362 if (entries[i] != otherList.entries[i]) return false; | 396 if (entries[i] != otherList.entries[i]) return false; |
| 363 } | 397 } |
| 364 return true; | 398 return true; |
| 365 } | 399 } |
| 366 | 400 |
| 367 List<Constant> getDependencies() => entries; | 401 List<Constant> getDependencies() => entries; |
| 368 | 402 |
| 369 int get length => entries.length; | 403 int get length => entries.length; |
| 370 | 404 |
| 405 ti.TypeMask computeMask(Compiler compiler) { |
| 406 return compiler.typesTask.constListType; |
| 407 } |
| 408 |
| 371 accept(ConstantVisitor visitor) => visitor.visitList(this); | 409 accept(ConstantVisitor visitor) => visitor.visitList(this); |
| 372 | 410 |
| 373 String toString() { | 411 String toString() { |
| 374 StringBuffer sb = new StringBuffer(); | 412 StringBuffer sb = new StringBuffer(); |
| 375 sb.write('ListConstant(['); | 413 sb.write('ListConstant(['); |
| 376 for (int i = 0 ; i < entries.length ; i++) { | 414 for (int i = 0 ; i < entries.length ; i++) { |
| 377 if (i > 0) sb.write(','); | 415 if (i > 0) sb.write(','); |
| 378 sb.write(Error.safeToString(entries[i])); | 416 sb.write(Error.safeToString(entries[i])); |
| 379 } | 417 } |
| 380 sb.write('])'); | 418 sb.write('])'); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 static int computeHash(DartType type, List<Constant> values) { | 455 static int computeHash(DartType type, List<Constant> values) { |
| 418 // TODO(floitsch): create a better hash. | 456 // TODO(floitsch): create a better hash. |
| 419 int hash = 0; | 457 int hash = 0; |
| 420 for (Constant value in values) { | 458 for (Constant value in values) { |
| 421 hash ^= value.hashCode; | 459 hash ^= value.hashCode; |
| 422 } | 460 } |
| 423 hash ^= type.hashCode; | 461 hash ^= type.hashCode; |
| 424 return hash; | 462 return hash; |
| 425 } | 463 } |
| 426 | 464 |
| 465 ti.TypeMask computeMask(Compiler compiler) { |
| 466 return compiler.typesTask.constMapType; |
| 467 } |
| 468 |
| 427 bool operator ==(var other) { | 469 bool operator ==(var other) { |
| 428 if (other is !MapConstant) return false; | 470 if (other is !MapConstant) return false; |
| 429 MapConstant otherMap = other; | 471 MapConstant otherMap = other; |
| 430 if (hashCode != otherMap.hashCode) return false; | 472 if (hashCode != otherMap.hashCode) return false; |
| 431 if (type != other.type) return false; | 473 if (type != other.type) return false; |
| 432 if (keys != otherMap.keys) return false; | 474 if (keys != otherMap.keys) return false; |
| 433 for (int i = 0; i < values.length; i++) { | 475 for (int i = 0; i < values.length; i++) { |
| 434 if (values[i] != otherMap.values[i]) return false; | 476 if (values[i] != otherMap.values[i]) return false; |
| 435 } | 477 } |
| 436 return true; | 478 return true; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 } | 524 } |
| 483 | 525 |
| 484 int get hashCode => dispatchedType.hashCode * 43; | 526 int get hashCode => dispatchedType.hashCode * 43; |
| 485 | 527 |
| 486 List<Constant> getDependencies() => const <Constant>[]; | 528 List<Constant> getDependencies() => const <Constant>[]; |
| 487 | 529 |
| 488 accept(ConstantVisitor visitor) => visitor.visitInterceptor(this); | 530 accept(ConstantVisitor visitor) => visitor.visitInterceptor(this); |
| 489 | 531 |
| 490 DartType computeType(Compiler compiler) => compiler.types.dynamicType; | 532 DartType computeType(Compiler compiler) => compiler.types.dynamicType; |
| 491 | 533 |
| 534 ti.TypeMask computeMask(Compiler compiler) { |
| 535 return compiler.typesTask.nonNullType; |
| 536 } |
| 537 |
| 492 String toString() { | 538 String toString() { |
| 493 return 'InterceptorConstant(${Error.safeToString(dispatchedType)})'; | 539 return 'InterceptorConstant(${Error.safeToString(dispatchedType)})'; |
| 494 } | 540 } |
| 495 } | 541 } |
| 496 | 542 |
| 497 class ConstructedConstant extends ObjectConstant { | 543 class ConstructedConstant extends ObjectConstant { |
| 498 final List<Constant> fields; | 544 final List<Constant> fields; |
| 499 final int hashCode; | 545 final int hashCode; |
| 500 | 546 |
| 501 ConstructedConstant(DartType type, List<Constant> fields) | 547 ConstructedConstant(DartType type, List<Constant> fields) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 523 if (type != other.type) return false; | 569 if (type != other.type) return false; |
| 524 if (fields.length != other.fields.length) return false; | 570 if (fields.length != other.fields.length) return false; |
| 525 for (int i = 0; i < fields.length; i++) { | 571 for (int i = 0; i < fields.length; i++) { |
| 526 if (fields[i] != other.fields[i]) return false; | 572 if (fields[i] != other.fields[i]) return false; |
| 527 } | 573 } |
| 528 return true; | 574 return true; |
| 529 } | 575 } |
| 530 | 576 |
| 531 List<Constant> getDependencies() => fields; | 577 List<Constant> getDependencies() => fields; |
| 532 | 578 |
| 579 ti.TypeMask computeMask(Compiler compiler) { |
| 580 if (compiler.backend.isInterceptorClass(type.element)) { |
| 581 return compiler.typesTask.nonNullType; |
| 582 } |
| 583 return new ti.TypeMask.nonNullExact(type.element); |
| 584 } |
| 585 |
| 533 accept(ConstantVisitor visitor) => visitor.visitConstructed(this); | 586 accept(ConstantVisitor visitor) => visitor.visitConstructed(this); |
| 534 | 587 |
| 535 Map<Element, Constant> get fieldElements { | 588 Map<Element, Constant> get fieldElements { |
| 536 // TODO(ahe): Refactor constant system to store this information directly. | 589 // TODO(ahe): Refactor constant system to store this information directly. |
| 537 ClassElement classElement = type.element; | 590 ClassElement classElement = type.element; |
| 538 int count = 0; | 591 int count = 0; |
| 539 Map<Element, Constant> result = new Map<Element, Constant>(); | 592 Map<Element, Constant> result = new Map<Element, Constant>(); |
| 540 classElement.implementation.forEachInstanceField((holder, field) { | 593 classElement.implementation.forEachInstanceField((holder, field) { |
| 541 result[field] = fields[count++]; | 594 result[field] = fields[count++]; |
| 542 }, includeSuperAndInjectedMembers: true); | 595 }, includeSuperAndInjectedMembers: true); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 553 if (i > 0) sb.write(','); | 606 if (i > 0) sb.write(','); |
| 554 sb.write(Error.safeToString(field.name)); | 607 sb.write(Error.safeToString(field.name)); |
| 555 sb.write('='); | 608 sb.write('='); |
| 556 sb.write(Error.safeToString(value)); | 609 sb.write(Error.safeToString(value)); |
| 557 i++; | 610 i++; |
| 558 }); | 611 }); |
| 559 sb.write('))'); | 612 sb.write('))'); |
| 560 return sb.toString(); | 613 return sb.toString(); |
| 561 } | 614 } |
| 562 } | 615 } |
| OLD | NEW |