| 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 class SsaCodeGeneratorTask extends CompilerTask { | 5 class SsaCodeGeneratorTask extends CompilerTask { |
| 6 SsaCodeGeneratorTask(Compiler compiler) : super(compiler); | 6 SsaCodeGeneratorTask(Compiler compiler) : super(compiler); |
| 7 String get name() => 'SSA code generator'; | 7 String get name() => 'SSA code generator'; |
| 8 | 8 |
| 9 | 9 |
| 10 String buildJavaScriptFunction(FunctionElement element, | 10 String buildJavaScriptFunction(FunctionElement element, |
| (...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 addIndented("}"); | 588 addIndented("}"); |
| 589 if (info.elseGraph !== null) { | 589 if (info.elseGraph !== null) { |
| 590 buffer.add(" else {\n"); | 590 buffer.add(" else {\n"); |
| 591 indent++; | 591 indent++; |
| 592 generateStatements(info.elseGraph); | 592 generateStatements(info.elseGraph); |
| 593 indent--; | 593 indent--; |
| 594 addIndented("}"); | 594 addIndented("}"); |
| 595 } | 595 } |
| 596 buffer.add("\n"); | 596 buffer.add("\n"); |
| 597 } | 597 } |
| 598 if (info.joinBlock !== null) { | |
| 599 visitBasicBlock(info.joinBlock); | |
| 600 } | |
| 601 return true; | 598 return true; |
| 602 } | 599 } |
| 603 | 600 |
| 601 bool visitSequenceInfo(HStatementSequenceInformation info) { |
| 602 return false; |
| 603 } |
| 604 |
| 604 bool visitSubGraphInfo(HSubGraphBlockInformation info) { | 605 bool visitSubGraphInfo(HSubGraphBlockInformation info) { |
| 605 visitSubGraph(info.subGraph); | 606 visitSubGraph(info.subGraph); |
| 606 // A [HSubGraphBlockInformation] is always part of another block | 607 // A [HSubGraphBlockInformation] is always part of another block |
| 607 // information structure, so it doesn't have a joinBlock. | 608 // information structure, so it doesn't have a joinBlock. |
| 608 } | 609 } |
| 609 | 610 |
| 610 bool visitSubExpressionInfo(HSubExpressionBlockInformation info) { | 611 bool visitSubExpressionInfo(HSubExpressionBlockInformation info) { |
| 611 return false; | 612 return false; |
| 612 } | 613 } |
| 613 | 614 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 634 addIndented('}'); | 635 addIndented('}'); |
| 635 } | 636 } |
| 636 if (info.finallyBlock != null) { | 637 if (info.finallyBlock != null) { |
| 637 buffer.add(" finally {\n"); | 638 buffer.add(" finally {\n"); |
| 638 indent++; | 639 indent++; |
| 639 generateStatements(info.finallyBlock); | 640 generateStatements(info.finallyBlock); |
| 640 indent--; | 641 indent--; |
| 641 addIndented("}"); | 642 addIndented("}"); |
| 642 } | 643 } |
| 643 buffer.add("\n"); | 644 buffer.add("\n"); |
| 644 visitBasicBlock(info.joinBlock); | |
| 645 return true; | 645 return true; |
| 646 } | 646 } |
| 647 | 647 |
| 648 bool visitLoopInfo(HLoopInformation info) { | 648 bool visitLoopInfo(HLoopBlockInformation info) { |
| 649 // We must look at the loop information only once, when visiting the | |
| 650 // initializer. After that, the initializer has been generated. | |
| 651 // The same block information is also put on the condition-block for | |
| 652 // the traditional code generation. | |
| 653 bool isInitializerBlock = (currentBlock !== info.header); | |
| 654 if (!isInitializerBlock && info.kind != HLoopInformation.DO_WHILE_LOOP) { | |
| 655 return false; | |
| 656 } | |
| 657 | |
| 658 HExpressionInformation condition = info.condition; | 649 HExpressionInformation condition = info.condition; |
| 659 bool isConditionExpression = isJSCondition(condition); | 650 bool isConditionExpression = isJSCondition(condition); |
| 660 | 651 |
| 661 void visitBodyIgnoreLabels() { | 652 void visitBodyIgnoreLabels() { |
| 662 if (info.body.start.isLabeledBlock()) { | 653 if (info.body.start.isLabeledBlock()) { |
| 663 HBlockInformation oldInfo = currentBlockInformation; | 654 HBlockInformation oldInfo = currentBlockInformation; |
| 664 currentBlockInformation = info.body.start.blockInformation; | 655 currentBlockInformation = info.body.start.blockFlow.body; |
| 665 generateStatements(info.body); | 656 generateStatements(info.body); |
| 666 currentBlockInformation = oldInfo; | 657 currentBlockInformation = oldInfo; |
| 667 } else { | 658 } else { |
| 668 generateStatements(info.body); | 659 generateStatements(info.body); |
| 669 } | 660 } |
| 670 } | 661 } |
| 671 | 662 |
| 672 switch (info.kind) { | 663 switch (info.kind) { |
| 673 // Treate all three "test-first" loops the same way. | 664 // Treate all three "test-first" loops the same way. |
| 674 case HLoopInformation.FOR_LOOP: | 665 case HLoopBlockInformation.FOR_LOOP: |
| 675 case HLoopInformation.WHILE_LOOP: | 666 case HLoopBlockInformation.WHILE_LOOP: |
| 676 case HLoopInformation.FOR_IN_LOOP: { | 667 case HLoopBlockInformation.FOR_IN_LOOP: { |
| 677 HBlockInformation initialization = info.initializer; | 668 HBlockInformation initialization = info.initializer; |
| 678 int initializationType = TYPE_STATEMENT; | 669 int initializationType = TYPE_STATEMENT; |
| 679 if (initialization !== null) { | 670 if (initialization !== null) { |
| 680 initializationType = expressionType(initialization); | 671 initializationType = expressionType(initialization); |
| 681 if (initializationType == TYPE_STATEMENT) { | 672 if (initializationType == TYPE_STATEMENT) { |
| 682 generateStatements(initialization); | 673 generateStatements(initialization); |
| 683 initialization = null; | 674 initialization = null; |
| 684 } | 675 } |
| 685 } | 676 } |
| 686 for (LabelElement label in info.labels) { | 677 for (LabelElement label in info.labels) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 wrapLoopBodyForContinue(info); | 728 wrapLoopBodyForContinue(info); |
| 738 generateStatements(info.updates); | 729 generateStatements(info.updates); |
| 739 } else { | 730 } else { |
| 740 visitBodyIgnoreLabels(); | 731 visitBodyIgnoreLabels(); |
| 741 } | 732 } |
| 742 indent--; | 733 indent--; |
| 743 } | 734 } |
| 744 addIndented("}\n"); | 735 addIndented("}\n"); |
| 745 break; | 736 break; |
| 746 } | 737 } |
| 747 case HLoopInformation.DO_WHILE_LOOP: { | 738 case HLoopBlockInformation.DO_WHILE_LOOP: { |
| 748 // Generate do-while loop in all cases. | 739 // Generate do-while loop in all cases. |
| 749 if (info.initializer !== null) { | 740 if (info.initializer !== null) { |
| 750 generateStatements(info.initializer); | 741 generateStatements(info.initializer); |
| 751 } | 742 } |
| 752 addIndentation(); | 743 addIndentation(); |
| 753 for (LabelElement label in info.labels) { | 744 for (LabelElement label in info.labels) { |
| 754 if (label.isTarget) { | 745 if (label.isTarget) { |
| 755 writeLabel(label); | 746 writeLabel(label); |
| 756 buffer.add(":"); | 747 buffer.add(":"); |
| 757 } | 748 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 778 use(condition.conditionExpression, JSPrecedence.PREFIX_PRECEDENCE); | 769 use(condition.conditionExpression, JSPrecedence.PREFIX_PRECEDENCE); |
| 779 buffer.add(");\n"); | 770 buffer.add(");\n"); |
| 780 } | 771 } |
| 781 break; | 772 break; |
| 782 } | 773 } |
| 783 default: | 774 default: |
| 784 compiler.internalError( | 775 compiler.internalError( |
| 785 'Unexpected loop kind: ${info.kind}', | 776 'Unexpected loop kind: ${info.kind}', |
| 786 instruction: condition.conditionExpression); | 777 instruction: condition.conditionExpression); |
| 787 } | 778 } |
| 788 visitBasicBlock(info.joinBlock); | |
| 789 return true; | 779 return true; |
| 790 } | 780 } |
| 791 | 781 |
| 792 bool visitLabeledBlockInfo(HLabeledBlockInformation labeledBlockInfo) { | 782 bool visitLabeledBlockInfo(HLabeledBlockInformation labeledBlockInfo) { |
| 793 preLabeledBlock(labeledBlockInfo); | 783 preLabeledBlock(labeledBlockInfo); |
| 794 addIndentation(); | 784 addIndentation(); |
| 795 Link<Element> continueOverrides = const EmptyLink<Element>(); | 785 Link<Element> continueOverrides = const EmptyLink<Element>(); |
| 796 // If [labeledBlockInfo.isContinue], the block is an artificial | 786 // If [labeledBlockInfo.isContinue], the block is an artificial |
| 797 // block around the body of a loop with an update block, so that | 787 // block around the body of a loop with an update block, so that |
| 798 // continues of the loop can be written as breaks of the body | 788 // continues of the loop can be written as breaks of the body |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 buffer.add('{\n'); | 824 buffer.add('{\n'); |
| 835 indent++; | 825 indent++; |
| 836 | 826 |
| 837 startLabeledBlock(labeledBlockInfo); | 827 startLabeledBlock(labeledBlockInfo); |
| 838 generateStatements(labeledBlockInfo.body); | 828 generateStatements(labeledBlockInfo.body); |
| 839 endLabeledBlock(labeledBlockInfo); | 829 endLabeledBlock(labeledBlockInfo); |
| 840 | 830 |
| 841 indent--; | 831 indent--; |
| 842 addIndented('}\n'); | 832 addIndented('}\n'); |
| 843 | 833 |
| 844 if (labeledBlockInfo.joinBlock !== null) { | |
| 845 visitBasicBlock(labeledBlockInfo.joinBlock); | |
| 846 } | |
| 847 if (labeledBlockInfo.isContinue) { | 834 if (labeledBlockInfo.isContinue) { |
| 848 while (!continueOverrides.isEmpty()) { | 835 while (!continueOverrides.isEmpty()) { |
| 849 continueAction.remove(continueOverrides.head); | 836 continueAction.remove(continueOverrides.head); |
| 850 continueOverrides = continueOverrides.tail; | 837 continueOverrides = continueOverrides.tail; |
| 851 } | 838 } |
| 852 } else { | 839 } else { |
| 853 breakAction.remove(labeledBlockInfo.target); | 840 breakAction.remove(labeledBlockInfo.target); |
| 854 } | 841 } |
| 855 return true; | 842 return true; |
| 856 } | 843 } |
| 857 | 844 |
| 858 void emitLogicalOperation(HPhi node, String operation) { | 845 void emitLogicalOperation(HPhi node, String operation) { |
| 859 JSBinaryOperatorPrecedence operatorPrecedence = | 846 JSBinaryOperatorPrecedence operatorPrecedence = |
| 860 JSPrecedence.binary[operation]; | 847 JSPrecedence.binary[operation]; |
| 861 beginExpression(operatorPrecedence.precedence); | 848 beginExpression(operatorPrecedence.precedence); |
| 862 use(node.inputs[0], operatorPrecedence.left); | 849 use(node.inputs[0], operatorPrecedence.left); |
| 863 buffer.add(" $operation "); | 850 buffer.add(" $operation "); |
| 864 use(node.inputs[1], operatorPrecedence.right); | 851 use(node.inputs[1], operatorPrecedence.right); |
| 865 endExpression(operatorPrecedence.precedence); | 852 endExpression(operatorPrecedence.precedence); |
| 866 } | 853 } |
| 867 | 854 |
| 868 // Wraps a loop body in a block to make continues have a target to break | 855 // Wraps a loop body in a block to make continues have a target to break |
| 869 // to (if necessary). | 856 // to (if necessary). |
| 870 void wrapLoopBodyForContinue(HLoopInformation info) { | 857 void wrapLoopBodyForContinue(HLoopBlockInformation info) { |
| 871 TargetElement target = info.target; | 858 TargetElement target = info.target; |
| 872 if (target !== null && target.isContinueTarget) { | 859 if (target !== null && target.isContinueTarget) { |
| 873 addIndentation(); | 860 addIndentation(); |
| 874 for (LabelElement label in info.labels) { | 861 for (LabelElement label in info.labels) { |
| 875 if (label.isContinueTarget) { | 862 if (label.isContinueTarget) { |
| 876 writeContinueLabel(label); | 863 writeContinueLabel(label); |
| 877 buffer.add(":"); | 864 buffer.add(":"); |
| 878 continueAction[label] = continueAsBreak; | 865 continueAction[label] = continueAsBreak; |
| 879 } | 866 } |
| 880 } | 867 } |
| 881 writeImplicitContinueLabel(target); | 868 writeImplicitContinueLabel(target); |
| 882 buffer.add(":{\n"); | 869 buffer.add(":{\n"); |
| 883 continueAction[info.target] = implicitContinueAsBreak; | 870 continueAction[info.target] = implicitContinueAsBreak; |
| 884 indent++; | 871 indent++; |
| 885 generateStatements(info.body); | 872 generateStatements(info.body); |
| 886 indent--; | 873 indent--; |
| 887 addIndented("}\n"); | 874 addIndented("}\n"); |
| 888 continueAction.remove(info.target); | 875 continueAction.remove(info.target); |
| 889 for (LabelElement label in info.labels) { | 876 for (LabelElement label in info.labels) { |
| 890 if (label.isContinueTarget) { | 877 if (label.isContinueTarget) { |
| 891 continueAction.remove(label); | 878 continueAction.remove(label); |
| 892 } | 879 } |
| 893 } | 880 } |
| 894 } else { | 881 } else { |
| 895 // Loop body contains no continues, so we don't need a break target. | 882 // Loop body contains no continues, so we don't need a break target. |
| 896 generateStatements(info.body); | 883 generateStatements(info.body); |
| 897 } | 884 } |
| 898 } | 885 } |
| 899 | 886 |
| 887 bool handleBlockFlow(HBlockFlow block) { |
| 888 HBlockInformation info = block.body; |
| 889 // If we reach here again while handling the attached information, |
| 890 // e.g., because we call visitSubGraph on a subgraph starting on |
| 891 // the same block, don't handle it again. |
| 892 // When the structure graph is complete, we will be able to have |
| 893 // different structures starting on the same basic block (e.g., an |
| 894 // "if" and its condition). |
| 895 if (info === currentBlockInformation) return false; |
| 896 |
| 897 HBlockInformation oldBlockInformation = currentBlockInformation; |
| 898 currentBlockInformation = info; |
| 899 bool success = info.accept(this); |
| 900 currentBlockInformation = oldBlockInformation; |
| 901 if (success) { |
| 902 HBasicBlock continuation = block.continuation; |
| 903 if (continuation !== null) { |
| 904 visitBasicBlock(continuation); |
| 905 } |
| 906 } |
| 907 return success; |
| 908 } |
| 909 |
| 900 void visitBasicBlock(HBasicBlock node) { | 910 void visitBasicBlock(HBasicBlock node) { |
| 901 // Abort traversal if we are leaving the currently active sub-graph. | 911 // Abort traversal if we are leaving the currently active sub-graph. |
| 902 if (!subGraph.contains(node)) return; | 912 if (!subGraph.contains(node)) return; |
| 903 | 913 |
| 904 currentBlock = node; | 914 currentBlock = node; |
| 905 // If this node has special behavior attached, handle it. | 915 // If this node has block-structure based information attached, |
| 906 // If we reach here again while handling the attached information, | 916 // try using that to traverse from here. |
| 907 // e.g., because we call visitSubGraph on a subgraph starting here, | 917 if (node.blockFlow !== null && |
| 908 // don't handle it again. | 918 handleBlockFlow(node.blockFlow)) { |
| 909 if (node.blockInformation !== null && | 919 return; |
| 910 node.blockInformation !== currentBlockInformation) { | 920 } |
| 911 HBlockInformation oldBlockInformation = currentBlockInformation; | 921 // Flow based traversal. |
| 912 currentBlockInformation = node.blockInformation; | 922 if (node.isLoopHeader() && |
| 913 bool success = currentBlockInformation.accept(this); | 923 node.loopInformation.loopBlockInformation !== currentBlockInformation) { |
| 914 currentBlockInformation = oldBlockInformation; | 924 beginLoop(node); |
| 915 if (success) return; | |
| 916 | |
| 917 // If our special handling didn't succeed, we have to emit a generic | |
| 918 // version. This still requires special handling for loop-blocks | |
| 919 if (node.isLoopHeader()) { | |
| 920 beginLoop(node); | |
| 921 } | |
| 922 } | 925 } |
| 923 iterateBasicBlock(node); | 926 iterateBasicBlock(node); |
| 924 } | 927 } |
| 925 | 928 |
| 926 /** Generates the assignments for all phis of successors blocks. */ | 929 /** Generates the assignments for all phis of successors blocks. */ |
| 927 void assignPhisOfAllSuccessors(HBasicBlock node) { | 930 void assignPhisOfAllSuccessors(HBasicBlock node) { |
| 928 Map<HInstruction, String> temporaryNamesOfPhis = null; | 931 Map<HInstruction, String> temporaryNamesOfPhis = null; |
| 929 | 932 |
| 930 /** | 933 /** |
| 931 * Generates the assignment [canonicalPhi] = [value]. | 934 * Generates the assignment [canonicalPhi] = [value]. |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 visitIf(HIf node) { | 1309 visitIf(HIf node) { |
| 1307 if (subGraph !== null && node.block === subGraph.end) { | 1310 if (subGraph !== null && node.block === subGraph.end) { |
| 1308 if (isGeneratingExpression()) { | 1311 if (isGeneratingExpression()) { |
| 1309 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE); | 1312 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE); |
| 1310 } | 1313 } |
| 1311 return; | 1314 return; |
| 1312 } | 1315 } |
| 1313 HInstruction condition = node.inputs[0]; | 1316 HInstruction condition = node.inputs[0]; |
| 1314 int preVisitedBlocks = 0; | 1317 int preVisitedBlocks = 0; |
| 1315 List<HBasicBlock> dominated = node.block.dominatedBlocks; | 1318 List<HBasicBlock> dominated = node.block.dominatedBlocks; |
| 1316 HIfBlockInformation info = node.blockInformation; | 1319 HIfBlockInformation info = node.blockInformation.body; |
| 1317 if (condition.isConstant()) { | 1320 if (condition.isConstant()) { |
| 1318 HConstant constant = condition; | 1321 HConstant constant = condition; |
| 1319 if (constant.constant.isTrue()) { | 1322 if (constant.constant.isTrue()) { |
| 1320 generateStatements(info.thenGraph); | 1323 generateStatements(info.thenGraph); |
| 1321 } else if (node.hasElse) { | 1324 } else if (node.hasElse) { |
| 1322 generateStatements(info.elseGraph); | 1325 generateStatements(info.elseGraph); |
| 1323 } | 1326 } |
| 1324 // We ignore the other branch, even if it isn't visited. | 1327 // We ignore the other branch, even if it isn't visited. |
| 1325 preVisitedBlocks = node.hasElse ? 2 : 1; | 1328 preVisitedBlocks = node.hasElse ? 2 : 1; |
| 1326 } else { | 1329 } else { |
| 1327 startIf(node); | 1330 startIf(node); |
| 1328 assert(!isGenerateAtUseSite(node)); | 1331 assert(!isGenerateAtUseSite(node)); |
| 1329 startThen(node); | 1332 startThen(node); |
| 1330 assert(node.thenBlock === dominated[0]); | 1333 assert(node.thenBlock === dominated[0]); |
| 1331 generateStatements(info.thenGraph); | 1334 generateStatements(info.thenGraph); |
| 1332 preVisitedBlocks++; | 1335 preVisitedBlocks++; |
| 1333 endThen(node); | 1336 endThen(node); |
| 1334 if (node.hasElse) { | 1337 if (node.hasElse) { |
| 1335 startElse(node); | 1338 startElse(node); |
| 1336 assert(node.elseBlock === dominated[1]); | 1339 assert(node.elseBlock === dominated[1]); |
| 1337 generateStatements(info.elseGraph); | 1340 generateStatements(info.elseGraph); |
| 1338 preVisitedBlocks++; | 1341 preVisitedBlocks++; |
| 1339 endElse(node); | 1342 endElse(node); |
| 1340 } | 1343 } |
| 1341 endIf(node); | 1344 endIf(node); |
| 1342 } | 1345 } |
| 1343 if (info.joinBlock !== null && info.joinBlock.dominator !== node.block) { | 1346 HBasicBlock joinBlock = node.joinBlock; |
| 1347 if (joinBlock !== null && joinBlock.dominator !== node.block) { |
| 1344 // The join block is dominated by a block in one of the branches. | 1348 // The join block is dominated by a block in one of the branches. |
| 1345 // The subgraph traversal never reached it, so we visit it here | 1349 // The subgraph traversal never reached it, so we visit it here |
| 1346 // instead. | 1350 // instead. |
| 1347 visitBasicBlock(info.joinBlock); | 1351 visitBasicBlock(joinBlock); |
| 1348 } | 1352 } |
| 1349 | 1353 |
| 1350 // Visit all the dominated blocks that are not part of the then or else | 1354 // Visit all the dominated blocks that are not part of the then or else |
| 1351 // branches, and is not the join block. | 1355 // branches, and is not the join block. |
| 1352 // Depending on how the then/else branches terminate | 1356 // Depending on how the then/else branches terminate |
| 1353 // (e.g., return/throw/break) there can be any number of these. | 1357 // (e.g., return/throw/break) there can be any number of these. |
| 1354 int dominatedCount = dominated.length; | 1358 int dominatedCount = dominated.length; |
| 1355 for (int i = preVisitedBlocks; i < dominatedCount; i++) { | 1359 for (int i = preVisitedBlocks; i < dominatedCount; i++) { |
| 1356 HBasicBlock dominatedBlock = dominated[i]; | 1360 HBasicBlock dominatedBlock = dominated[i]; |
| 1357 assert(dominatedBlock.dominator === node.block); | 1361 assert(dominatedBlock.dominator === node.block); |
| (...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2190 buffer.add(')) '); | 2194 buffer.add(')) '); |
| 2191 bailout(node, 'Not a string or array'); | 2195 bailout(node, 'Not a string or array'); |
| 2192 } else { | 2196 } else { |
| 2193 unreachable(); | 2197 unreachable(); |
| 2194 } | 2198 } |
| 2195 buffer.add(';\n'); | 2199 buffer.add(';\n'); |
| 2196 } | 2200 } |
| 2197 | 2201 |
| 2198 void beginLoop(HBasicBlock block) { | 2202 void beginLoop(HBasicBlock block) { |
| 2199 addIndentation(); | 2203 addIndentation(); |
| 2200 HLoopInformation info = block.blockInformation; | 2204 HLoopInformation info = block.loopInformation; |
| 2201 for (LabelElement label in info.labels) { | 2205 for (LabelElement label in info.labels) { |
| 2202 writeLabel(label); | 2206 writeLabel(label); |
| 2203 buffer.add(":"); | 2207 buffer.add(":"); |
| 2204 } | 2208 } |
| 2205 buffer.add('while (true) {\n'); | 2209 buffer.add('while (true) {\n'); |
| 2206 indent++; | 2210 indent++; |
| 2207 } | 2211 } |
| 2208 | 2212 |
| 2209 void endLoop(HBasicBlock block) { | 2213 void endLoop(HBasicBlock block) { |
| 2210 indent--; | 2214 indent--; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2314 } else if (argument is HTypeGuard) { | 2318 } else if (argument is HTypeGuard) { |
| 2315 HTypeGuard instruction = argument; | 2319 HTypeGuard instruction = argument; |
| 2316 return unwrap(instruction.guarded); | 2320 return unwrap(instruction.guarded); |
| 2317 } else { | 2321 } else { |
| 2318 return argument; | 2322 return argument; |
| 2319 } | 2323 } |
| 2320 } | 2324 } |
| 2321 | 2325 |
| 2322 bool visitAndOrInfo(HAndOrBlockInformation info) => false; | 2326 bool visitAndOrInfo(HAndOrBlockInformation info) => false; |
| 2323 bool visitIfInfo(HIfBlockInformation info) => false; | 2327 bool visitIfInfo(HIfBlockInformation info) => false; |
| 2324 bool visitLoopInfo(HLoopInformation info) => false; | 2328 bool visitLoopInfo(HLoopBlockInformation info) => false; |
| 2325 bool visitTryInfo(HTryBlockInformation info) => false; | 2329 bool visitTryInfo(HTryBlockInformation info) => false; |
| 2326 | 2330 bool visitSequenceInfo(HStatementSequenceInformation info) => false; |
| 2327 | 2331 |
| 2328 void visitTypeGuard(HTypeGuard node) { | 2332 void visitTypeGuard(HTypeGuard node) { |
| 2329 indent--; | 2333 indent--; |
| 2330 addIndented('case ${node.state}:\n'); | 2334 addIndented('case ${node.state}:\n'); |
| 2331 indent++; | 2335 indent++; |
| 2332 addIndented('state = 0;\n'); | 2336 addIndented('state = 0;\n'); |
| 2333 | 2337 |
| 2334 setup.add(' case ${node.state}:\n'); | 2338 setup.add(' case ${node.state}:\n'); |
| 2335 int i = 0; | 2339 int i = 0; |
| 2336 for (HInstruction input in node.inputs) { | 2340 for (HInstruction input in node.inputs) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2370 } | 2374 } |
| 2371 | 2375 |
| 2372 void beginLoop(HBasicBlock block) { | 2376 void beginLoop(HBasicBlock block) { |
| 2373 // TODO(ngeoffray): Don't put labels on loops that don't bailout. | 2377 // TODO(ngeoffray): Don't put labels on loops that don't bailout. |
| 2374 String newLabel = pushLabel(); | 2378 String newLabel = pushLabel(); |
| 2375 if (block.hasGuards()) { | 2379 if (block.hasGuards()) { |
| 2376 startBailoutCase(block.guards, const <HTypeGuard>[]); | 2380 startBailoutCase(block.guards, const <HTypeGuard>[]); |
| 2377 } | 2381 } |
| 2378 | 2382 |
| 2379 addIndentation(); | 2383 addIndentation(); |
| 2380 HLoopInformation loopInformation = block.blockInformation; | 2384 HLoopInformation loopInformation = block.loopInformation; |
| 2381 for (LabelElement label in loopInformation.labels) { | 2385 for (LabelElement label in loopInformation.labels) { |
| 2382 writeLabel(label); | 2386 writeLabel(label); |
| 2383 buffer.add(":"); | 2387 buffer.add(":"); |
| 2384 } | 2388 } |
| 2385 buffer.add('$newLabel: while (true) {\n'); | 2389 buffer.add('$newLabel: while (true) {\n'); |
| 2386 indent++; | 2390 indent++; |
| 2387 | 2391 |
| 2388 if (block.hasGuards()) { | 2392 if (block.hasGuards()) { |
| 2389 startBailoutSwitch(); | 2393 startBailoutSwitch(); |
| 2390 if (loopInformation.target !== null) { | 2394 if (loopInformation.target !== null) { |
| 2391 breakAction[loopInformation.target] = (TargetElement target) { | 2395 breakAction[loopInformation.target] = (TargetElement target) { |
| 2392 addIndented("break $newLabel;\n"); | 2396 addIndented("break $newLabel;\n"); |
| 2393 }; | 2397 }; |
| 2394 } | 2398 } |
| 2395 } | 2399 } |
| 2396 } | 2400 } |
| 2397 | 2401 |
| 2398 void endLoop(HBasicBlock block) { | 2402 void endLoop(HBasicBlock block) { |
| 2399 popLabel(); | 2403 popLabel(); |
| 2400 HBasicBlock header = block.isLoopHeader() ? block : block.parentLoopHeader; | 2404 HBasicBlock header = block.isLoopHeader() ? block : block.parentLoopHeader; |
| 2401 if (header.hasGuards()) { | 2405 if (header.hasGuards()) { |
| 2402 endBailoutSwitch(); | 2406 endBailoutSwitch(); |
| 2403 HLoopInformation info = header.blockInformation; | 2407 HLoopInformation info = header.loopInformation; |
| 2404 if (info.target != null) breakAction.remove(info.target); | 2408 if (info.target != null) breakAction.remove(info.target); |
| 2405 } | 2409 } |
| 2406 indent--; | 2410 indent--; |
| 2407 addIndented('}\n'); // Close 'while'. | 2411 addIndented('}\n'); // Close 'while'. |
| 2408 } | 2412 } |
| 2409 | 2413 |
| 2410 void handleLoopCondition(HLoopBranch node) { | 2414 void handleLoopCondition(HLoopBranch node) { |
| 2411 buffer.add('if (!'); | 2415 buffer.add('if (!'); |
| 2412 use(node.inputs[0], JSPrecedence.PREFIX_PRECEDENCE); | 2416 use(node.inputs[0], JSPrecedence.PREFIX_PRECEDENCE); |
| 2413 buffer.add(') break ${currentLabel()};\n'); | 2417 buffer.add(') break ${currentLabel()};\n'); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2487 startBailoutSwitch(); | 2491 startBailoutSwitch(); |
| 2488 } | 2492 } |
| 2489 } | 2493 } |
| 2490 | 2494 |
| 2491 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 2495 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
| 2492 if (labeledBlockInfo.body.start.hasGuards()) { | 2496 if (labeledBlockInfo.body.start.hasGuards()) { |
| 2493 endBailoutSwitch(); | 2497 endBailoutSwitch(); |
| 2494 } | 2498 } |
| 2495 } | 2499 } |
| 2496 } | 2500 } |
| OLD | NEW |