| 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 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |