Chromium Code Reviews| Index: frog/leg/ssa/builder.dart |
| diff --git a/frog/leg/ssa/builder.dart b/frog/leg/ssa/builder.dart |
| index 160074f75517f0a6bf988910312b8eccc57c3ca7..26dc4c3c072ed4ce70e183b4f611034be40079d8 100644 |
| --- a/frog/leg/ssa/builder.dart |
| +++ b/frog/leg/ssa/builder.dart |
| @@ -1090,7 +1090,7 @@ class SsaBuilder implements Visitor { |
| localsHandler.endLoop(loopEntry); |
| if (!breakLocals.isEmpty()) { |
| breakLocals.add(savedLocals); |
| - localsHandler = localsHandler.mergeMultiple(breakLocals, loopExitBlock); |
| + localsHandler = savedLocals.mergeMultiple(breakLocals, loopExitBlock); |
| } else { |
| localsHandler = savedLocals; |
| } |
| @@ -1224,10 +1224,20 @@ class SsaBuilder implements Visitor { |
| } |
| visitDoWhile(DoWhile node) { |
| + LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); |
| localsHandler.startLoop(node); |
| JumpHandler jumpHandler = beginLoopHeader(node); |
| HBasicBlock loopEntryBlock = current; |
| - |
| + HBasicBlock bodyEntryBlock = current; |
| + TargetElement target = elements[node]; |
| + bool hasContinues = target !== null && target.isContinueTarget; |
| + if (hasContinues) { |
| + // Add extra block to hang labels on. |
| + // It doesn't work if they are on the same block as the HLoopInfo. |
|
ngeoffray
2012/03/21 12:23:23
Please explain why.
Lasse Reichstein Nielsen
2012/03/21 12:33:26
Done.
|
| + bodyEntryBlock = graph.addNewBlock(); |
| + goto(current, bodyEntryBlock); |
| + open(bodyEntryBlock); |
| + } |
| localsHandler.enterLoopBody(node); |
| hackAroundPossiblyAbortingBody(node, () { visit(node.body); }); |
| @@ -1235,12 +1245,34 @@ class SsaBuilder implements Visitor { |
| // block. This could also lead to a block having multiple entries and exits. |
| HBasicBlock bodyExitBlock = close(new HGoto()); |
| HBasicBlock conditionBlock = addNewBlock(); |
| - bodyExitBlock.addSuccessor(conditionBlock); |
| - jumpHandler.forEachContinue((x,y) { |
| - // TODO(lrn): Handle continue in do-while loops. |
| - compiler.cancel("do-while with continue", node: node); |
| + |
| + List<LocalsHandler> continueLocals = <LocalsHandler>[]; |
| + jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { |
| + instruction.block.addSuccessor(conditionBlock); |
| + continueLocals.add(locals); |
| }); |
| + bodyExitBlock.addSuccessor(conditionBlock); |
| + if (!continueLocals.isEmpty()) { |
| + continueLocals.add(localsHandler); |
| + localsHandler = savedLocals.mergeMultiple(continueLocals, conditionBlock); |
| + SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); |
| + List<LabelElement> labels = jumpHandler.labels(); |
| + if (!labels.isEmpty()) { |
|
ngeoffray
2012/03/21 12:23:23
You could save duplicated code by doing:
new HLabe
Lasse Reichstein Nielsen
2012/03/21 12:33:26
No, they are different constructors.
|
| + bodyEntryBlock.labeledBlockInformation = |
| + new HLabeledBlockInformation(bodyGraph, |
| + conditionBlock, |
| + labels, |
| + isContinue: true); |
| + } else { |
| + bodyEntryBlock.labeledBlockInformation = |
| + new HLabeledBlockInformation.implicit(bodyGraph, |
| + conditionBlock, |
| + target, |
| + isContinue: true); |
| + } |
| + } |
| open(conditionBlock); |
| + |
| visit(node.condition); |
| assert(!isAborted()); |
| conditionBlock = close(new HLoopBranch(popBoolified(), |