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

Unified Diff: sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder_visitor.dart

Issue 661923003: Support binary expressions in analyzer2dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 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: sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder_visitor.dart
diff --git a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder_visitor.dart b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder_visitor.dart
index ae3babf3c0b01bd974e736f5e37ceb768a7e1b14..6ec3070f9fd7e9a9a3762a60b1c9307a623cbe48 100644
--- a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder_visitor.dart
@@ -219,112 +219,6 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
return null;
}
-
- /// Create a non-recursive join-point continuation.
- ///
- /// Given the environment length at the join point and a list of
- /// jumps that should reach the join point, create a join-point
- /// continuation. The join-point continuation has a parameter for each
- /// variable that has different values reaching on different paths.
- ///
- /// The jumps are uninitialized [ir.InvokeContinuation] expressions.
- /// They are filled in with the target continuation and appropriate
- /// arguments.
- ///
- /// As a side effect, the environment of this builder is updated to include
- /// the join-point continuation parameters.
- ir.Continuation createJoin(int environmentLength, JumpCollector jumps) {
- assert(jumps.length >= 2);
-
- // Compute which values are identical on all paths reaching the join.
- // Handle the common case of a pair of contexts efficiently.
- Environment first = jumps.environments[0];
- Environment second = jumps.environments[1];
- assert(environmentLength <= first.length);
- assert(environmentLength <= second.length);
- assert(first.sameDomain(environmentLength, second));
- // A running count of the join-point parameters.
- int parameterCount = 0;
- // The null elements of common correspond to required parameters of the
- // join-point continuation.
- List<ir.Primitive> common =
- new List<ir.Primitive>.generate(environmentLength,
- (i) {
- ir.Primitive candidate = first[i];
- if (second[i] == candidate) {
- return candidate;
- } else {
- ++parameterCount;
- return null;
- }
- });
- // If there is already a parameter for each variable, the other
- // environments do not need to be considered.
- if (parameterCount < environmentLength) {
- for (int i = 0; i < environmentLength; ++i) {
- ir.Primitive candidate = common[i];
- if (candidate == null) continue;
- for (Environment current in jumps.environments.skip(2)) {
- assert(environmentLength <= current.length);
- assert(first.sameDomain(environmentLength, current));
- if (candidate != current[i]) {
- common[i] = null;
- ++parameterCount;
- break;
- }
- }
- if (parameterCount >= environmentLength) break;
- }
- }
-
- // Create the join point continuation.
- List<ir.Parameter> parameters = <ir.Parameter>[];
- parameters.length = parameterCount;
- int index = 0;
- for (int i = 0; i < environmentLength; ++i) {
- if (common[i] == null) {
- parameters[index++] = new ir.Parameter(first.index2variable[i]);
- }
- }
- assert(index == parameterCount);
- ir.Continuation join = new ir.Continuation(parameters);
-
- // Fill in all the continuation invocations.
- for (int i = 0; i < jumps.length; ++i) {
- Environment currentEnvironment = jumps.environments[i];
- ir.InvokeContinuation invoke = jumps.invocations[i];
- // Sharing this.environment with one of the invocations will not do
- // the right thing (this.environment has already been mutated).
- List<ir.Reference> arguments = <ir.Reference>[];
- arguments.length = parameterCount;
- int index = 0;
- for (int i = 0; i < environmentLength; ++i) {
- if (common[i] == null) {
- arguments[index++] = new ir.Reference(currentEnvironment[i]);
- }
- }
- invoke.continuation = new ir.Reference(join);
- invoke.arguments = arguments;
- }
-
- // Mutate this.environment to be the environment at the join point. Do
- // this after adding the continuation invocations, because this.environment
- // might be collected by the jump collector and so the old environment
- // values are needed for the continuation invocation.
- //
- // Iterate to environment.length because environmentLength includes values
- // outside the environment which are 'phantom' variables used for the
- // values of expressions like &&, ||, and ?:.
- index = 0;
- for (int i = 0; i < irBuilder.environment.length; ++i) {
- if (common[i] == null) {
- irBuilder.environment.index2value[i] = parameters[index++];
- }
- }
-
- return join;
- }
-
/// Invoke a join-point continuation that contains arguments for all local
/// variables.
///
@@ -474,7 +368,7 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
irBuilder.environment = condBuilder.environment;
breakCollector.addJump(irBuilder);
letJoin.continuation =
- createJoin(irBuilder.environment.length, breakCollector);
+ irBuilder.createJoin(irBuilder.environment.length, breakCollector);
irBuilder._current = letJoin;
} else {
irBuilder._current = condBuilder._current;
@@ -517,7 +411,8 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
JumpCollector jumps = new JumpCollector(null);
jumps.addJump(thenBuilder);
jumps.addJump(elseBuilder);
- joinContinuation = createJoin(irBuilder.environment.length, jumps);
+ joinContinuation =
+ irBuilder.createJoin(irBuilder.environment.length, jumps);
result = new ir.LetCont(joinContinuation, result);
}
@@ -627,7 +522,7 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
irBuilder.environment = condBuilder.environment;
breakCollector.addJump(irBuilder);
letJoin.continuation =
- createJoin(irBuilder.environment.length, breakCollector);
+ irBuilder.createJoin(irBuilder.environment.length, breakCollector);
irBuilder._current = letJoin;
} else {
irBuilder._current = condBuilder._current;
@@ -747,7 +642,7 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
irBuilder.environment = condBuilder.environment;
breakCollector.addJump(irBuilder);
letJoin.continuation =
- createJoin(irBuilder.environment.length, breakCollector);
+ irBuilder.createJoin(irBuilder.environment.length, breakCollector);
irBuilder._current = letJoin;
} else {
irBuilder._current = condBuilder._current;
@@ -826,7 +721,7 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
jumps.addJump(thenBuilder);
jumps.addJump(elseBuilder);
ir.Continuation joinContinuation =
- createJoin(irBuilder.environment.length + 1, jumps);
+ irBuilder.createJoin(irBuilder.environment.length + 1, jumps);
// Build the term
// let cont join(x, ..., result) = [] in
@@ -1102,123 +997,17 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
}
- ir.Primitive buildNegation(ir.Primitive condition) {
- // ! e is translated as e ? false : true
-
- // Add a continuation parameter for the result of the expression.
- ir.Parameter resultParameter = new ir.Parameter(null);
-
- ir.Continuation joinContinuation = new ir.Continuation([resultParameter]);
- ir.Continuation thenContinuation = new ir.Continuation([]);
- ir.Continuation elseContinuation = new ir.Continuation([]);
-
- ir.Constant trueConstant = irBuilder.makePrimConst(
- irBuilder.state.constantSystem.createBool(true));
- ir.Constant falseConstant = irBuilder.makePrimConst(
- irBuilder.state.constantSystem.createBool(false));
-
- thenContinuation.body = new ir.LetPrim(falseConstant)
- ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant]));
- elseContinuation.body = new ir.LetPrim(trueConstant)
- ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant]));
-
- irBuilder.add(new ir.LetCont(joinContinuation,
- new ir.LetCont(thenContinuation,
- new ir.LetCont(elseContinuation,
- new ir.Branch(new ir.IsTrue(condition),
- thenContinuation,
- elseContinuation)))));
- return resultParameter;
- }
-
ir.Primitive translateLogicalOperator(ast.Operator op,
ast.Expression left,
ast.Expression right) {
- // e0 && e1 is translated as if e0 ? (e1 == true) : false.
- // e0 || e1 is translated as if e0 ? true : (e1 == true).
- // The translation must convert both e0 and e1 to booleans and handle
- // local variable assignments in e1.
-
ir.Primitive leftValue = visit(left);
- IrBuilder rightBuilder = new IrBuilder.delimited(irBuilder);
- ir.Primitive rightValue =
- withBuilder(rightBuilder, () => visit(right));
- // A dummy empty target for the branch on the left subexpression branch.
- // This enables using the same infrastructure for join-point continuations
- // as in visitIf and visitConditional. It will hold a definition of the
- // appropriate constant and an invocation of the join-point continuation.
- IrBuilder emptyBuilder = new IrBuilder.delimited(irBuilder);
- // Dummy empty targets for right true and right false. They hold
- // definitions of the appropriate constant and an invocation of the
- // join-point continuation.
- IrBuilder rightTrueBuilder = new IrBuilder.delimited(rightBuilder);
- IrBuilder rightFalseBuilder = new IrBuilder.delimited(rightBuilder);
-
- // If we don't evaluate the right subexpression, the value of the whole
- // expression is this constant.
- ir.Constant leftBool = emptyBuilder.makePrimConst(
- emptyBuilder.state.constantSystem.createBool(op.source == '||'));
- // If we do evaluate the right subexpression, the value of the expression
- // is a true or false constant.
- ir.Constant rightTrue = rightTrueBuilder.makePrimConst(
- rightTrueBuilder.state.constantSystem.createBool(true));
- ir.Constant rightFalse = rightFalseBuilder.makePrimConst(
- rightFalseBuilder.state.constantSystem.createBool(false));
- emptyBuilder.add(new ir.LetPrim(leftBool));
- rightTrueBuilder.add(new ir.LetPrim(rightTrue));
- rightFalseBuilder.add(new ir.LetPrim(rightFalse));
-
- // Treat the result values as named values in the environment, so they
- // will be treated as arguments to the join-point continuation.
- assert(irBuilder.environment.length == emptyBuilder.environment.length);
- assert(irBuilder.environment.length == rightTrueBuilder.environment.length);
- assert(irBuilder.environment.length ==
- rightFalseBuilder.environment.length);
- emptyBuilder.environment.extend(null, leftBool);
- rightTrueBuilder.environment.extend(null, rightTrue);
- rightFalseBuilder.environment.extend(null, rightFalse);
-
- // Wire up two continuations for the left subexpression, two continuations
- // for the right subexpression, and a three-way join continuation.
- JumpCollector jumps = new JumpCollector(null);
- jumps.addJump(emptyBuilder);
- jumps.addJump(rightTrueBuilder);
- jumps.addJump(rightFalseBuilder);
- ir.Continuation joinContinuation =
- createJoin(irBuilder.environment.length + 1, jumps);
- ir.Continuation leftTrueContinuation = new ir.Continuation([]);
- ir.Continuation leftFalseContinuation = new ir.Continuation([]);
- ir.Continuation rightTrueContinuation = new ir.Continuation([]);
- ir.Continuation rightFalseContinuation = new ir.Continuation([]);
- rightTrueContinuation.body = rightTrueBuilder._root;
- rightFalseContinuation.body = rightFalseBuilder._root;
- // The right subexpression has two continuations.
- rightBuilder.add(
- new ir.LetCont(rightTrueContinuation,
- new ir.LetCont(rightFalseContinuation,
- new ir.Branch(new ir.IsTrue(rightValue),
- rightTrueContinuation,
- rightFalseContinuation))));
- // Depending on the operator, the left subexpression's continuations are
- // either the right subexpression or an invocation of the join-point
- // continuation.
- if (op.source == '&&') {
- leftTrueContinuation.body = rightBuilder._root;
- leftFalseContinuation.body = emptyBuilder._root;
- } else {
- leftTrueContinuation.body = emptyBuilder._root;
- leftFalseContinuation.body = rightBuilder._root;
+
+ ir.Primitive buildRightValue(IrBuilder rightBuilder) {
+ return withBuilder(rightBuilder, () => visit(right));
}
- irBuilder.add(new ir.LetCont(joinContinuation,
- new ir.LetCont(leftTrueContinuation,
- new ir.LetCont(leftFalseContinuation,
- new ir.Branch(new ir.IsTrue(leftValue),
- leftTrueContinuation,
- leftFalseContinuation)))));
- // There is always a join parameter for the result value, because it
- // is different on at least two paths.
- return joinContinuation.parameters.last;
+ return irBuilder.buildLogicalOperator(
+ leftValue, buildRightValue, isLazyOr: op.source == '||');
}
ir.Primitive visitOperatorSend(ast.Send node) {
@@ -1236,13 +1025,13 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
if (op.source == "!") {
assert(node.receiver != null);
assert(node.arguments.isEmpty);
- return buildNegation(visit(node.receiver));
+ return irBuilder.buildNegation(visit(node.receiver));
}
if (op.source == "!=") {
assert(node.receiver != null);
assert(!node.arguments.isEmpty);
assert(node.arguments.tail.isEmpty);
- return buildNegation(visitDynamicSend(node));
+ return irBuilder.buildNegation(visitDynamicSend(node));
}
assert(invariant(node, op.source == "is" || op.source == "as",
message: "unexpected operator $op"));
@@ -1250,7 +1039,7 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
ir.Primitive receiver = visit(node.receiver);
ir.Primitive check = irBuilder.continueWithExpression(
(k) => new ir.TypeOperator(op.source, receiver, type, k));
- return node.isIsNotCheck ? buildNegation(check) : check;
+ return node.isIsNotCheck ? irBuilder.buildNegation(check) : check;
}
// Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]]

Powered by Google App Engine
This is Rietveld 408576698