| 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 | 4 |
| 5 // IrNodes are kept in a separate library to have precise control over their | 5 // IrNodes are kept in a separate library to have precise control over their |
| 6 // dependencies on other parts of the system. | 6 // dependencies on other parts of the system. |
| 7 library dart2js.ir_nodes; | 7 library dart2js.ir_nodes; |
| 8 | 8 |
| 9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
| 10 import '../constants/values.dart' as values show ConstantValue; | 10 import '../constants/values.dart' as values show ConstantValue; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 | 117 |
| 118 Expression plug(Expression expr) { | 118 Expression plug(Expression expr) { |
| 119 assert(body == null); | 119 assert(body == null); |
| 120 return body = expr; | 120 return body = expr; |
| 121 } | 121 } |
| 122 | 122 |
| 123 accept(Visitor visitor) => visitor.visitLetPrim(this); | 123 accept(Visitor visitor) => visitor.visitLetPrim(this); |
| 124 } | 124 } |
| 125 | 125 |
| 126 | 126 |
| 127 /// Binding a continuation: 'let cont k(v) = E in E'. The bound continuation | 127 /// Binding continuations. |
| 128 /// is in scope in the body and the continuation parameter is in scope in the | 128 /// |
| 129 /// continuation body. | 129 /// let cont k0(v0 ...) = E0 |
| 130 /// During one-pass construction a LetCont with an empty continuation body is | 130 /// k1(v1 ...) = E1 |
| 131 /// used to represent the one-level context 'let cont k(v) = [] in E'. | 131 /// ... |
| 132 /// in E |
| 133 /// |
| 134 /// The bound continuations are in scope in the body and the continuation |
| 135 /// parameters are in scope in the respective continuation bodies. |
| 136 /// During one-pass construction a LetCont whose first continuation has an empty |
| 137 /// body is used to represent the one-level context |
| 138 /// 'let cont ... k(v) = [] ... in E'. |
| 132 class LetCont extends Expression implements InteriorNode { | 139 class LetCont extends Expression implements InteriorNode { |
| 133 Continuation continuation; | 140 List<Continuation> continuations; |
| 134 Expression body; | 141 Expression body; |
| 135 | 142 |
| 136 LetCont(this.continuation, this.body); | 143 LetCont(this.continuations, this.body); |
| 137 | 144 |
| 138 Expression plug(Expression expr) { | 145 Expression plug(Expression expr) { |
| 139 assert(continuation != null && continuation.body == null); | 146 assert(continuations != null && |
| 140 return continuation.body = expr; | 147 continuations.isNotEmpty && |
| 148 continuations.first.body == null); |
| 149 return continuations.first.body = expr; |
| 141 } | 150 } |
| 142 | 151 |
| 143 accept(Visitor visitor) => visitor.visitLetCont(this); | 152 accept(Visitor visitor) => visitor.visitLetCont(this); |
| 144 } | 153 } |
| 145 | 154 |
| 146 abstract class Invoke { | 155 abstract class Invoke { |
| 147 Selector get selector; | 156 Selector get selector; |
| 148 List<Reference<Primitive>> get arguments; | 157 List<Reference<Primitive>> get arguments; |
| 149 } | 158 } |
| 150 | 159 |
| 151 /// Represents a node with a child node, which can be accessed through the | 160 /// Represents a node with a child node, which can be accessed through the |
| 152 /// `body` member. A typical usage is when removing a node from the CPS graph: | 161 /// `body` member. A typical usage is when removing a node from the CPS graph: |
| 153 /// | 162 /// |
| 154 /// Node child = node.body; | 163 /// Node child = node.body; |
| 155 /// InteriorNode parent = node.parent; | 164 /// InteriorNode parent = node.parent; |
| 156 /// | 165 /// |
| 157 /// child.parent = parent; | 166 /// child.parent = parent; |
| 158 /// parent.body = child; | 167 /// parent.body = child; |
| 159 abstract class InteriorNode implements Node { | 168 abstract class InteriorNode extends Node { |
| 160 Expression body; | 169 Expression body; |
| 161 } | 170 } |
| 162 | 171 |
| 163 /// Invoke a static function or static field getter/setter. | 172 /// Invoke a static function or static field getter/setter. |
| 164 class InvokeStatic extends Expression implements Invoke { | 173 class InvokeStatic extends Expression implements Invoke { |
| 165 /// [FunctionElement] or [FieldElement]. | 174 /// [FunctionElement] or [FieldElement]. |
| 166 final Entity target; | 175 final Entity target; |
| 167 | 176 |
| 168 /** | 177 /** |
| 169 * The selector encodes how the function is invoked: number of positional | 178 * The selector encodes how the function is invoked: number of positional |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 accept(Visitor visitor) => visitor.visitParameter(this); | 610 accept(Visitor visitor) => visitor.visitParameter(this); |
| 602 } | 611 } |
| 603 | 612 |
| 604 /// Continuations are normally bound by 'let cont'. A continuation with one | 613 /// Continuations are normally bound by 'let cont'. A continuation with one |
| 605 /// parameter and no body is used to represent a function's return continuation. | 614 /// parameter and no body is used to represent a function's return continuation. |
| 606 /// The return continuation is bound by the Function, not by 'let cont'. | 615 /// The return continuation is bound by the Function, not by 'let cont'. |
| 607 class Continuation extends Definition<Continuation> implements InteriorNode { | 616 class Continuation extends Definition<Continuation> implements InteriorNode { |
| 608 final List<Parameter> parameters; | 617 final List<Parameter> parameters; |
| 609 Expression body = null; | 618 Expression body = null; |
| 610 | 619 |
| 620 // In addition to a parent pointer to the containing LetCont, continuations |
| 621 // have an index into the list of continuations bound by the LetCont. This |
| 622 // gives constant-time access to the continuation from the parent. |
| 623 int parent_index; |
| 624 |
| 611 // A continuation is recursive if it has any recursive invocations. | 625 // A continuation is recursive if it has any recursive invocations. |
| 612 bool isRecursive = false; | 626 bool isRecursive = false; |
| 613 | 627 |
| 614 bool get isReturnContinuation => body == null; | 628 bool get isReturnContinuation => body == null; |
| 615 | 629 |
| 616 Continuation(this.parameters); | 630 Continuation(this.parameters); |
| 617 | 631 |
| 618 Continuation.retrn() : parameters = <Parameter>[new Parameter(null)]; | 632 Continuation.retrn() : parameters = <Parameter>[new Parameter(null)]; |
| 619 | 633 |
| 620 accept(Visitor visitor) => visitor.visitContinuation(this); | 634 accept(Visitor visitor) => visitor.visitContinuation(this); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 class ClosureVariable extends Definition { | 679 class ClosureVariable extends Definition { |
| 666 /// Body of code that declares this closure variable. | 680 /// Body of code that declares this closure variable. |
| 667 ExecutableElement host; | 681 ExecutableElement host; |
| 668 Entity hint; | 682 Entity hint; |
| 669 | 683 |
| 670 ClosureVariable(this.host, this.hint); | 684 ClosureVariable(this.host, this.hint); |
| 671 | 685 |
| 672 accept(Visitor v) => v.visitClosureVariable(this); | 686 accept(Visitor v) => v.visitClosureVariable(this); |
| 673 } | 687 } |
| 674 | 688 |
| 675 class RunnableBody implements InteriorNode { | 689 class RunnableBody extends InteriorNode { |
| 676 Expression body; | 690 Expression body; |
| 677 final Continuation returnContinuation; | 691 final Continuation returnContinuation; |
| 678 Node parent; | |
| 679 RunnableBody(this.body, this.returnContinuation); | 692 RunnableBody(this.body, this.returnContinuation); |
| 680 accept(Visitor visitor) => visitor.visitRunnableBody(this); | 693 accept(Visitor visitor) => visitor.visitRunnableBody(this); |
| 681 } | 694 } |
| 682 | 695 |
| 683 /// A function definition, consisting of parameters and a body. The parameters | 696 /// A function definition, consisting of parameters and a body. The parameters |
| 684 /// include a distinguished continuation parameter. | 697 /// include a distinguished continuation parameter. |
| 685 class FunctionDefinition extends Node | 698 class FunctionDefinition extends Node |
| 686 implements ExecutableDefinition { | 699 implements ExecutableDefinition { |
| 687 final FunctionElement element; | 700 final FunctionElement element; |
| 688 /// Mixed list of [Parameter]s and [ClosureVariable]s. | 701 /// Mixed list of [Parameter]s and [ClosureVariable]s. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 715 | 728 |
| 716 /// Returns `true` if this function is abstract or external. | 729 /// Returns `true` if this function is abstract or external. |
| 717 /// | 730 /// |
| 718 /// If `true`, [body] and [returnContinuation] are `null` and [localConstants] | 731 /// If `true`, [body] and [returnContinuation] are `null` and [localConstants] |
| 719 /// is empty. | 732 /// is empty. |
| 720 bool get isAbstract => body == null; | 733 bool get isAbstract => body == null; |
| 721 } | 734 } |
| 722 | 735 |
| 723 abstract class Initializer extends Node {} | 736 abstract class Initializer extends Node {} |
| 724 | 737 |
| 725 class FieldInitializer implements Initializer { | 738 class FieldInitializer extends Initializer { |
| 726 final FieldElement element; | 739 final FieldElement element; |
| 727 final RunnableBody body; | 740 final RunnableBody body; |
| 728 Node parent; | |
| 729 | 741 |
| 730 FieldInitializer(this.element, this.body); | 742 FieldInitializer(this.element, this.body); |
| 731 accept(Visitor visitor) => visitor.visitFieldInitializer(this); | 743 accept(Visitor visitor) => visitor.visitFieldInitializer(this); |
| 732 } | 744 } |
| 733 | 745 |
| 734 class SuperInitializer implements Initializer { | 746 class SuperInitializer extends Initializer { |
| 735 final ConstructorElement target; | 747 final ConstructorElement target; |
| 736 final List<RunnableBody> arguments; | 748 final List<RunnableBody> arguments; |
| 737 final Selector selector; | 749 final Selector selector; |
| 738 Node parent; | |
| 739 SuperInitializer(this.target, this.arguments, this.selector); | 750 SuperInitializer(this.target, this.arguments, this.selector); |
| 740 accept(Visitor visitor) => visitor.visitSuperInitializer(this); | 751 accept(Visitor visitor) => visitor.visitSuperInitializer(this); |
| 741 } | 752 } |
| 742 | 753 |
| 743 class ConstructorDefinition extends FunctionDefinition { | 754 class ConstructorDefinition extends FunctionDefinition { |
| 744 final List<Initializer> initializers; | 755 final List<Initializer> initializers; |
| 745 | 756 |
| 746 ConstructorDefinition(ConstructorElement element, | 757 ConstructorDefinition(ConstructorElement element, |
| 747 List<Definition> parameters, | 758 List<Definition> parameters, |
| 748 RunnableBody body, | 759 RunnableBody body, |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 896 processLetPrim(LetPrim node) {} | 907 processLetPrim(LetPrim node) {} |
| 897 visitLetPrim(LetPrim node) { | 908 visitLetPrim(LetPrim node) { |
| 898 processLetPrim(node); | 909 processLetPrim(node); |
| 899 visit(node.primitive); | 910 visit(node.primitive); |
| 900 visit(node.body); | 911 visit(node.body); |
| 901 } | 912 } |
| 902 | 913 |
| 903 processLetCont(LetCont node) {} | 914 processLetCont(LetCont node) {} |
| 904 visitLetCont(LetCont node) { | 915 visitLetCont(LetCont node) { |
| 905 processLetCont(node); | 916 processLetCont(node); |
| 906 visit(node.continuation); | 917 node.continuations.forEach(visit); |
| 907 visit(node.body); | 918 visit(node.body); |
| 908 } | 919 } |
| 909 | 920 |
| 910 processInvokeStatic(InvokeStatic node) {} | 921 processInvokeStatic(InvokeStatic node) {} |
| 911 visitInvokeStatic(InvokeStatic node) { | 922 visitInvokeStatic(InvokeStatic node) { |
| 912 processInvokeStatic(node); | 923 processInvokeStatic(node); |
| 913 processReference(node.continuation); | 924 processReference(node.continuation); |
| 914 node.arguments.forEach(processReference); | 925 node.arguments.forEach(processReference); |
| 915 } | 926 } |
| 916 | 927 |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 allocate(param); | 1180 allocate(param); |
| 1170 } | 1181 } |
| 1171 } | 1182 } |
| 1172 } | 1183 } |
| 1173 | 1184 |
| 1174 void visitFieldInitializer(FieldInitializer node) { | 1185 void visitFieldInitializer(FieldInitializer node) { |
| 1175 visit(node.body.body); | 1186 visit(node.body.body); |
| 1176 } | 1187 } |
| 1177 | 1188 |
| 1178 void visitSuperInitializer(SuperInitializer node) { | 1189 void visitSuperInitializer(SuperInitializer node) { |
| 1179 node.arguments.forEach((RunnableBody argument) => visit(argument.body)); | 1190 node.arguments.forEach(visit); |
| 1180 } | 1191 } |
| 1181 | 1192 |
| 1182 void visitLetPrim(LetPrim node) { | 1193 void visitLetPrim(LetPrim node) { |
| 1183 visit(node.body); | 1194 visit(node.body); |
| 1184 release(node.primitive); | 1195 release(node.primitive); |
| 1185 visit(node.primitive); | 1196 visit(node.primitive); |
| 1186 } | 1197 } |
| 1187 | 1198 |
| 1188 void visitLetCont(LetCont node) { | 1199 void visitLetCont(LetCont node) { |
| 1189 visit(node.continuation); | 1200 node.continuations.forEach(visit); |
| 1190 visit(node.body); | 1201 visit(node.body); |
| 1191 } | 1202 } |
| 1192 | 1203 |
| 1193 void visitInvokeStatic(InvokeStatic node) { | 1204 void visitInvokeStatic(InvokeStatic node) { |
| 1194 node.arguments.forEach(visitReference); | 1205 node.arguments.forEach(visitReference); |
| 1195 } | 1206 } |
| 1196 | 1207 |
| 1197 void visitInvokeContinuation(InvokeContinuation node) { | 1208 void visitInvokeContinuation(InvokeContinuation node) { |
| 1198 node.arguments.forEach(visitReference); | 1209 node.arguments.forEach(visitReference); |
| 1199 } | 1210 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 | 1311 |
| 1301 void visitIdentical(Identical node) { | 1312 void visitIdentical(Identical node) { |
| 1302 visitReference(node.left); | 1313 visitReference(node.left); |
| 1303 visitReference(node.right); | 1314 visitReference(node.right); |
| 1304 } | 1315 } |
| 1305 | 1316 |
| 1306 void visitInterceptor(Interceptor node) { | 1317 void visitInterceptor(Interceptor node) { |
| 1307 visitReference(node.input); | 1318 visitReference(node.input); |
| 1308 } | 1319 } |
| 1309 } | 1320 } |
| OLD | NEW |