| OLD | NEW |
| 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 758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 HExpressionInformation condition = info.condition; | 769 HExpressionInformation condition = info.condition; |
| 770 bool isConditionExpression = isJSCondition(condition); | 770 bool isConditionExpression = isJSCondition(condition); |
| 771 | 771 |
| 772 js.Loop loop; | 772 js.Loop loop; |
| 773 | 773 |
| 774 switch (info.kind) { | 774 switch (info.kind) { |
| 775 // Treate all three "test-first" loops the same way. | 775 // Treate all three "test-first" loops the same way. |
| 776 case HLoopBlockInformation.FOR_LOOP: | 776 case HLoopBlockInformation.FOR_LOOP: |
| 777 case HLoopBlockInformation.WHILE_LOOP: | 777 case HLoopBlockInformation.WHILE_LOOP: |
| 778 case HLoopBlockInformation.FOR_IN_LOOP: | 778 case HLoopBlockInformation.FOR_IN_LOOP: |
| 779 case HLoopBlockInformation.SWITCH_CONTINUE_LOOP: |
| 779 HBlockInformation initialization = info.initializer; | 780 HBlockInformation initialization = info.initializer; |
| 780 int initializationType = TYPE_STATEMENT; | 781 int initializationType = TYPE_STATEMENT; |
| 781 if (initialization != null) { | 782 if (initialization != null) { |
| 782 initializationType = expressionType(initialization); | 783 initializationType = expressionType(initialization); |
| 783 if (initializationType == TYPE_STATEMENT) { | 784 if (initializationType == TYPE_STATEMENT) { |
| 784 generateStatements(initialization); | 785 generateStatements(initialization); |
| 785 initialization = null; | 786 initialization = null; |
| 786 } | 787 } |
| 787 } | 788 } |
| 788 if (isConditionExpression && | 789 if (isConditionExpression && |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 921 } | 922 } |
| 922 loop = new js.Do(unwrapStatement(body), jsCondition); | 923 loop = new js.Do(unwrapStatement(body), jsCondition); |
| 923 currentContainer = oldContainer; | 924 currentContainer = oldContainer; |
| 924 break; | 925 break; |
| 925 default: | 926 default: |
| 926 compiler.internalError( | 927 compiler.internalError( |
| 927 'Unexpected loop kind: ${info.kind}', | 928 'Unexpected loop kind: ${info.kind}', |
| 928 instruction: condition.conditionExpression); | 929 instruction: condition.conditionExpression); |
| 929 } | 930 } |
| 930 attachLocationRange(loop, info.sourcePosition, info.endSourcePosition); | 931 attachLocationRange(loop, info.sourcePosition, info.endSourcePosition); |
| 931 pushStatement(wrapIntoLabels(loop, info.labels)); | 932 js.Statement result = loop; |
| 933 if (info.kind == HLoopBlockInformation.SWITCH_CONTINUE_LOOP) { |
| 934 String continueLabelString = |
| 935 backend.namer.implicitContinueLabelName(info.target); |
| 936 result = new js.LabeledStatement(continueLabelString, result); |
| 937 } |
| 938 pushStatement(wrapIntoLabels(result, info.labels)); |
| 932 return true; | 939 return true; |
| 933 } | 940 } |
| 934 | 941 |
| 935 bool visitLabeledBlockInfo(HLabeledBlockInformation labeledBlockInfo) { | 942 bool visitLabeledBlockInfo(HLabeledBlockInformation labeledBlockInfo) { |
| 936 preLabeledBlock(labeledBlockInfo); | 943 preLabeledBlock(labeledBlockInfo); |
| 937 Link<Element> continueOverrides = const Link<Element>(); | 944 Link<Element> continueOverrides = const Link<Element>(); |
| 938 | 945 |
| 939 js.Block oldContainer = currentContainer; | 946 js.Block oldContainer = currentContainer; |
| 940 js.Block body = new js.Block.empty(); | 947 js.Block body = new js.Block.empty(); |
| 941 js.Statement result = body; | 948 js.Statement result = body; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 963 result = new js.LabeledStatement(labelName, result); | 970 result = new js.LabeledStatement(labelName, result); |
| 964 continueAction[target] = implicitContinueAsBreak; | 971 continueAction[target] = implicitContinueAsBreak; |
| 965 continueOverrides = continueOverrides.prepend(target); | 972 continueOverrides = continueOverrides.prepend(target); |
| 966 } else { | 973 } else { |
| 967 for (LabelElement label in labeledBlockInfo.labels) { | 974 for (LabelElement label in labeledBlockInfo.labels) { |
| 968 if (label.isBreakTarget) { | 975 if (label.isBreakTarget) { |
| 969 String labelName = backend.namer.breakLabelName(label); | 976 String labelName = backend.namer.breakLabelName(label); |
| 970 result = new js.LabeledStatement(labelName, result); | 977 result = new js.LabeledStatement(labelName, result); |
| 971 } | 978 } |
| 972 } | 979 } |
| 973 TargetElement target = labeledBlockInfo.target; | 980 } |
| 974 if (target.isSwitch) { | 981 TargetElement target = labeledBlockInfo.target; |
| 975 // This is an extra block around a switch that is generated | 982 if (target.isSwitch) { |
| 976 // as a nested if/else chain. We add an extra break target | 983 // This is an extra block around a switch that is generated |
| 977 // so that case code can break. | 984 // as a nested if/else chain. We add an extra break target |
| 978 String labelName = backend.namer.implicitBreakLabelName(target); | 985 // so that case code can break. |
| 979 result = new js.LabeledStatement(labelName, result); | 986 String labelName = backend.namer.implicitBreakLabelName(target); |
| 980 breakAction[target] = implicitBreakWithLabel; | 987 result = new js.LabeledStatement(labelName, result); |
| 981 } | 988 breakAction[target] = implicitBreakWithLabel; |
| 982 } | 989 } |
| 983 | 990 |
| 984 currentContainer = body; | 991 currentContainer = body; |
| 985 startLabeledBlock(labeledBlockInfo); | 992 startLabeledBlock(labeledBlockInfo); |
| 986 generateStatements(labeledBlockInfo.body); | 993 generateStatements(labeledBlockInfo.body); |
| 987 endLabeledBlock(labeledBlockInfo); | 994 endLabeledBlock(labeledBlockInfo); |
| 988 | 995 |
| 989 if (labeledBlockInfo.isContinue) { | 996 if (labeledBlockInfo.isContinue) { |
| 990 while (!continueOverrides.isEmpty) { | 997 while (!continueOverrides.isEmpty) { |
| 991 continueAction.remove(continueOverrides.head); | 998 continueAction.remove(continueOverrides.head); |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1327 visitBreak(HBreak node) { | 1334 visitBreak(HBreak node) { |
| 1328 assert(node.block.successors.length == 1); | 1335 assert(node.block.successors.length == 1); |
| 1329 if (node.label != null) { | 1336 if (node.label != null) { |
| 1330 LabelElement label = node.label; | 1337 LabelElement label = node.label; |
| 1331 if (!tryCallAction(breakAction, label)) { | 1338 if (!tryCallAction(breakAction, label)) { |
| 1332 pushStatement(new js.Break(backend.namer.breakLabelName(label)), node); | 1339 pushStatement(new js.Break(backend.namer.breakLabelName(label)), node); |
| 1333 } | 1340 } |
| 1334 } else { | 1341 } else { |
| 1335 TargetElement target = node.target; | 1342 TargetElement target = node.target; |
| 1336 if (!tryCallAction(breakAction, target)) { | 1343 if (!tryCallAction(breakAction, target)) { |
| 1337 pushStatement(new js.Break(null), node); | 1344 if (node.breakSwitchContinueLoop) { |
| 1345 pushStatement(new js.Break( |
| 1346 backend.namer.implicitContinueLabelName(target)), node); |
| 1347 } else { |
| 1348 pushStatement(new js.Break(null), node); |
| 1349 } |
| 1338 } | 1350 } |
| 1339 } | 1351 } |
| 1340 } | 1352 } |
| 1341 | 1353 |
| 1342 visitContinue(HContinue node) { | 1354 visitContinue(HContinue node) { |
| 1343 assert(node.block.successors.length == 1); | 1355 assert(node.block.successors.length == 1); |
| 1344 if (node.label != null) { | 1356 if (node.label != null) { |
| 1345 LabelElement label = node.label; | 1357 LabelElement label = node.label; |
| 1346 if (!tryCallAction(continueAction, label)) { | 1358 if (!tryCallAction(continueAction, label)) { |
| 1347 // TODO(floitsch): should this really be the breakLabelName? | 1359 // TODO(floitsch): should this really be the breakLabelName? |
| 1348 pushStatement(new js.Continue(backend.namer.breakLabelName(label)), | 1360 pushStatement(new js.Continue(backend.namer.breakLabelName(label)), |
| 1349 node); | 1361 node); |
| 1350 } | 1362 } |
| 1351 } else { | 1363 } else { |
| 1352 TargetElement target = node.target; | 1364 TargetElement target = node.target; |
| 1353 if (!tryCallAction(continueAction, target)) { | 1365 if (!tryCallAction(continueAction, target)) { |
| 1354 pushStatement(new js.Continue(null), node); | 1366 if (target.statement is SwitchStatement) { |
| 1367 pushStatement(new js.Continue( |
| 1368 backend.namer.implicitContinueLabelName(target)), node); |
| 1369 } else { |
| 1370 pushStatement(new js.Continue(null), node); |
| 1371 } |
| 1355 } | 1372 } |
| 1356 } | 1373 } |
| 1357 } | 1374 } |
| 1358 | 1375 |
| 1359 visitExitTry(HExitTry node) { | 1376 visitExitTry(HExitTry node) { |
| 1360 // An [HExitTry] is used to represent the control flow graph of a | 1377 // An [HExitTry] is used to represent the control flow graph of a |
| 1361 // try/catch block, ie the try body is always a predecessor | 1378 // try/catch block, ie the try body is always a predecessor |
| 1362 // of the catch and finally. Here, we continue visiting the try | 1379 // of the catch and finally. Here, we continue visiting the try |
| 1363 // body by visiting the block that contains the user-level control | 1380 // body by visiting the block that contains the user-level control |
| 1364 // flow instruction. | 1381 // flow instruction. |
| (...skipping 1594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2959 if (leftType.canBeNull() && rightType.canBeNull()) { | 2976 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 2960 if (left.isConstantNull() || right.isConstantNull() || | 2977 if (left.isConstantNull() || right.isConstantNull() || |
| 2961 (leftType.isPrimitive() && leftType == rightType)) { | 2978 (leftType.isPrimitive() && leftType == rightType)) { |
| 2962 return '=='; | 2979 return '=='; |
| 2963 } | 2980 } |
| 2964 return null; | 2981 return null; |
| 2965 } else { | 2982 } else { |
| 2966 return '==='; | 2983 return '==='; |
| 2967 } | 2984 } |
| 2968 } | 2985 } |
| OLD | NEW |