| 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);
|
| }
|
|
|