| 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 '../constants/expressions.dart'; | 6 import '../constants/expressions.dart'; |
| 7 import '../constants/values.dart' as values show ConstantValue; | 7 import '../constants/values.dart' as values show ConstantValue; |
| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 previous = current; | 57 previous = current; |
| 58 current = current.next; | 58 current = current.next; |
| 59 } while (current != null); | 59 } while (current != null); |
| 60 previous.next = firstRef; | 60 previous.next = firstRef; |
| 61 if (firstRef != null) firstRef.previous = previous; | 61 if (firstRef != null) firstRef.previous = previous; |
| 62 firstRef = other.firstRef; | 62 firstRef = other.firstRef; |
| 63 other.firstRef = null; | 63 other.firstRef = null; |
| 64 } | 64 } |
| 65 } | 65 } |
| 66 | 66 |
| 67 /// An expression that cannot throw or diverge and has no side-effects. | 67 /// A named value. |
| 68 /// All primitives are named using the identity of the [Primitive] object. | |
| 69 /// | 68 /// |
| 70 /// Primitives may allocate objects; this is not considered side-effect here. | 69 /// The identity of the [Primitive] object is the name of the value. |
| 71 /// | 70 /// The subclass describes how to compute the value. |
| 72 /// Although primitives may not mutate state, they may depend on state. | |
| 73 /// | 71 /// |
| 74 /// All primitives except [Parameter] must be bound by a [LetPrim]. | 72 /// All primitives except [Parameter] must be bound by a [LetPrim]. |
| 75 abstract class Primitive extends Definition<Primitive> { | 73 abstract class Primitive extends Definition<Primitive> { |
| 76 /// The [VariableElement] or [ParameterElement] from which the primitive | 74 /// The [VariableElement] or [ParameterElement] from which the primitive |
| 77 /// binding originated. | 75 /// binding originated. |
| 78 Entity hint; | 76 Entity hint; |
| 79 | 77 |
| 80 /// Use the given element as a hint for naming this primitive. | 78 /// Use the given element as a hint for naming this primitive. |
| 81 /// | 79 /// |
| 82 /// Has no effect if this primitive already has a non-null [element]. | 80 /// Has no effect if this primitive already has a non-null [element]. |
| 83 void useElementAsHint(Entity hint) { | 81 void useElementAsHint(Entity hint) { |
| 84 if (this.hint == null) { | 82 if (this.hint == null) { |
| 85 this.hint = hint; | 83 this.hint = hint; |
| 86 } | 84 } |
| 87 } | 85 } |
| 86 |
| 87 /// True if the primitive can be removed, assuming it has no uses |
| 88 /// (this getter does not check if there are any uses). |
| 89 /// |
| 90 /// False must be returned for primitives that may throw, diverge, or have |
| 91 /// observable side-effects. |
| 92 bool get isSafeForElimination => true; |
| 88 } | 93 } |
| 89 | 94 |
| 90 /// Operands to invocations and primitives are always variables. They point to | 95 /// Operands to invocations and primitives are always variables. They point to |
| 91 /// their definition and are doubly-linked into a list of occurrences. | 96 /// their definition and are doubly-linked into a list of occurrences. |
| 92 class Reference<T extends Definition<T>> { | 97 class Reference<T extends Definition<T>> { |
| 93 T definition; | 98 T definition; |
| 94 Reference<T> previous; | 99 Reference<T> previous; |
| 95 Reference<T> next; | 100 Reference<T> next; |
| 96 | 101 |
| 97 /// A pointer to the parent node. Is null until set by optimization passes. | 102 /// A pointer to the parent node. Is null until set by optimization passes. |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 | 605 |
| 601 Expression plug(Expression expr) { | 606 Expression plug(Expression expr) { |
| 602 assert(body == null); | 607 assert(body == null); |
| 603 return body = expr; | 608 return body = expr; |
| 604 } | 609 } |
| 605 | 610 |
| 606 accept(Visitor visitor) => visitor.visitSetField(this); | 611 accept(Visitor visitor) => visitor.visitSetField(this); |
| 607 } | 612 } |
| 608 | 613 |
| 609 /// Directly reads from a field on a given object. | 614 /// Directly reads from a field on a given object. |
| 615 /// |
| 616 /// The [object] must either be `null` or an object that has [field]. |
| 610 class GetField extends Primitive { | 617 class GetField extends Primitive { |
| 611 final Reference<Primitive> object; | 618 final Reference<Primitive> object; |
| 612 FieldElement field; | 619 FieldElement field; |
| 613 | 620 |
| 621 /// True if the receiver is known not to be null. |
| 622 // TODO(asgerf): This is a placeholder until we agree on how to track |
| 623 // side effects. |
| 624 bool objectIsNotNull = false; |
| 625 |
| 614 GetField(Primitive object, this.field) | 626 GetField(Primitive object, this.field) |
| 615 : this.object = new Reference<Primitive>(object); | 627 : this.object = new Reference<Primitive>(object); |
| 616 | 628 |
| 617 accept(Visitor visitor) => visitor.visitGetField(this); | 629 accept(Visitor visitor) => visitor.visitGetField(this); |
| 630 |
| 631 @override |
| 632 bool get isSafeForElimination => objectIsNotNull; |
| 618 } | 633 } |
| 619 | 634 |
| 620 /// Reads the value of a static field or tears off a static method. | 635 /// Reads the value of a static field or tears off a static method. |
| 621 class GetStatic extends Primitive { | 636 class GetStatic extends Primitive { |
| 622 /// Can be [FieldElement] or [FunctionElement]. | 637 /// Can be [FieldElement] or [FunctionElement]. |
| 623 final Element element; | 638 final Element element; |
| 624 final SourceInformation sourceInformation; | 639 final SourceInformation sourceInformation; |
| 625 | 640 |
| 626 GetStatic(this.element, this.sourceInformation); | 641 GetStatic(this.element, this.sourceInformation); |
| 627 | 642 |
| (...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 const RemovalVisitor(); | 1271 const RemovalVisitor(); |
| 1257 | 1272 |
| 1258 processReference(Reference reference) { | 1273 processReference(Reference reference) { |
| 1259 reference.unlink(); | 1274 reference.unlink(); |
| 1260 } | 1275 } |
| 1261 | 1276 |
| 1262 static void remove(Node node) { | 1277 static void remove(Node node) { |
| 1263 (const RemovalVisitor()).visit(node); | 1278 (const RemovalVisitor()).visit(node); |
| 1264 } | 1279 } |
| 1265 } | 1280 } |
| OLD | NEW |