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

Side by Side Diff: pkg/compiler/lib/src/js_backend/codegen/codegen.dart

Issue 1287253002: dart2js cps: Compile some loops as 'for' loops. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library code_generator; 5 library code_generator;
6 6
7 import 'glue.dart'; 7 import 'glue.dart';
8 8
9 import '../../closure.dart' show ClosureClassElement; 9 import '../../closure.dart' show ClosureClassElement;
10 import '../../common/codegen.dart' show CodegenRegistry; 10 import '../../common/codegen.dart' show CodegenRegistry;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 if (!declaredVariables.add(use.name)) break; 101 if (!declaredVariables.add(use.name)) break;
102 102
103 js.VariableInitialization jsVariable = new js.VariableInitialization( 103 js.VariableInitialization jsVariable = new js.VariableInitialization(
104 new js.VariableDeclaration(use.name), 104 new js.VariableDeclaration(use.name),
105 assign.value); 105 assign.value);
106 jsVariables.add(jsVariable); 106 jsVariables.add(jsVariable);
107 107
108 ++accumulatorIndex; 108 ++accumulatorIndex;
109 } 109 }
110 110
111 // If the last statement is a for loop with an initializer expression, try
112 // to pull that expression into an initializer as well.
113 pullFromForLoop:
114 if (accumulatorIndex < accumulator.length &&
115 accumulator[accumulatorIndex] is js.For) {
116 js.For forLoop = accumulator[accumulatorIndex];
117 if (forLoop.init is! js.Assignment) break pullFromForLoop;
118 js.Assignment assign = forLoop.init;
119 if (assign.leftHandSide is! js.VariableUse) break pullFromForLoop;
120 if (assign.op != null) break pullFromForLoop; // Compound assignment.
121 js.VariableUse use = assign.leftHandSide;
122
123 // We cannot declare a variable more than once.
124 if (!declaredVariables.add(use.name)) break pullFromForLoop;
125
126 js.VariableInitialization jsVariable = new js.VariableInitialization(
127 new js.VariableDeclaration(use.name),
128 assign.value);
129 jsVariables.add(jsVariable);
130
131 // Remove the initializer from the for loop.
132 accumulator[accumulatorIndex] =
133 new js.For(null, forLoop.condition, forLoop.update, forLoop.body);
134 }
135
111 // Discard the statements that were pulled in the initializer. 136 // Discard the statements that were pulled in the initializer.
112 if (accumulatorIndex > 0) { 137 if (accumulatorIndex > 0) {
113 accumulator = accumulator.sublist(accumulatorIndex); 138 accumulator = accumulator.sublist(accumulatorIndex);
114 } 139 }
115 140
116 // Declare remaining variables. 141 // Declare remaining variables.
117 for (tree_ir.Variable variable in variableNames.keys) { 142 for (tree_ir.Variable variable in variableNames.keys) {
118 String name = getVariableName(variable); 143 String name = getVariableName(variable);
119 if (declaredVariables.contains(name)) continue; 144 if (declaredVariables.contains(name)) continue;
120 js.VariableInitialization jsVariable = new js.VariableInitialization( 145 js.VariableInitialization jsVariable = new js.VariableInitialization(
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 534
510 js.Block buildBodyBlock(tree_ir.Statement statement) { 535 js.Block buildBodyBlock(tree_ir.Statement statement) {
511 List<js.Statement> savedAccumulator = accumulator; 536 List<js.Statement> savedAccumulator = accumulator;
512 accumulator = <js.Statement>[]; 537 accumulator = <js.Statement>[];
513 visitStatement(statement); 538 visitStatement(statement);
514 js.Statement result = new js.Block(accumulator); 539 js.Statement result = new js.Block(accumulator);
515 accumulator = savedAccumulator; 540 accumulator = savedAccumulator;
516 return result; 541 return result;
517 } 542 }
518 543
544 js.Expression makeSequence(List<tree_ir.Expression> list) {
545 return list.map(visitExpression).reduce((x,y) => new js.Binary(',', x, y));
546 }
547
519 @override 548 @override
520 void visitWhileCondition(tree_ir.WhileCondition node) { 549 void visitWhileCondition(tree_ir.WhileCondition node) {
521 js.Expression condition = visitExpression(node.condition); 550 js.Expression condition = visitExpression(node.condition);
522 shortBreak.push(node.next); 551 shortBreak.push(node.next);
523 shortContinue.push(node); 552 shortContinue.push(node);
524 fallthrough.push(node); 553 fallthrough.push(node);
525 js.Statement jsBody = buildBodyStatement(node.body); 554 js.Statement body = buildBodyStatement(node.body);
526 fallthrough.pop(); 555 fallthrough.pop();
527 shortContinue.pop(); 556 shortContinue.pop();
528 shortBreak.pop(); 557 shortBreak.pop();
529 accumulator.add(insertLabel(node.label, new js.While(condition, jsBody))); 558 js.Statement loopNode;
559 if (node.updates.isEmpty) {
560 loopNode = new js.While(condition, body);
561 } else { // Compile as a for loop.
562 js.Expression init;
563 if (accumulator.isNotEmpty &&
564 accumulator.last is js.ExpressionStatement) {
565 // Take the preceding expression from the accumulator and use
566 // it as the initializer expression.
567 js.ExpressionStatement initStmt = accumulator.removeLast();
568 init = initStmt.expression;
569 }
570 js.Expression update = makeSequence(node.updates);
571 loopNode = new js.For(init, condition, update, body);
572 }
573 accumulator.add(insertLabel(node.label, loopNode));
530 visitStatement(node.next); 574 visitStatement(node.next);
531 } 575 }
532 576
533 @override 577 @override
534 void visitWhileTrue(tree_ir.WhileTrue node) { 578 void visitWhileTrue(tree_ir.WhileTrue node) {
535 js.Expression condition = new js.LiteralBool(true); 579 js.Expression condition = new js.LiteralBool(true);
536 // A short break in the while will jump to the current fallthrough target. 580 // A short break in the while will jump to the current fallthrough target.
537 shortBreak.push(fallthrough.target); 581 shortBreak.push(fallthrough.target);
538 shortContinue.push(node); 582 shortContinue.push(node);
539 fallthrough.push(node); 583 fallthrough.push(node);
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 js.Expression visitAwait(tree_ir.Await node) { 896 js.Expression visitAwait(tree_ir.Await node) {
853 return new js.Await(visitExpression(node.input)); 897 return new js.Await(visitExpression(node.input));
854 } 898 }
855 899
856 visitFunctionExpression(tree_ir.FunctionExpression node) { 900 visitFunctionExpression(tree_ir.FunctionExpression node) {
857 // FunctionExpressions are currently unused. 901 // FunctionExpressions are currently unused.
858 // We might need them if we want to emit raw JS nested functions. 902 // We might need them if we want to emit raw JS nested functions.
859 throw 'FunctionExpressions should not be used'; 903 throw 'FunctionExpressions should not be used';
860 } 904 }
861 } 905 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698