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

Unified 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, 10 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
index 2b37c176b1c5e4c80d67e887ab929d4f10d7ca8c..7306262863c6460876e6dd666b5ecba077ea8ec7 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
@@ -84,9 +84,20 @@ class Label {
}
/**
- * Variables are [Expression]s.
+ * A local variable in the tree IR.
+ *
+ * All tree IR variables are mutable, and may in Dart-mode be referenced inside
+ * nested functions.
+ *
+ * To use a variable as an expression, reference it from a [VariableUse], with
+ * one [VariableUse] per expression.
+ *
+ * [Variable]s are reference counted. The node constructors [VariableUse],
+ * [Assign], [FunctionDefinition], and [Try] automatically update the reference
+ * count for their variables, but when transforming the tree, the transformer
+ * is responsible for updating reference counts.
*/
-class Variable extends Expression {
+class Variable extends Node {
/// Function that declares this variable.
ExecutableElement host;
@@ -94,20 +105,34 @@ class Variable extends Expression {
/// Different variables may have the same entity. May be null.
Entity element;
+ /// Number of places where this variable occurs in a [VariableUse].
int readCount = 0;
/// Number of places where this variable occurs as:
/// - left-hand of an [Assign]
/// - left-hand of a [FunctionDeclaration]
/// - parameter in a [FunctionDefinition]
+ /// - catch parameter in a [Try]
int writeCount = 0;
Variable(this.host, this.element) {
assert(host != null);
}
+}
+
+/// Read the value of a variable.
+class VariableUse extends Expression {
+ Variable variable;
+
+ /// Creates a use of [variable] and updates its `readCount`.
+ VariableUse(this.variable) {
+ variable.readCount++;
+ }
- accept(ExpressionVisitor visitor) => visitor.visitVariable(this);
- accept1(ExpressionVisitor1 visitor, arg) => visitor.visitVariable(this, arg);
+ accept(ExpressionVisitor visitor) => visitor.visitVariableUse(this);
+ accept1(ExpressionVisitor1 visitor, arg) {
+ return visitor.visitVariableUse(this, arg);
+ }
}
/**
@@ -498,6 +523,7 @@ class Assign extends Statement {
/// Variable declarations themselves are hoisted to function level.
bool isDeclaration;
+ /// Creates an assignment to [variable] and updates its `writeCount`.
Assign(this.variable, this.definition, this.next,
{ this.isDeclaration: false }) {
variable.writeCount++;
@@ -571,7 +597,11 @@ class Try extends Statement {
Statement get next => null;
void set next(Statement s) => throw 'UNREACHABLE';
- Try(this.tryBody, this.catchParameters, this.catchBody);
+ Try(this.tryBody, this.catchParameters, this.catchBody) {
+ for (Variable variable in catchParameters) {
+ variable.writeCount++; // Being a catch parameter counts as a write.
+ }
+ }
accept(StatementVisitor visitor) => visitor.visitTry(this);
accept1(StatementVisitor1 visitor, arg) {
@@ -621,8 +651,13 @@ class FunctionDefinition extends Node implements ExecutableDefinition {
final List<ConstDeclaration> localConstants;
final List<ConstantExpression> defaultParameterValues;
+ /// Creates a function definition and updates `writeCount` for [parameters].
FunctionDefinition(this.element, this.parameters, this.body,
- this.localConstants, this.defaultParameterValues);
+ this.localConstants, this.defaultParameterValues) {
+ for (Variable param in parameters) {
+ param.writeCount++; // Being a parameter counts as a write.
+ }
+ }
/// Returns `true` if this function is abstract.
///
@@ -719,7 +754,7 @@ class SetField extends Statement implements JsSpecificNode {
abstract class ExpressionVisitor<E> {
E visitExpression(Expression e) => e.accept(this);
- E visitVariable(Variable node);
+ E visitVariableUse(VariableUse node);
E visitInvokeStatic(InvokeStatic node);
E visitInvokeMethod(InvokeMethod node);
E visitInvokeMethodDirectly(InvokeMethodDirectly node);
@@ -744,7 +779,7 @@ abstract class ExpressionVisitor<E> {
abstract class ExpressionVisitor1<E, A> {
E visitExpression(Expression e, A arg) => e.accept1(this, arg);
- E visitVariable(Variable node, A arg);
+ E visitVariableUse(VariableUse node, A arg);
E visitInvokeStatic(InvokeStatic node, A arg);
E visitInvokeMethod(InvokeMethod node, A arg);
E visitInvokeMethodDirectly(InvokeMethodDirectly node, A arg);
@@ -813,11 +848,16 @@ abstract class Visitor1<S, E, A> implements ExpressionVisitor1<E, A>,
class RecursiveVisitor extends Visitor {
visitFunctionDefinition(FunctionDefinition node) {
+ node.parameters.forEach(visitVariable);
visitStatement(node.body);
}
visitVariable(Variable node) {}
+ visitVariableUse(VariableUse node) {
+ visitVariable(node.variable);
+ }
+
visitInvokeStatic(InvokeStatic node) {
node.arguments.forEach(visitExpression);
}
« 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