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

Unified Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart

Issue 1234753003: dart2js cps: Rewrite mutable variables to continuation parameters. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Add tests and fix an assertion Created 5 years, 5 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
Index: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
index 8c5bf34b55f808e940905dfae91c7e40c761d332..37e91fe15c09214d1a826163661a57e93dcd4d6c 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -36,10 +36,51 @@ abstract class Node {
/// invoke a [Continuation] with the result as argument. Alternatively, values
/// that can be obtained without side-effects, divergence, or throwing
/// exceptions can be built using a [LetPrim].
+///
+/// All subclasses implement exactly one of [CallExpression],
+/// [InteriorExpression], or [TailExpression].
abstract class Expression extends Node {
InteriorNode get parent; // Only InteriorNodes may contain expressions.
Expression plug(Expression expr) => throw 'impossible';
+
+ /// The next expression in the basic block.
+ ///
+ /// For [InteriorExpression]s this is the body, for [CallExpressions] it is
+ /// the body of the continuation, and for [TailExpressions] it is `null`.
+ Expression get next;
+}
+
+/// Represents a node with a child node, which can be accessed through the
+/// `body` member. A typical usage is when removing a node from the CPS graph:
+///
+/// Node child = node.body;
+/// InteriorNode parent = node.parent;
+///
+/// child.parent = parent;
+/// parent.body = child;
+abstract class InteriorNode extends Node {
+ Expression get body;
+ void set body(Expression body);
+}
+
+/// An expression with a subexpression as body.
+abstract class InteriorExpression extends Expression implements InteriorNode {
+ Expression get next => body;
+}
+
+/// An expression that passes a continuation to a call.
+abstract class CallExpression extends Expression {
+ Reference<Continuation> get continuation;
+ Expression get next => continuation.definition.body;
+}
+
+/// An expression without a continuation or a subexpression body.
+///
+/// These break straight-line control flow and can be throught of as ending a
+/// basic block.
+abstract class TailExpression extends Expression {
+ Expression get next => null;
}
/// The base class of things that variables can refer to: primitives,
@@ -147,7 +188,7 @@ class Reference<T extends Definition<T>> {
///
/// During one-pass construction a LetPrim with an empty body is used to
/// represent the one-hole context `let val x = V in []`.
-class LetPrim extends Expression implements InteriorNode {
+class LetPrim extends InteriorExpression {
Primitive primitive;
Expression body;
@@ -175,7 +216,7 @@ class LetPrim extends Expression implements InteriorNode {
/// During one-pass construction a LetCont whose first continuation has an empty
/// body is used to represent the one-hole context
/// `let cont ... k(v) = [] ... in E`.
-class LetCont extends Expression implements InteriorNode {
+class LetCont extends InteriorExpression {
List<Continuation> continuations;
Expression body;
@@ -206,7 +247,7 @@ class LetCont extends Expression implements InteriorNode {
// [LetHandler] differs from a [LetCont] binding in that it (1) has the
// runtime semantics of pushing/popping a handler from the dynamic exception
// handler stack and (2) it does not have any explicit invocations.
-class LetHandler extends Expression implements InteriorNode {
+class LetHandler extends InteriorExpression {
Continuation handler;
Expression body;
@@ -224,7 +265,7 @@ class LetHandler extends Expression implements InteriorNode {
/// to prevent unrestricted use of references to them. During one-pass
/// construction, a [LetMutable] with an empty body is use to represent the
/// one-hole context 'let mutable v = P in []'.
-class LetMutable extends Expression implements InteriorNode {
+class LetMutable extends InteriorExpression {
final MutableVariable variable;
final Reference<Primitive> value;
Expression body;
@@ -239,25 +280,6 @@ class LetMutable extends Expression implements InteriorNode {
accept(Visitor visitor) => visitor.visitLetMutable(this);
}
-abstract class Invoke implements Expression {
- Selector get selector;
- List<Reference<Primitive>> get arguments;
- Reference<Continuation> get continuation;
-}
-
-/// Represents a node with a child node, which can be accessed through the
-/// `body` member. A typical usage is when removing a node from the CPS graph:
-///
-/// Node child = node.body;
-/// InteriorNode parent = node.parent;
-///
-/// child.parent = parent;
-/// parent.body = child;
-abstract class InteriorNode extends Node {
- Expression get body;
- void set body(Expression body);
-}
-
/// Invoke a static function.
///
/// All optional arguments declared by [target] are passed in explicitly, and
@@ -266,7 +288,7 @@ abstract class InteriorNode extends Node {
/// Discussion:
/// All information in the [selector] is technically redundant; it will likely
/// be removed.
-class InvokeStatic extends Expression implements Invoke {
+class InvokeStatic extends CallExpression {
final FunctionElement target;
final Selector selector;
final List<Reference<Primitive>> arguments;
@@ -299,7 +321,7 @@ class InvokeStatic extends Expression implements Invoke {
///
/// The [selector] records the names of named arguments. The value of named
/// arguments occur at the end of the [arguments] list, in normalized order.
-class InvokeMethod extends Expression implements Invoke {
+class InvokeMethod extends CallExpression {
Reference<Primitive> receiver;
Selector selector;
TypeMask mask;
@@ -349,7 +371,7 @@ class InvokeMethod extends Expression implements Invoke {
///
/// All optional arguments declared by [target] are passed in explicitly, and
/// occur at the end of [arguments] list, in normalized order.
-class InvokeMethodDirectly extends Expression implements Invoke {
+class InvokeMethodDirectly extends CallExpression {
Reference<Primitive> receiver;
final FunctionElement target;
final Selector selector;
@@ -385,7 +407,7 @@ class InvokeMethodDirectly extends Expression implements Invoke {
///
/// Note that [InvokeConstructor] does it itself allocate an object.
/// The invoked constructor will do that using [CreateInstance].
-class InvokeConstructor extends Expression implements Invoke {
+class InvokeConstructor extends CallExpression {
final DartType type;
final ConstructorElement target;
final List<Reference<Primitive>> arguments;
@@ -451,7 +473,7 @@ class TypeTest extends Primitive {
/// [value], which is typically in scope in the continuation. However, it might
/// simplify type propagation, since a better type can be computed for the
/// continuation parameter without needing flow-sensitive analysis.
-class TypeCast extends Expression {
+class TypeCast extends CallExpression {
Reference<Primitive> value;
final DartType type;
@@ -490,7 +512,7 @@ class ApplyBuiltinOperator extends Primitive {
///
/// Throw is an expression, i.e., it always occurs in tail position with
/// respect to a body or expression.
-class Throw extends Expression {
+class Throw extends TailExpression {
Reference<Primitive> value;
Throw(Primitive value) : value = new Reference<Primitive>(value);
@@ -503,7 +525,7 @@ class Throw extends Expression {
/// Rethrow can only occur inside a continuation bound by [LetHandler]. It
/// implicitly throws the exception parameter of the enclosing handler with
/// the same stack trace as the enclosing handler.
-class Rethrow extends Expression {
+class Rethrow extends TailExpression {
accept(Visitor visitor) => visitor.visitRethrow(this);
}
@@ -528,7 +550,7 @@ class NonTailThrow extends Primitive {
///
/// This can be placed as the body of a call continuation, when the caller is
/// known never to invoke it, e.g. because the calling expression always throws.
-class Unreachable extends Expression {
+class Unreachable extends TailExpression {
accept(Visitor visitor) => visitor.visitUnreachable(this);
}
@@ -557,7 +579,7 @@ class GetMutableVariable extends Primitive {
/// values. This can be seen as a dereferencing assignment:
///
/// { [variable] := [value]; [body] }
-class SetMutableVariable extends Expression implements InteriorNode {
+class SetMutableVariable extends InteriorExpression {
final Reference<MutableVariable> variable;
final Reference<Primitive> value;
Expression body;
@@ -575,7 +597,7 @@ class SetMutableVariable extends Expression implements InteriorNode {
}
/// Invoke a continuation in tail position.
-class InvokeContinuation extends Expression {
+class InvokeContinuation extends TailExpression {
Reference<Continuation> continuation;
List<Reference<Primitive>> arguments;
SourceInformation sourceInformation;
@@ -627,7 +649,7 @@ class IsTrue extends Condition {
/// Choose between a pair of continuations based on a condition value.
///
/// The two continuations must not declare any parameters.
-class Branch extends Expression {
+class Branch extends TailExpression {
final Condition condition;
final Reference<Continuation> trueContinuation;
final Reference<Continuation> falseContinuation;
@@ -640,7 +662,7 @@ class Branch extends Expression {
}
/// Directly assigns to a field on a given object.
-class SetField extends Expression implements InteriorNode {
+class SetField extends InteriorExpression {
final Reference<Primitive> object;
FieldElement field;
final Reference<Primitive> value;
@@ -756,7 +778,7 @@ class GetStatic extends Primitive {
}
/// Sets the value of a static field.
-class SetStatic extends Expression implements InteriorNode {
+class SetStatic extends InteriorExpression {
final FieldElement element;
final Reference<Primitive> value;
Expression body;
@@ -779,7 +801,7 @@ class SetStatic extends Expression implements InteriorNode {
/// and assigned to the field.
///
/// [continuation] is then invoked with the value of the field as argument.
-class GetLazyStatic extends Expression {
+class GetLazyStatic extends CallExpression {
final FieldElement element;
final Reference<Continuation> continuation;
final SourceInformation sourceInformation;
@@ -855,22 +877,18 @@ class CreateInvocationMirror extends Primitive {
bool get isSafeForReordering => true;
}
-class ForeignCode extends Expression {
+class ForeignCode extends CallExpression {
final js.Template codeTemplate;
final TypeMask type;
final List<Reference<Primitive>> arguments;
final native.NativeBehavior nativeBehavior;
final FunctionElement dependency;
-
- /// The continuation, if the foreign code is not a JavaScript 'throw',
- /// otherwise null.
final Reference<Continuation> continuation;
ForeignCode(this.codeTemplate, this.type, List<Primitive> arguments,
- this.nativeBehavior, {Continuation continuation, this.dependency})
- : arguments = _referenceList(arguments),
- continuation = continuation == null ? null
- : new Reference<Continuation>(continuation);
+ this.nativeBehavior, Continuation continuation, {this.dependency})
+ : this.arguments = _referenceList(arguments),
+ this.continuation = new Reference<Continuation>(continuation);
accept(Visitor visitor) => visitor.visitForeignCode(this);
}
@@ -992,7 +1010,7 @@ class Continuation extends Definition<Continuation> implements InteriorNode {
class MutableVariable extends Definition {
Entity hint;
- MutableVariable(this.hint);
+MutableVariable(this.hint);
accept(Visitor v) => v.visitMutableVariable(this);
}
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698