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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/codegen.dart

Issue 14969004: Implement continue for switch. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of ssa; 5 part of ssa;
6 6
7 class SsaCodeGeneratorTask extends CompilerTask { 7 class SsaCodeGeneratorTask extends CompilerTask {
8 8
9 final JavaScriptBackend backend; 9 final JavaScriptBackend backend;
10 10
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 HExpressionInformation condition = info.condition; 771 HExpressionInformation condition = info.condition;
772 bool isConditionExpression = isJSCondition(condition); 772 bool isConditionExpression = isJSCondition(condition);
773 773
774 js.Loop loop; 774 js.Loop loop;
775 775
776 switch (info.kind) { 776 switch (info.kind) {
777 // Treate all three "test-first" loops the same way. 777 // Treate all three "test-first" loops the same way.
778 case HLoopBlockInformation.FOR_LOOP: 778 case HLoopBlockInformation.FOR_LOOP:
779 case HLoopBlockInformation.WHILE_LOOP: 779 case HLoopBlockInformation.WHILE_LOOP:
780 case HLoopBlockInformation.FOR_IN_LOOP: 780 case HLoopBlockInformation.FOR_IN_LOOP:
781 case HLoopBlockInformation.SWITCH_CONTINUE_LOOP:
781 HBlockInformation initialization = info.initializer; 782 HBlockInformation initialization = info.initializer;
782 int initializationType = TYPE_STATEMENT; 783 int initializationType = TYPE_STATEMENT;
783 if (initialization != null) { 784 if (initialization != null) {
784 initializationType = expressionType(initialization); 785 initializationType = expressionType(initialization);
785 if (initializationType == TYPE_STATEMENT) { 786 if (initializationType == TYPE_STATEMENT) {
786 generateStatements(initialization); 787 generateStatements(initialization);
787 initialization = null; 788 initialization = null;
788 } 789 }
789 } 790 }
790 if (isConditionExpression && 791 if (isConditionExpression &&
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 } 924 }
924 loop = new js.Do(unwrapStatement(body), jsCondition); 925 loop = new js.Do(unwrapStatement(body), jsCondition);
925 currentContainer = oldContainer; 926 currentContainer = oldContainer;
926 break; 927 break;
927 default: 928 default:
928 compiler.internalError( 929 compiler.internalError(
929 'Unexpected loop kind: ${info.kind}', 930 'Unexpected loop kind: ${info.kind}',
930 instruction: condition.conditionExpression); 931 instruction: condition.conditionExpression);
931 } 932 }
932 attachLocationRange(loop, info.sourcePosition, info.endSourcePosition); 933 attachLocationRange(loop, info.sourcePosition, info.endSourcePosition);
933 pushStatement(wrapIntoLabels(loop, info.labels)); 934 js.Statement result = loop;
935 if (info.kind == HLoopBlockInformation.SWITCH_CONTINUE_LOOP) {
936 String continueLabelString =
937 backend.namer.implicitContinueLabelName(info.target);
938 result = new js.LabeledStatement(continueLabelString, result);
939 }
940 pushStatement(wrapIntoLabels(result, info.labels));
934 return true; 941 return true;
935 } 942 }
936 943
937 bool visitLabeledBlockInfo(HLabeledBlockInformation labeledBlockInfo) { 944 bool visitLabeledBlockInfo(HLabeledBlockInformation labeledBlockInfo) {
938 preLabeledBlock(labeledBlockInfo); 945 preLabeledBlock(labeledBlockInfo);
939 Link<Element> continueOverrides = const Link<Element>(); 946 Link<Element> continueOverrides = const Link<Element>();
940 947
941 js.Block oldContainer = currentContainer; 948 js.Block oldContainer = currentContainer;
942 js.Block body = new js.Block.empty(); 949 js.Block body = new js.Block.empty();
943 js.Statement result = body; 950 js.Statement result = body;
(...skipping 21 matching lines...) Expand all
965 result = new js.LabeledStatement(labelName, result); 972 result = new js.LabeledStatement(labelName, result);
966 continueAction[target] = implicitContinueAsBreak; 973 continueAction[target] = implicitContinueAsBreak;
967 continueOverrides = continueOverrides.prepend(target); 974 continueOverrides = continueOverrides.prepend(target);
968 } else { 975 } else {
969 for (LabelElement label in labeledBlockInfo.labels) { 976 for (LabelElement label in labeledBlockInfo.labels) {
970 if (label.isBreakTarget) { 977 if (label.isBreakTarget) {
971 String labelName = backend.namer.breakLabelName(label); 978 String labelName = backend.namer.breakLabelName(label);
972 result = new js.LabeledStatement(labelName, result); 979 result = new js.LabeledStatement(labelName, result);
973 } 980 }
974 } 981 }
975 TargetElement target = labeledBlockInfo.target; 982 }
976 if (target.isSwitch) { 983 TargetElement target = labeledBlockInfo.target;
977 // This is an extra block around a switch that is generated 984 if (target.isSwitch) {
978 // as a nested if/else chain. We add an extra break target 985 // This is an extra block around a switch that is generated
979 // so that case code can break. 986 // as a nested if/else chain. We add an extra break target
980 String labelName = backend.namer.implicitBreakLabelName(target); 987 // so that case code can break.
981 result = new js.LabeledStatement(labelName, result); 988 String labelName = backend.namer.implicitBreakLabelName(target);
982 breakAction[target] = implicitBreakWithLabel; 989 result = new js.LabeledStatement(labelName, result);
983 } 990 breakAction[target] = implicitBreakWithLabel;
984 } 991 }
985 992
986 currentContainer = body; 993 currentContainer = body;
987 startLabeledBlock(labeledBlockInfo); 994 startLabeledBlock(labeledBlockInfo);
988 generateStatements(labeledBlockInfo.body); 995 generateStatements(labeledBlockInfo.body);
989 endLabeledBlock(labeledBlockInfo); 996 endLabeledBlock(labeledBlockInfo);
990 997
991 if (labeledBlockInfo.isContinue) { 998 if (labeledBlockInfo.isContinue) {
992 while (!continueOverrides.isEmpty) { 999 while (!continueOverrides.isEmpty) {
993 continueAction.remove(continueOverrides.head); 1000 continueAction.remove(continueOverrides.head);
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 visitBreak(HBreak node) { 1336 visitBreak(HBreak node) {
1330 assert(node.block.successors.length == 1); 1337 assert(node.block.successors.length == 1);
1331 if (node.label != null) { 1338 if (node.label != null) {
1332 LabelElement label = node.label; 1339 LabelElement label = node.label;
1333 if (!tryCallAction(breakAction, label)) { 1340 if (!tryCallAction(breakAction, label)) {
1334 pushStatement(new js.Break(backend.namer.breakLabelName(label)), node); 1341 pushStatement(new js.Break(backend.namer.breakLabelName(label)), node);
1335 } 1342 }
1336 } else { 1343 } else {
1337 TargetElement target = node.target; 1344 TargetElement target = node.target;
1338 if (!tryCallAction(breakAction, target)) { 1345 if (!tryCallAction(breakAction, target)) {
1339 pushStatement(new js.Break(null), node); 1346 if (node.breakSwitchContinueLoop) {
1347 pushStatement(new js.Break(
1348 backend.namer.implicitContinueLabelName(target)), node);
1349 } else {
1350 pushStatement(new js.Break(null), node);
1351 }
1340 } 1352 }
1341 } 1353 }
1342 } 1354 }
1343 1355
1344 visitContinue(HContinue node) { 1356 visitContinue(HContinue node) {
1345 assert(node.block.successors.length == 1); 1357 assert(node.block.successors.length == 1);
1346 if (node.label != null) { 1358 if (node.label != null) {
1347 LabelElement label = node.label; 1359 LabelElement label = node.label;
1348 if (!tryCallAction(continueAction, label)) { 1360 if (!tryCallAction(continueAction, label)) {
1349 // TODO(floitsch): should this really be the breakLabelName? 1361 // TODO(floitsch): should this really be the breakLabelName?
1350 pushStatement(new js.Continue(backend.namer.breakLabelName(label)), 1362 pushStatement(new js.Continue(backend.namer.breakLabelName(label)),
1351 node); 1363 node);
1352 } 1364 }
1353 } else { 1365 } else {
1354 TargetElement target = node.target; 1366 TargetElement target = node.target;
1355 if (!tryCallAction(continueAction, target)) { 1367 if (!tryCallAction(continueAction, target)) {
1356 pushStatement(new js.Continue(null), node); 1368 if (target.statement is SwitchStatement) {
1369 pushStatement(new js.Continue(
1370 backend.namer.implicitContinueLabelName(target)), node);
1371 } else {
1372 pushStatement(new js.Continue(null), node);
1373 }
1357 } 1374 }
1358 } 1375 }
1359 } 1376 }
1360 1377
1361 visitExitTry(HExitTry node) { 1378 visitExitTry(HExitTry node) {
1362 // An [HExitTry] is used to represent the control flow graph of a 1379 // An [HExitTry] is used to represent the control flow graph of a
1363 // try/catch block, ie the try body is always a predecessor 1380 // try/catch block, ie the try body is always a predecessor
1364 // of the catch and finally. Here, we continue visiting the try 1381 // of the catch and finally. Here, we continue visiting the try
1365 // body by visiting the block that contains the user-level control 1382 // body by visiting the block that contains the user-level control
1366 // flow instruction. 1383 // flow instruction.
(...skipping 1607 matching lines...) Expand 10 before | Expand all | Expand 10 after
2974 if (leftType.canBeNull() && rightType.canBeNull()) { 2991 if (leftType.canBeNull() && rightType.canBeNull()) {
2975 if (left.isConstantNull() || right.isConstantNull() || 2992 if (left.isConstantNull() || right.isConstantNull() ||
2976 (leftType.isPrimitive() && leftType == rightType)) { 2993 (leftType.isPrimitive() && leftType == rightType)) {
2977 return '=='; 2994 return '==';
2978 } 2995 }
2979 return null; 2996 return null;
2980 } else { 2997 } else {
2981 return '==='; 2998 return '===';
2982 } 2999 }
2983 } 3000 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698