Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart

Issue 958603002: Added VariableUse expression to tree IR. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated docs regarding catch parameters Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library tree_ir_nodes; 5 library tree_ir_nodes;
6 6
7 import '../constants/expressions.dart'; 7 import '../constants/expressions.dart';
8 import '../constants/values.dart' as values; 8 import '../constants/values.dart' as values;
9 import '../dart_types.dart' show DartType, GenericType; 9 import '../dart_types.dart' show DartType, GenericType;
10 import '../elements/elements.dart'; 10 import '../elements/elements.dart';
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 /// Number of [Break] or [Continue] statements that target this label. 77 /// Number of [Break] or [Continue] statements that target this label.
78 /// The [Break] constructor will increment this automatically, but the 78 /// The [Break] constructor will increment this automatically, but the
79 /// counter must be decremented by hand when a [Break] becomes orphaned. 79 /// counter must be decremented by hand when a [Break] becomes orphaned.
80 int useCount = 0; 80 int useCount = 0;
81 81
82 /// The [LabeledStatement] or [WhileTrue] binding this label. 82 /// The [LabeledStatement] or [WhileTrue] binding this label.
83 JumpTarget binding; 83 JumpTarget binding;
84 } 84 }
85 85
86 /** 86 /**
87 * Variables are [Expression]s. 87 * A local variable in the tree IR.
88 *
89 * All tree IR variables are mutable, and may in Dart-mode be referenced inside
90 * nested functions.
91 *
92 * To use a variable as an expression, reference it from a [VariableUse], with
93 * one [VariableUse] per expression.
94 *
95 * [Variable]s are reference counted. The node constructors [VariableUse],
96 * [Assign], [FunctionDefinition], and [Try] automatically update the reference
97 * count for their variables, but when transforming the tree, the transformer
98 * is responsible for updating reference counts.
88 */ 99 */
89 class Variable extends Expression { 100 class Variable extends Node {
90 /// Function that declares this variable. 101 /// Function that declares this variable.
91 ExecutableElement host; 102 ExecutableElement host;
92 103
93 /// [Entity] used for synthesizing a name for the variable. 104 /// [Entity] used for synthesizing a name for the variable.
94 /// Different variables may have the same entity. May be null. 105 /// Different variables may have the same entity. May be null.
95 Entity element; 106 Entity element;
96 107
108 /// Number of places where this variable occurs in a [VariableUse].
97 int readCount = 0; 109 int readCount = 0;
98 110
99 /// Number of places where this variable occurs as: 111 /// Number of places where this variable occurs as:
100 /// - left-hand of an [Assign] 112 /// - left-hand of an [Assign]
101 /// - left-hand of a [FunctionDeclaration] 113 /// - left-hand of a [FunctionDeclaration]
102 /// - parameter in a [FunctionDefinition] 114 /// - parameter in a [FunctionDefinition]
115 /// - catch parameter in a [Try]
103 int writeCount = 0; 116 int writeCount = 0;
104 117
105 Variable(this.host, this.element) { 118 Variable(this.host, this.element) {
106 assert(host != null); 119 assert(host != null);
107 } 120 }
121 }
108 122
109 accept(ExpressionVisitor visitor) => visitor.visitVariable(this); 123 /// Read the value of a variable.
110 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitVariable(this, arg); 124 class VariableUse extends Expression {
125 Variable variable;
126
127 /// Creates a use of [variable] and updates its `readCount`.
128 VariableUse(this.variable) {
129 variable.readCount++;
130 }
131
132 accept(ExpressionVisitor visitor) => visitor.visitVariableUse(this);
133 accept1(ExpressionVisitor1 visitor, arg) {
134 return visitor.visitVariableUse(this, arg);
135 }
111 } 136 }
112 137
113 /** 138 /**
114 * Common interface for invocations with arguments. 139 * Common interface for invocations with arguments.
115 */ 140 */
116 abstract class Invoke { 141 abstract class Invoke {
117 List<Expression> get arguments; 142 List<Expression> get arguments;
118 Selector get selector; 143 Selector get selector;
119 } 144 }
120 145
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 Statement next; 516 Statement next;
492 Variable variable; 517 Variable variable;
493 Expression definition; 518 Expression definition;
494 519
495 /// If true, this assignes to a fresh variable scoped to the [next] 520 /// If true, this assignes to a fresh variable scoped to the [next]
496 /// statement. 521 /// statement.
497 /// 522 ///
498 /// Variable declarations themselves are hoisted to function level. 523 /// Variable declarations themselves are hoisted to function level.
499 bool isDeclaration; 524 bool isDeclaration;
500 525
526 /// Creates an assignment to [variable] and updates its `writeCount`.
501 Assign(this.variable, this.definition, this.next, 527 Assign(this.variable, this.definition, this.next,
502 { this.isDeclaration: false }) { 528 { this.isDeclaration: false }) {
503 variable.writeCount++; 529 variable.writeCount++;
504 } 530 }
505 531
506 bool get hasExactlyOneUse => variable.readCount == 1; 532 bool get hasExactlyOneUse => variable.readCount == 1;
507 533
508 accept(StatementVisitor visitor) => visitor.visitAssign(this); 534 accept(StatementVisitor visitor) => visitor.visitAssign(this);
509 accept1(StatementVisitor1 visitor, arg) => visitor.visitAssign(this, arg); 535 accept1(StatementVisitor1 visitor, arg) => visitor.visitAssign(this, arg);
510 } 536 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 // LabeledStatement and EmptyStatement, the statement class names are not 590 // LabeledStatement and EmptyStatement, the statement class names are not
565 // suffixed with 'Statement'. 591 // suffixed with 'Statement'.
566 class Try extends Statement { 592 class Try extends Statement {
567 Statement tryBody; 593 Statement tryBody;
568 List<Variable> catchParameters; 594 List<Variable> catchParameters;
569 Statement catchBody; 595 Statement catchBody;
570 596
571 Statement get next => null; 597 Statement get next => null;
572 void set next(Statement s) => throw 'UNREACHABLE'; 598 void set next(Statement s) => throw 'UNREACHABLE';
573 599
574 Try(this.tryBody, this.catchParameters, this.catchBody); 600 Try(this.tryBody, this.catchParameters, this.catchBody) {
601 for (Variable variable in catchParameters) {
602 variable.writeCount++; // Being a catch parameter counts as a write.
603 }
604 }
575 605
576 accept(StatementVisitor visitor) => visitor.visitTry(this); 606 accept(StatementVisitor visitor) => visitor.visitTry(this);
577 accept1(StatementVisitor1 visitor, arg) { 607 accept1(StatementVisitor1 visitor, arg) {
578 return visitor.visitTry(this, arg); 608 return visitor.visitTry(this, arg);
579 } 609 }
580 } 610 }
581 611
582 abstract class ExecutableDefinition { 612 abstract class ExecutableDefinition {
583 ExecutableElement get element; 613 ExecutableElement get element;
584 Statement body; 614 Statement body;
(...skipping 29 matching lines...) Expand all
614 bool get hasInitializer => body != null; 644 bool get hasInitializer => body != null;
615 } 645 }
616 646
617 class FunctionDefinition extends Node implements ExecutableDefinition { 647 class FunctionDefinition extends Node implements ExecutableDefinition {
618 final FunctionElement element; 648 final FunctionElement element;
619 final List<Variable> parameters; 649 final List<Variable> parameters;
620 Statement body; 650 Statement body;
621 final List<ConstDeclaration> localConstants; 651 final List<ConstDeclaration> localConstants;
622 final List<ConstantExpression> defaultParameterValues; 652 final List<ConstantExpression> defaultParameterValues;
623 653
654 /// Creates a function definition and updates `writeCount` for [parameters].
624 FunctionDefinition(this.element, this.parameters, this.body, 655 FunctionDefinition(this.element, this.parameters, this.body,
625 this.localConstants, this.defaultParameterValues); 656 this.localConstants, this.defaultParameterValues) {
657 for (Variable param in parameters) {
658 param.writeCount++; // Being a parameter counts as a write.
659 }
660 }
626 661
627 /// Returns `true` if this function is abstract. 662 /// Returns `true` if this function is abstract.
628 /// 663 ///
629 /// If `true` [body] is `null` and [localConstants] is empty. 664 /// If `true` [body] is `null` and [localConstants] is empty.
630 bool get isAbstract => body == null; 665 bool get isAbstract => body == null;
631 applyPass(Pass pass) => pass.rewriteFunctionDefinition(this); 666 applyPass(Pass pass) => pass.rewriteFunctionDefinition(this);
632 } 667 }
633 668
634 abstract class Initializer implements Expression, DartSpecificNode {} 669 abstract class Initializer implements Expression, DartSpecificNode {}
635 670
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 Statement next; 747 Statement next;
713 748
714 SetField(this.object, this.field, this.value, this.next); 749 SetField(this.object, this.field, this.value, this.next);
715 750
716 accept(StatementVisitor visitor) => visitor.visitSetField(this); 751 accept(StatementVisitor visitor) => visitor.visitSetField(this);
717 accept1(StatementVisitor1 visitor, arg) => visitor.visitSetField(this, arg); 752 accept1(StatementVisitor1 visitor, arg) => visitor.visitSetField(this, arg);
718 } 753 }
719 754
720 abstract class ExpressionVisitor<E> { 755 abstract class ExpressionVisitor<E> {
721 E visitExpression(Expression e) => e.accept(this); 756 E visitExpression(Expression e) => e.accept(this);
722 E visitVariable(Variable node); 757 E visitVariableUse(VariableUse node);
723 E visitInvokeStatic(InvokeStatic node); 758 E visitInvokeStatic(InvokeStatic node);
724 E visitInvokeMethod(InvokeMethod node); 759 E visitInvokeMethod(InvokeMethod node);
725 E visitInvokeMethodDirectly(InvokeMethodDirectly node); 760 E visitInvokeMethodDirectly(InvokeMethodDirectly node);
726 E visitInvokeConstructor(InvokeConstructor node); 761 E visitInvokeConstructor(InvokeConstructor node);
727 E visitConcatenateStrings(ConcatenateStrings node); 762 E visitConcatenateStrings(ConcatenateStrings node);
728 E visitConstant(Constant node); 763 E visitConstant(Constant node);
729 E visitThis(This node); 764 E visitThis(This node);
730 E visitReifyTypeVar(ReifyTypeVar node); 765 E visitReifyTypeVar(ReifyTypeVar node);
731 E visitConditional(Conditional node); 766 E visitConditional(Conditional node);
732 E visitLogicalOperator(LogicalOperator node); 767 E visitLogicalOperator(LogicalOperator node);
733 E visitNot(Not node); 768 E visitNot(Not node);
734 E visitLiteralList(LiteralList node); 769 E visitLiteralList(LiteralList node);
735 E visitLiteralMap(LiteralMap node); 770 E visitLiteralMap(LiteralMap node);
736 E visitTypeOperator(TypeOperator node); 771 E visitTypeOperator(TypeOperator node);
737 E visitFunctionExpression(FunctionExpression node); 772 E visitFunctionExpression(FunctionExpression node);
738 E visitFieldInitializer(FieldInitializer node); 773 E visitFieldInitializer(FieldInitializer node);
739 E visitSuperInitializer(SuperInitializer node); 774 E visitSuperInitializer(SuperInitializer node);
740 E visitGetField(GetField node); 775 E visitGetField(GetField node);
741 E visitCreateBox(CreateBox node); 776 E visitCreateBox(CreateBox node);
742 E visitCreateInstance(CreateInstance node); 777 E visitCreateInstance(CreateInstance node);
743 } 778 }
744 779
745 abstract class ExpressionVisitor1<E, A> { 780 abstract class ExpressionVisitor1<E, A> {
746 E visitExpression(Expression e, A arg) => e.accept1(this, arg); 781 E visitExpression(Expression e, A arg) => e.accept1(this, arg);
747 E visitVariable(Variable node, A arg); 782 E visitVariableUse(VariableUse node, A arg);
748 E visitInvokeStatic(InvokeStatic node, A arg); 783 E visitInvokeStatic(InvokeStatic node, A arg);
749 E visitInvokeMethod(InvokeMethod node, A arg); 784 E visitInvokeMethod(InvokeMethod node, A arg);
750 E visitInvokeMethodDirectly(InvokeMethodDirectly node, A arg); 785 E visitInvokeMethodDirectly(InvokeMethodDirectly node, A arg);
751 E visitInvokeConstructor(InvokeConstructor node, A arg); 786 E visitInvokeConstructor(InvokeConstructor node, A arg);
752 E visitConcatenateStrings(ConcatenateStrings node, A arg); 787 E visitConcatenateStrings(ConcatenateStrings node, A arg);
753 E visitConstant(Constant node, A arg); 788 E visitConstant(Constant node, A arg);
754 E visitThis(This node, A arg); 789 E visitThis(This node, A arg);
755 E visitReifyTypeVar(ReifyTypeVar node, A arg); 790 E visitReifyTypeVar(ReifyTypeVar node, A arg);
756 E visitConditional(Conditional node, A arg); 791 E visitConditional(Conditional node, A arg);
757 E visitLogicalOperator(LogicalOperator node, A arg); 792 E visitLogicalOperator(LogicalOperator node, A arg);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 } 841 }
807 842
808 abstract class Visitor1<S, E, A> implements ExpressionVisitor1<E, A>, 843 abstract class Visitor1<S, E, A> implements ExpressionVisitor1<E, A>,
809 StatementVisitor1<S, A> { 844 StatementVisitor1<S, A> {
810 E visitExpression(Expression e, A arg) => e.accept1(this, arg); 845 E visitExpression(Expression e, A arg) => e.accept1(this, arg);
811 S visitStatement(Statement s, A arg) => s.accept1(this, arg); 846 S visitStatement(Statement s, A arg) => s.accept1(this, arg);
812 } 847 }
813 848
814 class RecursiveVisitor extends Visitor { 849 class RecursiveVisitor extends Visitor {
815 visitFunctionDefinition(FunctionDefinition node) { 850 visitFunctionDefinition(FunctionDefinition node) {
851 node.parameters.forEach(visitVariable);
816 visitStatement(node.body); 852 visitStatement(node.body);
817 } 853 }
818 854
819 visitVariable(Variable node) {} 855 visitVariable(Variable node) {}
820 856
857 visitVariableUse(VariableUse node) {
858 visitVariable(node.variable);
859 }
860
821 visitInvokeStatic(InvokeStatic node) { 861 visitInvokeStatic(InvokeStatic node) {
822 node.arguments.forEach(visitExpression); 862 node.arguments.forEach(visitExpression);
823 } 863 }
824 864
825 visitInvokeMethod(InvokeMethod node) { 865 visitInvokeMethod(InvokeMethod node) {
826 visitExpression(node.receiver); 866 visitExpression(node.receiver);
827 node.arguments.forEach(visitExpression); 867 node.arguments.forEach(visitExpression);
828 } 868 }
829 869
830 visitInvokeMethodDirectly(InvokeMethodDirectly node) { 870 visitInvokeMethodDirectly(InvokeMethodDirectly node) {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 visitStatement(node.next); 988 visitStatement(node.next);
949 } 989 }
950 990
951 visitCreateBox(CreateBox node) { 991 visitCreateBox(CreateBox node) {
952 } 992 }
953 993
954 visitCreateInstance(CreateInstance node) { 994 visitCreateInstance(CreateInstance node) {
955 node.arguments.forEach(visitExpression); 995 node.arguments.forEach(visitExpression);
956 } 996 }
957 } 997 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart ('k') | pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698