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 import 'dart:math' as math; | 5 import 'dart:math' as math; |
6 import 'dart:collection' show Queue; | 6 import 'dart:collection' show Queue; |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
9 import '../common/tasks.dart' show CompilerTask; | 9 import '../common/tasks.dart' show CompilerTask; |
10 import '../constants/constant_system.dart'; | 10 import '../constants/constant_system.dart'; |
(...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1076 } | 1076 } |
1077 body.statements.add(new js.If(jsCondition, updateBody, exitLoop)); | 1077 body.statements.add(new js.If(jsCondition, updateBody, exitLoop)); |
1078 jsCondition = newLiteralBool(true, info.sourceInformation); | 1078 jsCondition = newLiteralBool(true, info.sourceInformation); |
1079 } | 1079 } |
1080 loop = new js.Do(unwrapStatement(body), jsCondition) | 1080 loop = new js.Do(unwrapStatement(body), jsCondition) |
1081 .withSourceInformation(info.sourceInformation); | 1081 .withSourceInformation(info.sourceInformation); |
1082 } | 1082 } |
1083 currentContainer = oldContainer; | 1083 currentContainer = oldContainer; |
1084 break; | 1084 break; |
1085 default: | 1085 default: |
1086 throw new SpannableAssertionFailure(condition.conditionExpression, | 1086 failedAt(condition.conditionExpression, |
1087 'Unexpected loop kind: ${info.kind}.'); | 1087 'Unexpected loop kind: ${info.kind}.'); |
1088 } | 1088 } |
1089 js.Statement result = loop; | 1089 js.Statement result = loop; |
1090 if (info.kind == HLoopBlockInformation.SWITCH_CONTINUE_LOOP) { | 1090 if (info.kind == HLoopBlockInformation.SWITCH_CONTINUE_LOOP) { |
1091 String continueLabelString = | 1091 String continueLabelString = |
1092 _namer.implicitContinueLabelName(info.target); | 1092 _namer.implicitContinueLabelName(info.target); |
1093 result = new js.LabeledStatement(continueLabelString, result); | 1093 result = new js.LabeledStatement(continueLabelString, result); |
1094 } | 1094 } |
1095 pushStatement(wrapIntoLabels(result, info.labels)); | 1095 pushStatement(wrapIntoLabels(result, info.labels)); |
1096 return true; | 1096 return true; |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1490 HBasicBlock block = node.block; | 1490 HBasicBlock block = node.block; |
1491 assert(block.successors.length == 1); | 1491 assert(block.successors.length == 1); |
1492 List<HBasicBlock> dominated = block.dominatedBlocks; | 1492 List<HBasicBlock> dominated = block.dominatedBlocks; |
1493 // With the exception of the entry-node which dominates its successor | 1493 // With the exception of the entry-node which dominates its successor |
1494 // and the exit node, no block finishing with a 'goto' can have more than | 1494 // and the exit node, no block finishing with a 'goto' can have more than |
1495 // one dominated block (since it has only one successor). | 1495 // one dominated block (since it has only one successor). |
1496 // If the successor is dominated by another block, then the other block | 1496 // If the successor is dominated by another block, then the other block |
1497 // is responsible for visiting the successor. | 1497 // is responsible for visiting the successor. |
1498 if (dominated.isEmpty) return; | 1498 if (dominated.isEmpty) return; |
1499 if (dominated.length > 2) { | 1499 if (dominated.length > 2) { |
1500 throw new SpannableAssertionFailure( | 1500 failedAt(node, 'dominated.length = ${dominated.length}'); |
1501 node, 'dominated.length = ${dominated.length}'); | |
1502 } | 1501 } |
1503 if (dominated.length == 2 && block != currentGraph.entry) { | 1502 if (dominated.length == 2 && block != currentGraph.entry) { |
1504 throw new SpannableAssertionFailure( | 1503 failedAt(node, 'node.block != currentGraph.entry'); |
1505 node, 'node.block != currentGraph.entry'); | |
1506 } | 1504 } |
1507 assert(dominated[0] == block.successors[0]); | 1505 assert(dominated[0] == block.successors[0]); |
1508 continueSubGraph(dominated.first); | 1506 continueSubGraph(dominated.first); |
1509 } | 1507 } |
1510 | 1508 |
1511 visitLoopBranch(HLoopBranch node) { | 1509 visitLoopBranch(HLoopBranch node) { |
1512 assert(node.block == subGraph.end); | 1510 assert(node.block == subGraph.end); |
1513 // We are generating code for a loop condition. | 1511 // We are generating code for a loop condition. |
1514 // If we are generating the subgraph as an expression, the | 1512 // If we are generating the subgraph as an expression, the |
1515 // condition will be generated as the expression. | 1513 // condition will be generated as the expression. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1583 // try/catch block, ie the try body is always a predecessor | 1581 // try/catch block, ie the try body is always a predecessor |
1584 // of the catch and finally. Here, we continue visiting the try | 1582 // of the catch and finally. Here, we continue visiting the try |
1585 // body by visiting the block that contains the user-level control | 1583 // body by visiting the block that contains the user-level control |
1586 // flow instruction. | 1584 // flow instruction. |
1587 continueSubGraph(node.bodyTrySuccessor); | 1585 continueSubGraph(node.bodyTrySuccessor); |
1588 } | 1586 } |
1589 | 1587 |
1590 visitTry(HTry node) { | 1588 visitTry(HTry node) { |
1591 // We should never get here. Try/catch/finally is always handled using block | 1589 // We should never get here. Try/catch/finally is always handled using block |
1592 // information in [visitTryInfo]. | 1590 // information in [visitTryInfo]. |
1593 throw new SpannableAssertionFailure(node, 'visitTry should not be called.'); | 1591 failedAt(node, 'visitTry should not be called.'); |
1594 } | 1592 } |
1595 | 1593 |
1596 bool tryControlFlowOperation(HIf node) { | 1594 bool tryControlFlowOperation(HIf node) { |
1597 if (!controlFlowOperators.contains(node)) return false; | 1595 if (!controlFlowOperators.contains(node)) return false; |
1598 HPhi phi = node.joinBlock.phis.first; | 1596 HPhi phi = node.joinBlock.phis.first; |
1599 bool atUseSite = isGenerateAtUseSite(phi); | 1597 bool atUseSite = isGenerateAtUseSite(phi); |
1600 // Don't generate a conditional operator in this situation: | 1598 // Don't generate a conditional operator in this situation: |
1601 // i = condition ? bar() : i; | 1599 // i = condition ? bar() : i; |
1602 // But generate this instead: | 1600 // But generate this instead: |
1603 // if (condition) i = bar(); | 1601 // if (condition) i = bar(); |
(...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2890 return pop(); | 2888 return pop(); |
2891 } else if (checkedType.containsOnlyBool(_closedWorld)) { | 2889 } else if (checkedType.containsOnlyBool(_closedWorld)) { |
2892 // input is !bool | 2890 // input is !bool |
2893 checkBool(input, '!==', input.sourceInformation); | 2891 checkBool(input, '!==', input.sourceInformation); |
2894 return pop(); | 2892 return pop(); |
2895 } else if (checkedType.containsOnlyString(_closedWorld)) { | 2893 } else if (checkedType.containsOnlyString(_closedWorld)) { |
2896 // input is !string | 2894 // input is !string |
2897 checkString(input, '!==', input.sourceInformation); | 2895 checkString(input, '!==', input.sourceInformation); |
2898 return pop(); | 2896 return pop(); |
2899 } | 2897 } |
2900 throw new SpannableAssertionFailure( | 2898 throw failedAt(input, 'Unexpected check: $checkedType.'); |
2901 input, 'Unexpected check: $checkedType.'); | |
2902 } | 2899 } |
2903 | 2900 |
2904 void visitTypeConversion(HTypeConversion node) { | 2901 void visitTypeConversion(HTypeConversion node) { |
2905 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) { | 2902 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) { |
2906 js.Expression test = generateReceiverOrArgumentTypeTest(node); | 2903 js.Expression test = generateReceiverOrArgumentTypeTest(node); |
2907 js.Block oldContainer = currentContainer; | 2904 js.Block oldContainer = currentContainer; |
2908 js.Statement body = new js.Block.empty(); | 2905 js.Statement body = new js.Block.empty(); |
2909 currentContainer = body; | 2906 currentContainer = body; |
2910 if (node.isArgumentTypeCheck) { | 2907 if (node.isArgumentTypeCheck) { |
2911 generateThrowWithHelper( | 2908 generateThrowWithHelper( |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3041 return _closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) { | 3038 return _closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) { |
3042 return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls); | 3039 return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls); |
3043 }); | 3040 }); |
3044 } | 3041 } |
3045 | 3042 |
3046 @override | 3043 @override |
3047 void visitRef(HRef node) { | 3044 void visitRef(HRef node) { |
3048 visit(node.value); | 3045 visit(node.value); |
3049 } | 3046 } |
3050 } | 3047 } |
OLD | NEW |