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 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 if (!isExpression) { | 758 if (!isExpression) { |
759 generateStatements(info.expression); | 759 generateStatements(info.expression); |
760 } | 760 } |
761 | 761 |
762 if (isExpression) { | 762 if (isExpression) { |
763 push(generateExpression(info.expression)); | 763 push(generateExpression(info.expression)); |
764 } else { | 764 } else { |
765 use(info.expression.conditionExpression); | 765 use(info.expression.conditionExpression); |
766 } | 766 } |
767 js.Expression key = pop(); | 767 js.Expression key = pop(); |
| 768 bool handledDefault = false; |
768 List<js.SwitchClause> cases = <js.SwitchClause>[]; | 769 List<js.SwitchClause> cases = <js.SwitchClause>[]; |
769 HSwitch switchInstruction = info.expression.end.last; | 770 HSwitch switchInstruction = info.expression.end.last; |
770 List<HInstruction> inputs = switchInstruction.inputs; | 771 List<HInstruction> inputs = switchInstruction.inputs; |
771 List<HBasicBlock> successors = switchInstruction.block.successors; | 772 List<HBasicBlock> successors = switchInstruction.block.successors; |
772 | 773 |
773 js.Block oldContainer = currentContainer; | 774 js.Block oldContainer = currentContainer; |
774 for (int inputIndex = 1, statementIndex = 0; | 775 for (int inputIndex = 1, statementIndex = 0; |
775 inputIndex < inputs.length; | 776 inputIndex < inputs.length; |
776 statementIndex++) { | 777 statementIndex++) { |
777 HBasicBlock successor = successors[inputIndex - 1]; | 778 HBasicBlock successor = successors[inputIndex - 1]; |
778 // If liveness analysis has figured out that this case is dead, | 779 // If liveness analysis has figured out that this case is dead, |
779 // omit the code for it. | 780 // omit the code for it. |
780 if (successor.isLive) { | 781 if (successor.isLive) { |
781 do { | 782 do { |
782 visit(inputs[inputIndex]); | 783 visit(inputs[inputIndex]); |
783 currentContainer = new js.Block.empty(); | 784 currentContainer = new js.Block.empty(); |
784 cases.add(new js.Case(pop(), currentContainer)); | 785 cases.add(new js.Case(pop(), currentContainer)); |
785 inputIndex++; | 786 inputIndex++; |
786 } while ((successors[inputIndex - 1] == successor) && | 787 } while ((successors[inputIndex - 1] == successor) && |
787 (inputIndex < inputs.length)); | 788 (inputIndex < inputs.length)); |
788 | 789 |
| 790 // If this is the last statement, then these cases also belong to the |
| 791 // default block. |
| 792 if (statementIndex == info.statements.length - 1) { |
| 793 currentContainer = new js.Block.empty(); |
| 794 cases.add(new js.Default(currentContainer)); |
| 795 handledDefault = true; |
| 796 } |
| 797 |
789 generateStatements(info.statements[statementIndex]); | 798 generateStatements(info.statements[statementIndex]); |
790 } else { | 799 } else { |
791 // Skip all the case statements that belong to this | 800 // Skip all the case statements that belong to this |
792 // block. | 801 // block. |
793 while ((successors[inputIndex - 1] == successor) && | 802 while ((successors[inputIndex - 1] == successor) && |
794 (inputIndex < inputs.length)) { | 803 (inputIndex < inputs.length)) { |
795 ++inputIndex; | 804 ++inputIndex; |
796 } | 805 } |
797 } | 806 } |
798 } | 807 } |
799 | 808 |
800 // If the default case is dead, we omit it. Likewise, if it is an | 809 // If the default case is dead, we omit it. Likewise, if it is an |
801 // empty block, we omit it, too. | 810 // empty block, we omit it, too. |
802 if (info.statements.last.start.isLive) { | 811 if (info.statements.last.start.isLive && !handledDefault) { |
803 currentContainer = new js.Block.empty(); | 812 currentContainer = new js.Block.empty(); |
804 generateStatements(info.statements.last); | 813 generateStatements(info.statements.last); |
805 if (currentContainer.statements.isNotEmpty) { | 814 if (currentContainer.statements.isNotEmpty) { |
806 cases.add(new js.Default(currentContainer)); | 815 cases.add(new js.Default(currentContainer)); |
807 } | 816 } |
808 } | 817 } |
809 | 818 |
810 currentContainer = oldContainer; | 819 currentContainer = oldContainer; |
811 | 820 |
812 js.Statement result = new js.Switch(key, cases); | 821 js.Statement result = new js.Switch(key, cases); |
(...skipping 2217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3030 return _closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) { | 3039 return _closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) { |
3031 return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls); | 3040 return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls); |
3032 }); | 3041 }); |
3033 } | 3042 } |
3034 | 3043 |
3035 @override | 3044 @override |
3036 void visitRef(HRef node) { | 3045 void visitRef(HRef node) { |
3037 visit(node.value); | 3046 visit(node.value); |
3038 } | 3047 } |
3039 } | 3048 } |
OLD | NEW |