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 4afa3e9d23be40610e29d35bc2ecad90a2cf89fc..162c38a7181493ed8f5709e4434af262a4bba4b7 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 |
@@ -252,123 +252,23 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> |
target: elements.getTargetDefinition(node)); |
} |
- ir.Primitive visitForIn(ast.ForIn node) { |
- // The for-in loop |
- // |
- // for (a in e) s; |
- // |
- // Is compiled analogously to: |
- // |
- // a = e.iterator; |
- // while (a.moveNext()) { |
- // var n0 = a.current; |
- // s; |
- // } |
- |
- // The condition and body are delimited. |
- IrBuilder condBuilder = new IrBuilder.recursive(irBuilder); |
- |
- ir.Primitive expressionReceiver = visit(node.expression); |
- List<ir.Primitive> emptyArguments = new List<ir.Primitive>(); |
- |
- ir.Parameter iterator = new ir.Parameter(null); |
- ir.Continuation iteratorInvoked = new ir.Continuation([iterator]); |
- irBuilder.add(new ir.LetCont(iteratorInvoked, |
- new ir.InvokeMethod(expressionReceiver, |
- new Selector.getter("iterator", null), iteratorInvoked, |
- emptyArguments))); |
- |
- ir.Parameter condition = new ir.Parameter(null); |
- ir.Continuation moveNextInvoked = new ir.Continuation([condition]); |
- condBuilder.add(new ir.LetCont(moveNextInvoked, |
- new ir.InvokeMethod(iterator, |
- new Selector.call("moveNext", null, 0), |
- moveNextInvoked, emptyArguments))); |
- |
- JumpTarget target = elements.getTargetDefinition(node); |
- JumpCollector breakCollector = new JumpCollector(target); |
- JumpCollector continueCollector = new JumpCollector(target); |
- irBuilder.state.breakCollectors.add(breakCollector); |
- irBuilder.state.continueCollectors.add(continueCollector); |
- |
- IrBuilder bodyBuilder = new IrBuilder.delimited(condBuilder); |
+ visitForIn(ast.ForIn node) { |
+ // [node.declaredIdentifier] can be either an [ast.VariableDefinitions] |
+ // (defining a new local variable) or a send designating some existing |
+ // variable. |
ast.Node identifier = node.declaredIdentifier; |
+ ast.VariableDefinitions variableDeclaration = |
+ identifier.asVariableDefinitions(); |
Element variableElement = elements.getForInVariable(node); |
Selector selector = elements.getSelector(identifier); |
- // node.declaredIdentifier can be either an ast.VariableDefinitions |
- // (defining a new local variable) or a send designating some existing |
- // variable. |
- ast.Node declaredIdentifier = node.declaredIdentifier; |
- |
- if (declaredIdentifier is ast.VariableDefinitions) { |
- withBuilder(bodyBuilder, () => visit(declaredIdentifier)); |
- } |
- |
- ir.Parameter currentValue = new ir.Parameter(null); |
- ir.Continuation currentInvoked = new ir.Continuation([currentValue]); |
- bodyBuilder.add(new ir.LetCont(currentInvoked, |
- new ir.InvokeMethod(iterator, new Selector.getter("current", null), |
- currentInvoked, emptyArguments))); |
- if (Elements.isLocal(variableElement)) { |
- bodyBuilder.buildLocalSet(variableElement, currentValue); |
- } else if (Elements.isStaticOrTopLevel(variableElement)) { |
- bodyBuilder.buildStaticSet(variableElement, selector, currentValue); |
- } else { |
- ir.Primitive receiver = |
- withBuilder(bodyBuilder, () => lookupThis()); |
- bodyBuilder.buildDynamicSet(receiver, selector, currentValue); |
- } |
- |
- withBuilder(bodyBuilder, () => visit(node.body)); |
- assert(irBuilder.state.breakCollectors.last == breakCollector); |
- assert(irBuilder.state.continueCollectors.last == continueCollector); |
- irBuilder.state.breakCollectors.removeLast(); |
- irBuilder.state.continueCollectors.removeLast(); |
- |
- // Create body entry and loop exit continuations and a branch to them. |
- ir.Continuation bodyContinuation = new ir.Continuation([]); |
- ir.Continuation exitContinuation = new ir.Continuation([]); |
- ir.LetCont branch = |
- new ir.LetCont(exitContinuation, |
- new ir.LetCont(bodyContinuation, |
- new ir.Branch(new ir.IsTrue(condition), |
- bodyContinuation, |
- exitContinuation))); |
- // If there are breaks in the body, then there must be a join-point |
- // continuation for the normal exit and the breaks. |
- bool hasBreaks = !breakCollector.isEmpty; |
- ir.LetCont letJoin; |
- if (hasBreaks) { |
- letJoin = new ir.LetCont(null, branch); |
- condBuilder.add(letJoin); |
- condBuilder._current = branch; |
- } else { |
- condBuilder.add(branch); |
- } |
- ir.Continuation loopContinuation = |
- new ir.Continuation(condBuilder._parameters); |
- if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder); |
- irBuilder.invokeFullJoin( |
- loopContinuation, continueCollector, recursive: true); |
- bodyContinuation.body = bodyBuilder._root; |
- |
- loopContinuation.body = condBuilder._root; |
- irBuilder.add(new ir.LetCont(loopContinuation, |
- new ir.InvokeContinuation(loopContinuation, |
- irBuilder.environment.index2value))); |
- if (hasBreaks) { |
- irBuilder._current = branch; |
- irBuilder.environment = condBuilder.environment; |
- breakCollector.addJump(irBuilder); |
- letJoin.continuation = |
- irBuilder.createJoin(irBuilder.environment.length, breakCollector); |
- irBuilder._current = letJoin; |
- } else { |
- irBuilder._current = condBuilder._current; |
- irBuilder.environment = condBuilder.environment; |
- } |
- return null; |
+ irBuilder.buildForIn( |
+ buildExpression: subbuild(node.expression), |
+ buildVariableDeclaration: subbuild(variableDeclaration), |
+ variableElement: variableElement, |
+ variableSelector: selector, |
+ buildBody: subbuild(node.body), |
+ target: elements.getTargetDefinition(node)); |
} |
ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) { |
@@ -489,10 +389,9 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> |
} |
ir.Primitive visitIdentifier(ast.Identifier node) { |
- assert(irBuilder.isOpen); |
// "this" is the only identifier that should be met by the visitor. |
assert(node.isThis()); |
- return lookupThis(); |
+ return irBuilder.buildThis(); |
} |
ir.Primitive visitParenthesizedExpression( |
@@ -521,12 +420,6 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> |
return receiver; |
} |
- ir.Primitive lookupThis() { |
- ir.Primitive result = new ir.This(); |
- irBuilder.add(new ir.LetPrim(result)); |
- return result; |
- } |
- |
// ==== Sends ==== |
ir.Primitive visitAssert(ast.Send node) { |
assert(irBuilder.isOpen); |
@@ -573,7 +466,7 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> |
/// If [node] is super, returns null (for special handling) |
/// Otherwise visits [node] and returns the result. |
ir.Primitive visitReceiver(ast.Expression node) { |
- if (node == null) return lookupThis(); |
+ if (node == null) return irBuilder.buildThis(); |
if (node.isSuper()) return null; |
return visit(node); |
} |