| 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 Interceptors { | 5 class Interceptors { |
| 6 Compiler compiler; | 6 Compiler compiler; |
| 7 Interceptors(Compiler this.compiler); | 7 Interceptors(Compiler this.compiler); |
| 8 | 8 |
| 9 SourceString mapOperatorToMethodName(Operator op) { | 9 SourceString mapOperatorToMethodName(Operator op) { |
| 10 String name = op.source.stringValue; | 10 String name = op.source.stringValue; |
| (...skipping 1072 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 List<LocalsHandler> breakLocals = <LocalsHandler>[]; | 1083 List<LocalsHandler> breakLocals = <LocalsHandler>[]; |
| 1084 jumpHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { | 1084 jumpHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { |
| 1085 breakInstruction.block.addSuccessor(loopExitBlock); | 1085 breakInstruction.block.addSuccessor(loopExitBlock); |
| 1086 breakLocals.add(locals); | 1086 breakLocals.add(locals); |
| 1087 }); | 1087 }); |
| 1088 branchBlock.addSuccessor(loopExitBlock); | 1088 branchBlock.addSuccessor(loopExitBlock); |
| 1089 open(loopExitBlock); | 1089 open(loopExitBlock); |
| 1090 localsHandler.endLoop(loopEntry); | 1090 localsHandler.endLoop(loopEntry); |
| 1091 if (!breakLocals.isEmpty()) { | 1091 if (!breakLocals.isEmpty()) { |
| 1092 breakLocals.add(savedLocals); | 1092 breakLocals.add(savedLocals); |
| 1093 localsHandler = localsHandler.mergeMultiple(breakLocals, loopExitBlock); | 1093 localsHandler = savedLocals.mergeMultiple(breakLocals, loopExitBlock); |
| 1094 } else { | 1094 } else { |
| 1095 localsHandler = savedLocals; | 1095 localsHandler = savedLocals; |
| 1096 } | 1096 } |
| 1097 } | 1097 } |
| 1098 | 1098 |
| 1099 // For while loops, initializer and update are null. | 1099 // For while loops, initializer and update are null. |
| 1100 // The condition function must return a boolean result. | 1100 // The condition function must return a boolean result. |
| 1101 // None of the functions must leave anything on the stack. | 1101 // None of the functions must leave anything on the stack. |
| 1102 handleLoop(Node loop, | 1102 handleLoop(Node loop, |
| 1103 void initialize(), | 1103 void initialize(), |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1217 return popBoolified(); | 1217 return popBoolified(); |
| 1218 } | 1218 } |
| 1219 handleLoop(node, | 1219 handleLoop(node, |
| 1220 () {}, | 1220 () {}, |
| 1221 buildCondition, | 1221 buildCondition, |
| 1222 () {}, | 1222 () {}, |
| 1223 () { visit(node.body); }); | 1223 () { visit(node.body); }); |
| 1224 } | 1224 } |
| 1225 | 1225 |
| 1226 visitDoWhile(DoWhile node) { | 1226 visitDoWhile(DoWhile node) { |
| 1227 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); |
| 1227 localsHandler.startLoop(node); | 1228 localsHandler.startLoop(node); |
| 1228 JumpHandler jumpHandler = beginLoopHeader(node); | 1229 JumpHandler jumpHandler = beginLoopHeader(node); |
| 1229 HBasicBlock loopEntryBlock = current; | 1230 HBasicBlock loopEntryBlock = current; |
| 1230 | 1231 HBasicBlock bodyEntryBlock = current; |
| 1232 TargetElement target = elements[node]; |
| 1233 bool hasContinues = target !== null && target.isContinueTarget; |
| 1234 if (hasContinues) { |
| 1235 // Add extra block to hang labels on. |
| 1236 // It doesn't currently work if they are on the same block as the |
| 1237 // HLoopInfo. The handling of HLabeledBlockInformation will visit a |
| 1238 // SubGraph that starts at the same block again, so the HLoopInfo is |
| 1239 // either handled twice, or it's handled after the labeled block info, |
| 1240 // both of which generate the wrong code. |
| 1241 // Using a separate block is just a simple workaround. |
| 1242 bodyEntryBlock = graph.addNewBlock(); |
| 1243 goto(current, bodyEntryBlock); |
| 1244 open(bodyEntryBlock); |
| 1245 } |
| 1231 localsHandler.enterLoopBody(node); | 1246 localsHandler.enterLoopBody(node); |
| 1232 hackAroundPossiblyAbortingBody(node, () { visit(node.body); }); | 1247 hackAroundPossiblyAbortingBody(node, () { visit(node.body); }); |
| 1233 | 1248 |
| 1234 // If there are no continues we could avoid the creation of the condition | 1249 // If there are no continues we could avoid the creation of the condition |
| 1235 // block. This could also lead to a block having multiple entries and exits. | 1250 // block. This could also lead to a block having multiple entries and exits. |
| 1236 HBasicBlock bodyExitBlock = close(new HGoto()); | 1251 HBasicBlock bodyExitBlock = close(new HGoto()); |
| 1237 HBasicBlock conditionBlock = addNewBlock(); | 1252 HBasicBlock conditionBlock = addNewBlock(); |
| 1253 |
| 1254 List<LocalsHandler> continueLocals = <LocalsHandler>[]; |
| 1255 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { |
| 1256 instruction.block.addSuccessor(conditionBlock); |
| 1257 continueLocals.add(locals); |
| 1258 }); |
| 1238 bodyExitBlock.addSuccessor(conditionBlock); | 1259 bodyExitBlock.addSuccessor(conditionBlock); |
| 1239 jumpHandler.forEachContinue((x,y) { | 1260 if (!continueLocals.isEmpty()) { |
| 1240 // TODO(lrn): Handle continue in do-while loops. | 1261 continueLocals.add(localsHandler); |
| 1241 compiler.cancel("do-while with continue", node: node); | 1262 localsHandler = savedLocals.mergeMultiple(continueLocals, conditionBlock); |
| 1242 }); | 1263 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); |
| 1264 List<LabelElement> labels = jumpHandler.labels(); |
| 1265 if (!labels.isEmpty()) { |
| 1266 bodyEntryBlock.labeledBlockInformation = |
| 1267 new HLabeledBlockInformation(bodyGraph, |
| 1268 conditionBlock, |
| 1269 labels, |
| 1270 isContinue: true); |
| 1271 } else { |
| 1272 bodyEntryBlock.labeledBlockInformation = |
| 1273 new HLabeledBlockInformation.implicit(bodyGraph, |
| 1274 conditionBlock, |
| 1275 target, |
| 1276 isContinue: true); |
| 1277 } |
| 1278 } |
| 1243 open(conditionBlock); | 1279 open(conditionBlock); |
| 1280 |
| 1244 visit(node.condition); | 1281 visit(node.condition); |
| 1245 assert(!isAborted()); | 1282 assert(!isAborted()); |
| 1246 conditionBlock = close(new HLoopBranch(popBoolified(), | 1283 conditionBlock = close(new HLoopBranch(popBoolified(), |
| 1247 HLoopBranch.DO_WHILE_LOOP)); | 1284 HLoopBranch.DO_WHILE_LOOP)); |
| 1248 | 1285 |
| 1249 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge. | 1286 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge. |
| 1250 loopEntryBlock.postProcessLoopHeader(); | 1287 loopEntryBlock.postProcessLoopHeader(); |
| 1251 | 1288 |
| 1252 endLoop(loopEntryBlock, conditionBlock, jumpHandler, localsHandler); | 1289 endLoop(loopEntryBlock, conditionBlock, jumpHandler, localsHandler); |
| 1253 jumpHandler.close(); | 1290 jumpHandler.close(); |
| (...skipping 1550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2804 HInstruction concat = new HAdd(target, left, right); | 2841 HInstruction concat = new HAdd(target, left, right); |
| 2805 builder.add(concat); | 2842 builder.add(concat); |
| 2806 return concat; | 2843 return concat; |
| 2807 } | 2844 } |
| 2808 | 2845 |
| 2809 HInstruction result() { | 2846 HInstruction result() { |
| 2810 flushAccumulator(); | 2847 flushAccumulator(); |
| 2811 return prefix; | 2848 return prefix; |
| 2812 } | 2849 } |
| 2813 } | 2850 } |
| OLD | NEW |