| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library dart2js.ir_nodes; | 4 library dart2js.ir_nodes; |
| 5 | 5 |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 import '../constants/values.dart' as values; | 7 import '../constants/values.dart' as values; |
| 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
| 9 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; |
| 10 import '../io/source_information.dart' show SourceInformation; | 10 import '../io/source_information.dart' show SourceInformation; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 EffectiveUseIterable(this.primitive); | 154 EffectiveUseIterable(this.primitive); |
| 155 EffectiveUseIterator get iterator => new EffectiveUseIterator(primitive); | 155 EffectiveUseIterator get iterator => new EffectiveUseIterator(primitive); |
| 156 } | 156 } |
| 157 | 157 |
| 158 /// A named value. | 158 /// A named value. |
| 159 /// | 159 /// |
| 160 /// The identity of the [Primitive] object is the name of the value. | 160 /// The identity of the [Primitive] object is the name of the value. |
| 161 /// The subclass describes how to compute the value. | 161 /// The subclass describes how to compute the value. |
| 162 /// | 162 /// |
| 163 /// All primitives except [Parameter] must be bound by a [LetPrim]. | 163 /// All primitives except [Parameter] must be bound by a [LetPrim]. |
| 164 abstract class Primitive extends Definition<Primitive> { | 164 abstract class Primitive extends Variable<Primitive> { |
| 165 /// The [VariableElement] or [ParameterElement] from which the primitive | 165 /// The [VariableElement] or [ParameterElement] from which the primitive |
| 166 /// binding originated. | 166 /// binding originated. |
| 167 Entity hint; | 167 Entity hint; |
| 168 | 168 |
| 169 /// Use the given element as a hint for naming this primitive. | 169 /// Use the given element as a hint for naming this primitive. |
| 170 /// | 170 /// |
| 171 /// Has no effect if this primitive already has a non-null [element]. | 171 /// Has no effect if this primitive already has a non-null [element]. |
| 172 void useElementAsHint(Entity hint) { | 172 void useElementAsHint(Entity hint) { |
| 173 if (this.hint == null) { | 173 if (this.hint == null) { |
| 174 this.hint = hint; | 174 this.hint = hint; |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 /// occur in the [arguments] list, in normalized order. | 477 /// occur in the [arguments] list, in normalized order. |
| 478 /// | 478 /// |
| 479 /// Last in the [arguments] list, after the mandatory and optional arguments, | 479 /// Last in the [arguments] list, after the mandatory and optional arguments, |
| 480 /// the internal representation of each type argument occurs, unless it could | 480 /// the internal representation of each type argument occurs, unless it could |
| 481 /// be determined at build-time that the constructed class has no need for its | 481 /// be determined at build-time that the constructed class has no need for its |
| 482 /// runtime type information. | 482 /// runtime type information. |
| 483 /// | 483 /// |
| 484 /// Note that [InvokeConstructor] does it itself allocate an object. | 484 /// Note that [InvokeConstructor] does it itself allocate an object. |
| 485 /// The invoked constructor will do that using [CreateInstance]. | 485 /// The invoked constructor will do that using [CreateInstance]. |
| 486 class InvokeConstructor extends CallExpression { | 486 class InvokeConstructor extends CallExpression { |
| 487 final DartType type; | 487 final DartType dartType; |
| 488 final ConstructorElement target; | 488 final ConstructorElement target; |
| 489 final List<Reference<Primitive>> arguments; | 489 final List<Reference<Primitive>> arguments; |
| 490 final Reference<Continuation> continuation; | 490 final Reference<Continuation> continuation; |
| 491 final Selector selector; | 491 final Selector selector; |
| 492 final SourceInformation sourceInformation; | 492 final SourceInformation sourceInformation; |
| 493 | 493 |
| 494 InvokeConstructor(this.type, | 494 InvokeConstructor(this.dartType, |
| 495 this.target, | 495 this.target, |
| 496 this.selector, | 496 this.selector, |
| 497 List<Primitive> args, | 497 List<Primitive> args, |
| 498 Continuation cont, | 498 Continuation cont, |
| 499 this.sourceInformation) | 499 this.sourceInformation) |
| 500 : arguments = _referenceList(args), | 500 : arguments = _referenceList(args), |
| 501 continuation = new Reference<Continuation>(cont); | 501 continuation = new Reference<Continuation>(cont); |
| 502 | 502 |
| 503 accept(Visitor visitor) => visitor.visitInvokeConstructor(this); | 503 accept(Visitor visitor) => visitor.visitInvokeConstructor(this); |
| 504 } | 504 } |
| 505 | 505 |
| 506 /// An alias for [value] in a context where the value is known to satisfy | 506 /// An alias for [value] in a context where the value is known to satisfy |
| 507 /// [type]. | 507 /// [type]. |
| 508 /// | 508 /// |
| 509 /// Refinement nodes are inserted before the type propagator pass and removed | 509 /// Refinement nodes are inserted before the type propagator pass and removed |
| 510 /// afterwards, so as not to complicate passes that don't reason about types, | 510 /// afterwards, so as not to complicate passes that don't reason about types, |
| 511 /// but need to reason about value references being identical (i.e. referring | 511 /// but need to reason about value references being identical (i.e. referring |
| 512 /// to the same primitive). | 512 /// to the same primitive). |
| 513 class Refinement extends Primitive { | 513 class Refinement extends Primitive { |
| 514 Reference<Primitive> value; | 514 Reference<Primitive> value; |
| 515 final TypeMask type; | 515 final TypeMask refineType; |
| 516 | 516 |
| 517 Refinement(Primitive value, this.type) | 517 Refinement(Primitive value, this.refineType) |
| 518 : value = new Reference<Primitive>(value); | 518 : value = new Reference<Primitive>(value); |
| 519 | 519 |
| 520 bool get isSafeForElimination => true; | 520 bool get isSafeForElimination => true; |
| 521 bool get isSafeForReordering => false; | 521 bool get isSafeForReordering => false; |
| 522 | 522 |
| 523 accept(Visitor visitor) => visitor.visitRefinement(this); | 523 accept(Visitor visitor) => visitor.visitRefinement(this); |
| 524 | 524 |
| 525 Primitive get effectiveDefinition => value.definition.effectiveDefinition; | 525 Primitive get effectiveDefinition => value.definition.effectiveDefinition; |
| 526 } | 526 } |
| 527 | 527 |
| 528 /// An "is" type test. | 528 /// An "is" type test. |
| 529 /// | 529 /// |
| 530 /// Returns `true` if [value] is an instance of [type]. | 530 /// Returns `true` if [value] is an instance of [type]. |
| 531 /// | 531 /// |
| 532 /// [type] must not be the [Object], `dynamic` or [Null] types (though it might | 532 /// [type] must not be the [Object], `dynamic` or [Null] types (though it might |
| 533 /// be a type variable containing one of these types). This design is chosen | 533 /// be a type variable containing one of these types). This design is chosen |
| 534 /// to simplify code generation for type tests. | 534 /// to simplify code generation for type tests. |
| 535 class TypeTest extends Primitive { | 535 class TypeTest extends Primitive { |
| 536 Reference<Primitive> value; | 536 Reference<Primitive> value; |
| 537 final DartType type; | 537 final DartType dartType; |
| 538 | 538 |
| 539 /// If [type] is an [InterfaceType], this holds the internal representation of | 539 /// If [type] is an [InterfaceType], this holds the internal representation of |
| 540 /// the type arguments to [type]. Since these may reference type variables | 540 /// the type arguments to [type]. Since these may reference type variables |
| 541 /// from the enclosing class, they are not constant. | 541 /// from the enclosing class, they are not constant. |
| 542 /// | 542 /// |
| 543 /// If [type] is a [TypeVariableType], this is a singleton list with | 543 /// If [type] is a [TypeVariableType], this is a singleton list with |
| 544 /// the internal representation of the type held in that type variable. | 544 /// the internal representation of the type held in that type variable. |
| 545 /// | 545 /// |
| 546 /// If [type] is a [FunctionType], this is a singleton list with the | 546 /// If [type] is a [FunctionType], this is a singleton list with the |
| 547 /// internal representation of that type, | 547 /// internal representation of that type, |
| 548 /// | 548 /// |
| 549 /// Otherwise the list is empty. | 549 /// Otherwise the list is empty. |
| 550 final List<Reference<Primitive>> typeArguments; | 550 final List<Reference<Primitive>> typeArguments; |
| 551 | 551 |
| 552 TypeTest(Primitive value, | 552 TypeTest(Primitive value, |
| 553 this.type, | 553 this.dartType, |
| 554 List<Primitive> typeArguments) | 554 List<Primitive> typeArguments) |
| 555 : this.value = new Reference<Primitive>(value), | 555 : this.value = new Reference<Primitive>(value), |
| 556 this.typeArguments = _referenceList(typeArguments); | 556 this.typeArguments = _referenceList(typeArguments); |
| 557 | 557 |
| 558 accept(Visitor visitor) => visitor.visitTypeTest(this); | 558 accept(Visitor visitor) => visitor.visitTypeTest(this); |
| 559 | 559 |
| 560 bool get isSafeForElimination => true; | 560 bool get isSafeForElimination => true; |
| 561 bool get isSafeForReordering => true; | 561 bool get isSafeForReordering => true; |
| 562 } | 562 } |
| 563 | 563 |
| 564 /// An "as" type cast. | 564 /// An "as" type cast. |
| 565 /// | 565 /// |
| 566 /// If [value] is `null` or is an instance of [type], [continuation] is invoked | 566 /// If [value] is `null` or is an instance of [type], [continuation] is invoked |
| 567 /// with [value] as argument. Otherwise, a [CastError] is thrown. | 567 /// with [value] as argument. Otherwise, a [CastError] is thrown. |
| 568 /// | 568 /// |
| 569 /// Discussion: | 569 /// Discussion: |
| 570 /// The parameter to [continuation] is redundant since it will always equal | 570 /// The parameter to [continuation] is redundant since it will always equal |
| 571 /// [value], which is typically in scope in the continuation. However, it might | 571 /// [value], which is typically in scope in the continuation. However, it might |
| 572 /// simplify type propagation, since a better type can be computed for the | 572 /// simplify type propagation, since a better type can be computed for the |
| 573 /// continuation parameter without needing flow-sensitive analysis. | 573 /// continuation parameter without needing flow-sensitive analysis. |
| 574 class TypeCast extends CallExpression { | 574 class TypeCast extends CallExpression { |
| 575 Reference<Primitive> value; | 575 Reference<Primitive> value; |
| 576 final DartType type; | 576 final DartType dartType; |
| 577 | 577 |
| 578 /// See the corresponding field on [TypeTest]. | 578 /// See the corresponding field on [TypeTest]. |
| 579 final List<Reference<Primitive>> typeArguments; | 579 final List<Reference<Primitive>> typeArguments; |
| 580 final Reference<Continuation> continuation; | 580 final Reference<Continuation> continuation; |
| 581 | 581 |
| 582 TypeCast(Primitive value, | 582 TypeCast(Primitive value, |
| 583 this.type, | 583 this.dartType, |
| 584 List<Primitive> typeArguments, | 584 List<Primitive> typeArguments, |
| 585 Continuation cont) | 585 Continuation cont) |
| 586 : this.value = new Reference<Primitive>(value), | 586 : this.value = new Reference<Primitive>(value), |
| 587 this.typeArguments = _referenceList(typeArguments), | 587 this.typeArguments = _referenceList(typeArguments), |
| 588 this.continuation = new Reference<Continuation>(cont); | 588 this.continuation = new Reference<Continuation>(cont); |
| 589 | 589 |
| 590 accept(Visitor visitor) => visitor.visitTypeCast(this); | 590 accept(Visitor visitor) => visitor.visitTypeCast(this); |
| 591 } | 591 } |
| 592 | 592 |
| 593 /// Apply a built-in operator. | 593 /// Apply a built-in operator. |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1029 } | 1029 } |
| 1030 | 1030 |
| 1031 accept(Visitor visitor) => visitor.visitConstant(this); | 1031 accept(Visitor visitor) => visitor.visitConstant(this); |
| 1032 | 1032 |
| 1033 bool get isSafeForElimination => true; | 1033 bool get isSafeForElimination => true; |
| 1034 bool get isSafeForReordering => true; | 1034 bool get isSafeForReordering => true; |
| 1035 } | 1035 } |
| 1036 | 1036 |
| 1037 class LiteralList extends Primitive { | 1037 class LiteralList extends Primitive { |
| 1038 /// The List type being created; this is not the type argument. | 1038 /// The List type being created; this is not the type argument. |
| 1039 final InterfaceType type; | 1039 final InterfaceType dartType; |
| 1040 final List<Reference<Primitive>> values; | 1040 final List<Reference<Primitive>> values; |
| 1041 | 1041 |
| 1042 LiteralList(this.type, List<Primitive> values) | 1042 LiteralList(this.dartType, List<Primitive> values) |
| 1043 : this.values = _referenceList(values); | 1043 : this.values = _referenceList(values); |
| 1044 | 1044 |
| 1045 accept(Visitor visitor) => visitor.visitLiteralList(this); | 1045 accept(Visitor visitor) => visitor.visitLiteralList(this); |
| 1046 | 1046 |
| 1047 bool get isSafeForElimination => true; | 1047 bool get isSafeForElimination => true; |
| 1048 bool get isSafeForReordering => true; | 1048 bool get isSafeForReordering => true; |
| 1049 } | 1049 } |
| 1050 | 1050 |
| 1051 class LiteralMapEntry { | 1051 class LiteralMapEntry { |
| 1052 final Reference<Primitive> key; | 1052 final Reference<Primitive> key; |
| 1053 final Reference<Primitive> value; | 1053 final Reference<Primitive> value; |
| 1054 | 1054 |
| 1055 LiteralMapEntry(Primitive key, Primitive value) | 1055 LiteralMapEntry(Primitive key, Primitive value) |
| 1056 : this.key = new Reference<Primitive>(key), | 1056 : this.key = new Reference<Primitive>(key), |
| 1057 this.value = new Reference<Primitive>(value); | 1057 this.value = new Reference<Primitive>(value); |
| 1058 } | 1058 } |
| 1059 | 1059 |
| 1060 class LiteralMap extends Primitive { | 1060 class LiteralMap extends Primitive { |
| 1061 final InterfaceType type; | 1061 final InterfaceType dartType; |
| 1062 final List<LiteralMapEntry> entries; | 1062 final List<LiteralMapEntry> entries; |
| 1063 | 1063 |
| 1064 LiteralMap(this.type, this.entries); | 1064 LiteralMap(this.dartType, this.entries); |
| 1065 | 1065 |
| 1066 accept(Visitor visitor) => visitor.visitLiteralMap(this); | 1066 accept(Visitor visitor) => visitor.visitLiteralMap(this); |
| 1067 | 1067 |
| 1068 bool get isSafeForElimination => true; | 1068 bool get isSafeForElimination => true; |
| 1069 bool get isSafeForReordering => true; | 1069 bool get isSafeForReordering => true; |
| 1070 } | 1070 } |
| 1071 | 1071 |
| 1072 /// Currently unused. | 1072 /// Currently unused. |
| 1073 /// | 1073 /// |
| 1074 /// Nested functions (from Dart code) are translated to classes by closure | 1074 /// Nested functions (from Dart code) are translated to classes by closure |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1128 | 1128 |
| 1129 Continuation(this.parameters, {this.isRecursive: false}); | 1129 Continuation(this.parameters, {this.isRecursive: false}); |
| 1130 | 1130 |
| 1131 Continuation.retrn() | 1131 Continuation.retrn() |
| 1132 : parameters = <Parameter>[new Parameter(null)], | 1132 : parameters = <Parameter>[new Parameter(null)], |
| 1133 isRecursive = false; | 1133 isRecursive = false; |
| 1134 | 1134 |
| 1135 accept(Visitor visitor) => visitor.visitContinuation(this); | 1135 accept(Visitor visitor) => visitor.visitContinuation(this); |
| 1136 } | 1136 } |
| 1137 | 1137 |
| 1138 /// Common interface for [Primitive] and [MutableVariable]. |
| 1139 abstract class Variable<T extends Variable<T>> extends Definition<T> { |
| 1140 /// Type of value held in the variable. |
| 1141 /// |
| 1142 /// Is `null` until initialized by type propagation. |
| 1143 TypeMask type; |
| 1144 } |
| 1145 |
| 1138 /// Identifies a mutable variable. | 1146 /// Identifies a mutable variable. |
| 1139 class MutableVariable extends Definition { | 1147 class MutableVariable extends Variable<MutableVariable> { |
| 1140 Entity hint; | 1148 Entity hint; |
| 1141 | 1149 |
| 1142 MutableVariable(this.hint); | 1150 MutableVariable(this.hint); |
| 1143 | 1151 |
| 1144 accept(Visitor v) => v.visitMutableVariable(this); | 1152 accept(Visitor v) => v.visitMutableVariable(this); |
| 1145 } | 1153 } |
| 1146 | 1154 |
| 1147 /// A function definition, consisting of parameters and a body. | 1155 /// A function definition, consisting of parameters and a body. |
| 1148 /// | 1156 /// |
| 1149 /// There is an explicit parameter for the `this` argument, and a return | 1157 /// There is an explicit parameter for the `this` argument, and a return |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1733 /// Visit a just-deleted subterm and unlink all [Reference]s in it. | 1741 /// Visit a just-deleted subterm and unlink all [Reference]s in it. |
| 1734 class RemovalVisitor extends RecursiveVisitor { | 1742 class RemovalVisitor extends RecursiveVisitor { |
| 1735 processReference(Reference reference) { | 1743 processReference(Reference reference) { |
| 1736 reference.unlink(); | 1744 reference.unlink(); |
| 1737 } | 1745 } |
| 1738 | 1746 |
| 1739 static void remove(Node node) { | 1747 static void remove(Node node) { |
| 1740 (new RemovalVisitor()).visit(node); | 1748 (new RemovalVisitor()).visit(node); |
| 1741 } | 1749 } |
| 1742 } | 1750 } |
| OLD | NEW |