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 |