Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(106)

Side by Side Diff: pkg/compiler/lib/src/ssa/builder_kernel.dart

Issue 2954463002: Refactoring to prepare for kernel based jump targets (Closed)
Patch Set: Updated cf. comments Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/compiler/lib/src/ssa/builder.dart ('k') | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../closure.dart'; 7 import '../closure.dart';
8 import '../common.dart'; 8 import '../common.dart';
9 import '../common/codegen.dart' show CodegenRegistry; 9 import '../common/codegen.dart' show CodegenRegistry;
10 import '../common/names.dart'; 10 import '../common/names.dart';
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 constructor.function.namedParameters.toList() 602 constructor.function.namedParameters.toList()
603 ..sort(namedOrdering) 603 ..sort(namedOrdering)
604 ..forEach(handleParameter); 604 ..forEach(handleParameter);
605 605
606 // Set the locals handler state as if we were inlining the constructor. 606 // Set the locals handler state as if we were inlining the constructor.
607 ConstructorEntity astElement = _elementMap.getConstructor(constructor); 607 ConstructorEntity astElement = _elementMap.getConstructor(constructor);
608 ClosureRepresentationInfo oldClosureData = localsHandler.closureData; 608 ClosureRepresentationInfo oldClosureData = localsHandler.closureData;
609 ClosureRepresentationInfo newClosureData = 609 ClosureRepresentationInfo newClosureData =
610 closureDataLookup.getClosureRepresentationInfo(astElement); 610 closureDataLookup.getClosureRepresentationInfo(astElement);
611 if (astElement is ConstructorElement) { 611 if (astElement is ConstructorElement) {
612 // TODO(johnniwinther): Support constructor (body) entities. 612 // TODO(redemption): Support constructor (body) entities.
613 ResolvedAst resolvedAst = astElement.resolvedAst; 613 ResolvedAst resolvedAst = astElement.resolvedAst;
614 localsHandler.closureData = newClosureData; 614 localsHandler.closureData = newClosureData;
615 if (resolvedAst.kind == ResolvedAstKind.PARSED) { 615 if (resolvedAst.kind == ResolvedAstKind.PARSED) {
616 localsHandler.enterScope( 616 localsHandler.enterScope(
617 closureDataLookup.getClosureAnalysisInfo(resolvedAst.node), 617 closureDataLookup.getClosureAnalysisInfo(resolvedAst.node),
618 forGenerativeConstructorBody: 618 forGenerativeConstructorBody:
619 astElement.isGenerativeConstructorBody); 619 astElement.isGenerativeConstructorBody);
620 } 620 }
621 } 621 }
622 inlinedFrom(astElement, () { 622 inlinedFrom(astElement, () {
(...skipping 29 matching lines...) Expand all
652 if (!backend.operatorEqHandlesNullArgument(method)) { 652 if (!backend.operatorEqHandlesNullArgument(method)) {
653 handleIf( 653 handleIf(
654 visitCondition: () { 654 visitCondition: () {
655 HParameterValue parameter = parameters.values.first; 655 HParameterValue parameter = parameters.values.first;
656 push(new HIdentity(parameter, graph.addConstantNull(closedWorld), 656 push(new HIdentity(parameter, graph.addConstantNull(closedWorld),
657 null, commonMasks.boolType)); 657 null, commonMasks.boolType));
658 }, 658 },
659 visitThen: () { 659 visitThen: () {
660 closeAndGotoExit(new HReturn( 660 closeAndGotoExit(new HReturn(
661 graph.addConstantBool(false, closedWorld), 661 graph.addConstantBool(false, closedWorld),
662 // TODO(johnniwinther): Provider source information like 662 // TODO(redemption): Provider source information like
663 // `sourceInformationBuilder.buildImplicitReturn(method)`. 663 // `sourceInformationBuilder.buildImplicitReturn(method)`.
664 null)); 664 null));
665 }, 665 },
666 visitElse: null, 666 visitElse: null,
667 // TODO(27394): Add sourceInformation via 667 // TODO(27394): Add sourceInformation via
668 // `sourceInformationBuilder.buildIf(?)`. 668 // `sourceInformationBuilder.buildIf(?)`.
669 ); 669 );
670 } 670 }
671 } 671 }
672 functionNode.body.accept(this); 672 functionNode.body.accept(this);
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 } 904 }
905 905
906 void buildBody() { 906 void buildBody() {
907 forStatement.body.accept(this); 907 forStatement.body.accept(this);
908 } 908 }
909 909
910 loopHandler.handleLoop( 910 loopHandler.handleLoop(
911 forStatement, 911 forStatement,
912 localsMap.getClosureRepresentationInfoForLoop( 912 localsMap.getClosureRepresentationInfoForLoop(
913 closureDataLookup, forStatement), 913 closureDataLookup, forStatement),
914 localsMap.getJumpTargetForFor(forStatement),
914 buildInitializer, 915 buildInitializer,
915 buildCondition, 916 buildCondition,
916 buildUpdate, 917 buildUpdate,
917 buildBody); 918 buildBody);
918 } 919 }
919 920
920 @override 921 @override
921 void visitForInStatement(ir.ForInStatement forInStatement) { 922 void visitForInStatement(ir.ForInStatement forInStatement) {
922 if (forInStatement.isAsync) { 923 if (forInStatement.isAsync) {
923 _buildAsyncForIn(forInStatement); 924 _buildAsyncForIn(forInStatement);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 HInstruction addInstruction = 1034 HInstruction addInstruction =
1034 new HAdd(index, one, null, commonMasks.positiveIntType); 1035 new HAdd(index, one, null, commonMasks.positiveIntType);
1035 add(addInstruction); 1036 add(addInstruction);
1036 localsHandler.updateLocal(indexVariable, addInstruction); 1037 localsHandler.updateLocal(indexVariable, addInstruction);
1037 } 1038 }
1038 1039
1039 loopHandler.handleLoop( 1040 loopHandler.handleLoop(
1040 forInStatement, 1041 forInStatement,
1041 localsMap.getClosureRepresentationInfoForLoop( 1042 localsMap.getClosureRepresentationInfoForLoop(
1042 closureDataLookup, forInStatement), 1043 closureDataLookup, forInStatement),
1044 localsMap.getJumpTargetForForIn(forInStatement),
1043 buildInitializer, 1045 buildInitializer,
1044 buildCondition, 1046 buildCondition,
1045 buildUpdate, 1047 buildUpdate,
1046 buildBody); 1048 buildBody);
1047 } 1049 }
1048 1050
1049 _buildForInIterator(ir.ForInStatement forInStatement) { 1051 _buildForInIterator(ir.ForInStatement forInStatement) {
1050 // Generate a structure equivalent to: 1052 // Generate a structure equivalent to:
1051 // Iterator<E> $iter = <iterable>.iterator; 1053 // Iterator<E> $iter = <iterable>.iterator;
1052 // while ($iter.moveNext()) { 1054 // while ($iter.moveNext()) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1084 if (loopVariableLocal is! SyntheticLocal) { 1086 if (loopVariableLocal is! SyntheticLocal) {
1085 value.sourceElement ??= loopVariableLocal; 1087 value.sourceElement ??= loopVariableLocal;
1086 } 1088 }
1087 forInStatement.body.accept(this); 1089 forInStatement.body.accept(this);
1088 } 1090 }
1089 1091
1090 loopHandler.handleLoop( 1092 loopHandler.handleLoop(
1091 forInStatement, 1093 forInStatement,
1092 localsMap.getClosureRepresentationInfoForLoop( 1094 localsMap.getClosureRepresentationInfoForLoop(
1093 closureDataLookup, forInStatement), 1095 closureDataLookup, forInStatement),
1096 localsMap.getJumpTargetForForIn(forInStatement),
1094 buildInitializer, 1097 buildInitializer,
1095 buildCondition, 1098 buildCondition,
1096 () {}, 1099 () {},
1097 buildBody); 1100 buildBody);
1098 } 1101 }
1099 1102
1100 void _buildAsyncForIn(ir.ForInStatement forInStatement) { 1103 void _buildAsyncForIn(ir.ForInStatement forInStatement) {
1101 // The async-for is implemented with a StreamIterator. 1104 // The async-for is implemented with a StreamIterator.
1102 HInstruction streamIterator; 1105 HInstruction streamIterator;
1103 1106
(...skipping 27 matching lines...) Expand all
1131 1134
1132 void buildUpdate() {} 1135 void buildUpdate() {}
1133 1136
1134 // Creates a synthetic try/finally block in case anything async goes amiss. 1137 // Creates a synthetic try/finally block in case anything async goes amiss.
1135 TryCatchFinallyBuilder tryBuilder = new TryCatchFinallyBuilder(this); 1138 TryCatchFinallyBuilder tryBuilder = new TryCatchFinallyBuilder(this);
1136 // Build fake try body: 1139 // Build fake try body:
1137 loopHandler.handleLoop( 1140 loopHandler.handleLoop(
1138 forInStatement, 1141 forInStatement,
1139 localsMap.getClosureRepresentationInfoForLoop( 1142 localsMap.getClosureRepresentationInfoForLoop(
1140 closureDataLookup, forInStatement), 1143 closureDataLookup, forInStatement),
1144 localsMap.getJumpTargetForForIn(forInStatement),
1141 buildInitializer, 1145 buildInitializer,
1142 buildCondition, 1146 buildCondition,
1143 buildUpdate, 1147 buildUpdate,
1144 buildBody); 1148 buildBody);
1145 1149
1146 void finalizerFunction() { 1150 void finalizerFunction() {
1147 _pushDynamicInvocation(forInStatement, null, [streamIterator], 1151 _pushDynamicInvocation(forInStatement, null, [streamIterator],
1148 selector: Selectors.cancel); 1152 selector: Selectors.cancel);
1149 add(new HAwait(pop(), closedWorld.commonMasks.dynamicType)); 1153 add(new HAwait(pop(), closedWorld.commonMasks.dynamicType));
1150 } 1154 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 assert(isReachable); 1186 assert(isReachable);
1183 HInstruction buildCondition() { 1187 HInstruction buildCondition() {
1184 whileStatement.condition.accept(this); 1188 whileStatement.condition.accept(this);
1185 return popBoolified(); 1189 return popBoolified();
1186 } 1190 }
1187 1191
1188 loopHandler.handleLoop( 1192 loopHandler.handleLoop(
1189 whileStatement, 1193 whileStatement,
1190 localsMap.getClosureRepresentationInfoForLoop( 1194 localsMap.getClosureRepresentationInfoForLoop(
1191 closureDataLookup, whileStatement), 1195 closureDataLookup, whileStatement),
1196 localsMap.getJumpTargetForWhile(whileStatement),
1192 () {}, 1197 () {},
1193 buildCondition, 1198 buildCondition,
1194 () {}, () { 1199 () {}, () {
1195 whileStatement.body.accept(this); 1200 whileStatement.body.accept(this);
1196 }); 1201 });
1197 } 1202 }
1198 1203
1199 @override 1204 @override
1200 visitDoStatement(ir.DoStatement doStatement) { 1205 visitDoStatement(ir.DoStatement doStatement) {
1201 // TODO(efortuna): I think this can be rewritten using 1206 // TODO(efortuna): I think this can be rewritten using
1202 // LoopHandler.handleLoop with some tricks about when the "update" happens. 1207 // LoopHandler.handleLoop with some tricks about when the "update" happens.
1203 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 1208 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
1204 LoopClosureRepresentationInfo loopClosureInfo = localsMap 1209 LoopClosureRepresentationInfo loopClosureInfo = localsMap
1205 .getClosureRepresentationInfoForLoop(closureDataLookup, doStatement); 1210 .getClosureRepresentationInfoForLoop(closureDataLookup, doStatement);
1206 localsHandler.startLoop(loopClosureInfo); 1211 localsHandler.startLoop(loopClosureInfo);
1207 JumpHandler jumpHandler = loopHandler.beginLoopHeader(doStatement); 1212 JumpTarget target = localsMap.getJumpTargetForDo(doStatement);
1213 JumpHandler jumpHandler = loopHandler.beginLoopHeader(doStatement, target);
1208 HLoopInformation loopInfo = current.loopInformation; 1214 HLoopInformation loopInfo = current.loopInformation;
1209 HBasicBlock loopEntryBlock = current; 1215 HBasicBlock loopEntryBlock = current;
1210 HBasicBlock bodyEntryBlock = current; 1216 HBasicBlock bodyEntryBlock = current;
1211 JumpTarget target = localsMap.getJumpTarget(doStatement);
1212 bool hasContinues = target != null && target.isContinueTarget; 1217 bool hasContinues = target != null && target.isContinueTarget;
1213 if (hasContinues) { 1218 if (hasContinues) {
1214 // Add extra block to hang labels on. 1219 // Add extra block to hang labels on.
1215 // It doesn't currently work if they are on the same block as the 1220 // It doesn't currently work if they are on the same block as the
1216 // HLoopInfo. The handling of HLabeledBlockInformation will visit a 1221 // HLoopInfo. The handling of HLabeledBlockInformation will visit a
1217 // SubGraph that starts at the same block again, so the HLoopInfo is 1222 // SubGraph that starts at the same block again, so the HLoopInfo is
1218 // either handled twice, or it's handled after the labeled block info, 1223 // either handled twice, or it's handled after the labeled block info,
1219 // both of which generate the wrong code. 1224 // both of which generate the wrong code.
1220 // Using a separate block is just a simple workaround. 1225 // Using a separate block is just a simple workaround.
1221 bodyEntryBlock = openNewBlock(); 1226 bodyEntryBlock = openNewBlock();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 loopEntryBlock.postProcessLoopHeader(); 1302 loopEntryBlock.postProcessLoopHeader();
1298 SubGraph bodyGraph = new SubGraph(loopEntryBlock, bodyExitBlock); 1303 SubGraph bodyGraph = new SubGraph(loopEntryBlock, bodyExitBlock);
1299 HLoopBlockInformation loopBlockInfo = new HLoopBlockInformation( 1304 HLoopBlockInformation loopBlockInfo = new HLoopBlockInformation(
1300 HLoopBlockInformation.DO_WHILE_LOOP, 1305 HLoopBlockInformation.DO_WHILE_LOOP,
1301 null, 1306 null,
1302 wrapExpressionGraph(conditionExpression), 1307 wrapExpressionGraph(conditionExpression),
1303 wrapStatementGraph(bodyGraph), 1308 wrapStatementGraph(bodyGraph),
1304 null, 1309 null,
1305 loopEntryBlock.loopInformation.target, 1310 loopEntryBlock.loopInformation.target,
1306 loopEntryBlock.loopInformation.labels, 1311 loopEntryBlock.loopInformation.labels,
1307 // TODO(johnniwinther): Provide source information like: 1312 // TODO(redemption): Provide source information like:
1308 // sourceInformationBuilder.buildLoop(astAdapter.getNode(doStatement)) 1313 // sourceInformationBuilder.buildLoop(astAdapter.getNode(doStatement))
1309 null); 1314 null);
1310 loopEntryBlock.setBlockFlow(loopBlockInfo, current); 1315 loopEntryBlock.setBlockFlow(loopBlockInfo, current);
1311 loopInfo.loopBlockInformation = loopBlockInfo; 1316 loopInfo.loopBlockInformation = loopBlockInfo;
1312 } else { 1317 } else {
1313 // Since the loop has no back edge, we remove the loop information on the 1318 // Since the loop has no back edge, we remove the loop information on the
1314 // header. 1319 // header.
1315 loopEntryBlock.loopInformation = null; 1320 loopEntryBlock.loopInformation = null;
1316 1321
1317 if (jumpHandler.hasAnyBreak()) { 1322 if (jumpHandler.hasAnyBreak()) {
1318 // Null branchBlock because the body of the do-while loop always aborts, 1323 // Null branchBlock because the body of the do-while loop always aborts,
1319 // so we never get to the condition. 1324 // so we never get to the condition.
1320 loopHandler.endLoop(loopEntryBlock, null, jumpHandler, localsHandler); 1325 loopHandler.endLoop(loopEntryBlock, null, jumpHandler, localsHandler);
1321 1326
1322 // Since the body of the loop has a break, we attach a synthesized label 1327 // Since the body of the loop has a break, we attach a synthesized label
1323 // to the body. 1328 // to the body.
1324 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); 1329 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
1325 JumpTarget target = localsMap.getJumpTarget(doStatement); 1330 JumpTarget target = localsMap.getJumpTargetForDo(doStatement);
1326 LabelDefinition label = target.addLabel(null, 'loop'); 1331 LabelDefinition label =
1327 label.setBreakTarget(); 1332 target.addLabel(null, 'loop', isBreakTarget: true);
1328 HLabeledBlockInformation info = new HLabeledBlockInformation( 1333 HLabeledBlockInformation info = new HLabeledBlockInformation(
1329 new HSubGraphBlockInformation(bodyGraph), <LabelDefinition>[label]); 1334 new HSubGraphBlockInformation(bodyGraph), <LabelDefinition>[label]);
1330 loopEntryBlock.setBlockFlow(info, current); 1335 loopEntryBlock.setBlockFlow(info, current);
1331 jumpHandler.forEachBreak((HBreak breakInstruction, _) { 1336 jumpHandler.forEachBreak((HBreak breakInstruction, _) {
1332 HBasicBlock block = breakInstruction.block; 1337 HBasicBlock block = breakInstruction.block;
1333 block.addAtExit(new HBreak.toLabel(label)); 1338 block.addAtExit(new HBreak.toLabel(label));
1334 block.remove(breakInstruction); 1339 block.remove(breakInstruction);
1335 }); 1340 });
1336 } 1341 }
1337 } 1342 }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 handleIf(visitCondition: buildCondition, visitThen: fail); 1444 handleIf(visitCondition: buildCondition, visitThen: fail);
1440 } 1445 }
1441 1446
1442 /// Creates a [JumpHandler] for a statement. The node must be a jump 1447 /// Creates a [JumpHandler] for a statement. The node must be a jump
1443 /// target. If there are no breaks or continues targeting the statement, 1448 /// target. If there are no breaks or continues targeting the statement,
1444 /// a special "null handler" is returned. 1449 /// a special "null handler" is returned.
1445 /// 1450 ///
1446 /// [isLoopJump] is true when the jump handler is for a loop. This is used 1451 /// [isLoopJump] is true when the jump handler is for a loop. This is used
1447 /// to distinguish the synthesized loop created for a switch statement with 1452 /// to distinguish the synthesized loop created for a switch statement with
1448 /// continue statements from simple switch statements. 1453 /// continue statements from simple switch statements.
1449 JumpHandler createJumpHandler(ir.TreeNode node, {bool isLoopJump: false}) { 1454 JumpHandler createJumpHandler(ir.TreeNode node, JumpTarget target,
1450 JumpTarget target = localsMap.getJumpTarget(node); 1455 {bool isLoopJump: false}) {
1451 if (target == null) { 1456 if (target == null) {
1452 // No breaks or continues to this node. 1457 // No breaks or continues to this node.
1453 return new NullJumpHandler(reporter); 1458 return new NullJumpHandler(reporter);
1454 } 1459 }
1455 if (isLoopJump && node is ir.SwitchStatement) { 1460 if (isLoopJump && node is ir.SwitchStatement) {
1456 return new KernelSwitchCaseJumpHandler(this, target, node, localsMap); 1461 return new KernelSwitchCaseJumpHandler(this, target, node, localsMap);
1457 } 1462 }
1458 1463
1459 return new JumpHandler(this, target); 1464 return new JumpHandler(this, target);
1460 } 1465 }
1461 1466
1462 @override 1467 @override
1463 void visitBreakStatement(ir.BreakStatement breakStatement) { 1468 void visitBreakStatement(ir.BreakStatement breakStatement) {
1464 assert(!isAborted()); 1469 assert(!isAborted());
1465 handleInTryStatement(); 1470 handleInTryStatement();
1466 JumpTarget target = localsMap.getJumpTarget(breakStatement.target); 1471 JumpTarget target = localsMap.getJumpTargetForBreak(breakStatement);
1467 assert(target != null); 1472 assert(target != null);
1468 JumpHandler handler = jumpTargets[target]; 1473 JumpHandler handler = jumpTargets[target];
1469 assert(handler != null); 1474 assert(handler != null);
1470 if (handler.labels.isNotEmpty) { 1475 if (handler.labels.isNotEmpty) {
1471 handler.generateBreak(handler.labels.first); 1476 handler.generateBreak(handler.labels.first);
1472 } else { 1477 } else {
1473 handler.generateBreak(); 1478 handler.generateBreak();
1474 } 1479 }
1475 } 1480 }
1476 1481
1477 @override 1482 @override
1478 void visitLabeledStatement(ir.LabeledStatement labeledStatement) { 1483 void visitLabeledStatement(ir.LabeledStatement labeledStatement) {
1479 ir.Statement body = labeledStatement.body; 1484 ir.Statement body = labeledStatement.body;
1480 if (body is ir.WhileStatement || 1485 if (body is ir.WhileStatement ||
1481 body is ir.DoStatement || 1486 body is ir.DoStatement ||
1482 body is ir.ForStatement || 1487 body is ir.ForStatement ||
1483 body is ir.ForInStatement || 1488 body is ir.ForInStatement ||
1484 body is ir.SwitchStatement) { 1489 body is ir.SwitchStatement) {
1485 // loops and switches handle breaks on their own 1490 // loops and switches handle breaks on their own
1486 body.accept(this); 1491 body.accept(this);
1487 return; 1492 return;
1488 } 1493 }
1489 JumpHandler handler = createJumpHandler(labeledStatement); 1494 JumpHandler handler = createJumpHandler(
1495 labeledStatement, localsMap.getJumpTargetForLabel(labeledStatement));
1490 1496
1491 LocalsHandler beforeLocals = new LocalsHandler.from(localsHandler); 1497 LocalsHandler beforeLocals = new LocalsHandler.from(localsHandler);
1492 1498
1493 HBasicBlock newBlock = openNewBlock(); 1499 HBasicBlock newBlock = openNewBlock();
1494 body.accept(this); 1500 body.accept(this);
1495 SubGraph bodyGraph = new SubGraph(newBlock, lastOpenedBlock); 1501 SubGraph bodyGraph = new SubGraph(newBlock, lastOpenedBlock);
1496 1502
1497 HBasicBlock joinBlock = graph.addNewBlock(); 1503 HBasicBlock joinBlock = graph.addNewBlock();
1498 List<LocalsHandler> breakHandlers = <LocalsHandler>[]; 1504 List<LocalsHandler> breakHandlers = <LocalsHandler>[];
1499 handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { 1505 handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
(...skipping 29 matching lines...) Expand all
1529 constants[caseExpression] = constant; 1535 constants[caseExpression] = constant;
1530 } 1536 }
1531 } 1537 }
1532 return constants; 1538 return constants;
1533 } 1539 }
1534 1540
1535 @override 1541 @override
1536 void visitContinueSwitchStatement( 1542 void visitContinueSwitchStatement(
1537 ir.ContinueSwitchStatement switchStatement) { 1543 ir.ContinueSwitchStatement switchStatement) {
1538 handleInTryStatement(); 1544 handleInTryStatement();
1539 JumpTarget target = localsMap.getJumpTarget(switchStatement.target); 1545 JumpTarget target =
1546 localsMap.getJumpTargetForContinueSwitch(switchStatement);
1540 assert(target != null); 1547 assert(target != null);
1541 JumpHandler handler = jumpTargets[target]; 1548 JumpHandler handler = jumpTargets[target];
1542 assert(handler != null); 1549 assert(handler != null);
1543 assert(target.labels.isNotEmpty); 1550 assert(target.labels.isNotEmpty);
1544 handler.generateContinue(target.labels.first); 1551 handler.generateContinue(target.labels.first);
1545 } 1552 }
1546 1553
1547 @override 1554 @override
1548 void visitSwitchStatement(ir.SwitchStatement switchStatement) { 1555 void visitSwitchStatement(ir.SwitchStatement switchStatement) {
1549 // The switch case indices must match those computed in 1556 // The switch case indices must match those computed in
1550 // [KernelSwitchCaseJumpHandler]. 1557 // [KernelSwitchCaseJumpHandler].
1551 bool hasContinue = false; 1558 bool hasContinue = false;
1552 Map<ir.SwitchCase, int> caseIndex = new Map<ir.SwitchCase, int>(); 1559 Map<ir.SwitchCase, int> caseIndex = new Map<ir.SwitchCase, int>();
1553 int switchIndex = 1; 1560 int switchIndex = 1;
1554 bool hasDefault = false; 1561 bool hasDefault = false;
1555 for (ir.SwitchCase switchCase in switchStatement.cases) { 1562 for (ir.SwitchCase switchCase in switchStatement.cases) {
1556 if (_isDefaultCase(switchCase)) { 1563 if (_isDefaultCase(switchCase)) {
1557 hasDefault = true; 1564 hasDefault = true;
1558 } 1565 }
1559 if (SwitchContinueAnalysis.containsContinue(switchCase.body)) { 1566 if (SwitchContinueAnalysis.containsContinue(switchCase.body)) {
1560 hasContinue = true; 1567 hasContinue = true;
1561 } 1568 }
1562 caseIndex[switchCase] = switchIndex; 1569 caseIndex[switchCase] = switchIndex;
1563 switchIndex++; 1570 switchIndex++;
1564 } 1571 }
1565 1572
1566 JumpHandler jumpHandler = createJumpHandler(switchStatement); 1573 JumpHandler jumpHandler = createJumpHandler(
1574 switchStatement, localsMap.getJumpTargetForSwitch(switchStatement));
1567 if (!hasContinue) { 1575 if (!hasContinue) {
1568 // If the switch statement has no switch cases targeted by continue 1576 // If the switch statement has no switch cases targeted by continue
1569 // statements we encode the switch statement directly. 1577 // statements we encode the switch statement directly.
1570 _buildSimpleSwitchStatement(switchStatement, jumpHandler); 1578 _buildSimpleSwitchStatement(switchStatement, jumpHandler);
1571 } else { 1579 } else {
1572 _buildComplexSwitchStatement( 1580 _buildComplexSwitchStatement(
1573 switchStatement, jumpHandler, caseIndex, hasDefault); 1581 switchStatement, jumpHandler, caseIndex, hasDefault);
1574 } 1582 }
1575 } 1583 }
1576 1584
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1649 // case 1: s_1; break l; 1657 // case 1: s_1; break l;
1650 // case 2: s_2; target = i; continue l; 1658 // case 2: s_2; target = i; continue l;
1651 // ... 1659 // ...
1652 // case n: s_n; target = j; continue l; 1660 // case n: s_n; target = j; continue l;
1653 // } 1661 // }
1654 // } 1662 // }
1655 // 1663 //
1656 // This is because JS does not have this same "continue label" semantics so 1664 // This is because JS does not have this same "continue label" semantics so
1657 // we encode it in the form of a state machine. 1665 // we encode it in the form of a state machine.
1658 1666
1659 JumpTarget switchTarget = localsMap.getJumpTarget(switchStatement); 1667 JumpTarget switchTarget = localsMap.getJumpTargetForSwitch(switchStatement);
1660 localsHandler.updateLocal(switchTarget, graph.addConstantNull(closedWorld)); 1668 localsHandler.updateLocal(switchTarget, graph.addConstantNull(closedWorld));
1661 1669
1662 var switchCases = switchStatement.cases; 1670 var switchCases = switchStatement.cases;
1663 if (!hasDefault) { 1671 if (!hasDefault) {
1664 // Use null as the marker for a synthetic default clause. 1672 // Use null as the marker for a synthetic default clause.
1665 // The synthetic default is added because otherwise there would be no 1673 // The synthetic default is added because otherwise there would be no
1666 // good place to give a default value to the local. 1674 // good place to give a default value to the local.
1667 switchCases = new List<ir.SwitchCase>.from(switchCases); 1675 switchCases = new List<ir.SwitchCase>.from(switchCases);
1668 switchCases.add(null); 1676 switchCases.add(null);
1669 } 1677 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1718 getConstants, 1726 getConstants,
1719 (_) => false, // No case is default. 1727 (_) => false, // No case is default.
1720 buildSwitchCase); 1728 buildSwitchCase);
1721 } 1729 }
1722 1730
1723 void buildLoop() { 1731 void buildLoop() {
1724 loopHandler.handleLoop( 1732 loopHandler.handleLoop(
1725 switchStatement, 1733 switchStatement,
1726 localsMap.getClosureRepresentationInfoForLoop( 1734 localsMap.getClosureRepresentationInfoForLoop(
1727 closureDataLookup, switchStatement), 1735 closureDataLookup, switchStatement),
1736 switchTarget,
1728 () {}, 1737 () {},
1729 buildCondition, 1738 buildCondition,
1730 () {}, 1739 () {},
1731 buildSwitch); 1740 buildSwitch);
1732 } 1741 }
1733 1742
1734 if (hasDefault) { 1743 if (hasDefault) {
1735 buildLoop(); 1744 buildLoop();
1736 } else { 1745 } else {
1737 // If the switch statement has no default case, surround the loop with 1746 // If the switch statement has no default case, surround the loop with
(...skipping 1749 matching lines...) Expand 10 before | Expand all | Expand 10 after
3487 enterBlock.setBlockFlow( 3496 enterBlock.setBlockFlow(
3488 new HTryBlockInformation( 3497 new HTryBlockInformation(
3489 kernelBuilder.wrapStatementGraph(bodyGraph), 3498 kernelBuilder.wrapStatementGraph(bodyGraph),
3490 exception, 3499 exception,
3491 kernelBuilder.wrapStatementGraph(catchGraph), 3500 kernelBuilder.wrapStatementGraph(catchGraph),
3492 kernelBuilder.wrapStatementGraph(finallyGraph)), 3501 kernelBuilder.wrapStatementGraph(finallyGraph)),
3493 exitBlock); 3502 exitBlock);
3494 kernelBuilder.inTryStatement = previouslyInTryStatement; 3503 kernelBuilder.inTryStatement = previouslyInTryStatement;
3495 } 3504 }
3496 } 3505 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/builder.dart ('k') | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698