Chromium Code Reviews| Index: frog/leg/ssa/builder.dart |
| =================================================================== |
| --- frog/leg/ssa/builder.dart (revision 4076) |
| +++ frog/leg/ssa/builder.dart (working copy) |
| @@ -875,9 +875,18 @@ |
| } |
| visitIf(If node) { |
| - // Add the condition to the current block. |
| - bool hasElse = node.hasElsePart; |
| visit(node.condition); |
| + Function visitElse; |
| + if (node.elsePart != null) { |
| + visitElse = () { |
| + visit(node.elsePart); |
| + }; |
| + } |
| + handleIf(() => visit(node.thenPart), visitElse); |
| + } |
| + |
| + void handleIf(void visitThen(), void visitElse()) { |
| + bool hasElse = visitElse != null; |
| HBasicBlock conditionBlock = close(new HIf(popBoolified(), hasElse)); |
| LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); |
| @@ -886,7 +895,7 @@ |
| HBasicBlock thenBlock = addNewBlock(); |
| conditionBlock.addSuccessor(thenBlock); |
| open(thenBlock); |
| - visit(node.thenPart); |
| + visitThen(); |
| thenBlock = current; |
| // Reset the locals state to the state after the condition and keep the |
| @@ -900,7 +909,7 @@ |
| elseBlock = addNewBlock(); |
| conditionBlock.addSuccessor(elseBlock); |
| open(elseBlock); |
| - visit(node.elsePart); |
| + visitElse(); |
| elseBlock = current; |
| } |
| @@ -1824,15 +1833,56 @@ |
| List<HBasicBlock> blocks = <HBasicBlock>[]; |
| if (!isAborted()) blocks.add(close(new HGoto())); |
| - int catchBlocksCount = 0; |
| - for (CatchBlock catchBlock in node.catchBlocks.nodes) { |
| - if (++catchBlocksCount != 1) { |
| - compiler.unimplemented('SsaBuilder multiple catch blocks', node: node); |
| - } |
| + if (!node.catchBlocks.isEmpty()) { |
| HBasicBlock block = graph.addNewBlock(); |
| enterBlock.addSuccessor(block); |
| open(block); |
| - visit(catchBlock); |
| + Element element = new Element( |
| + const SourceString(''), ElementKind.PARAMETER, work.element); |
|
floitsch
2012/02/09 15:06:57
I would still give it a name.
ngeoffray
2012/02/09 15:13:48
Done.
|
| + HParameterValue exception = new HParameterValue(element); |
| + add(exception); |
| + tryInstruction.exception = exception; |
| + Link<Node> link = node.catchBlocks.nodes; |
| + |
| + void pushCondition(CatchBlock catchBlock) { |
| + VariableDefinitions declaration = catchBlock.formals.nodes.head; |
| + HInstruction condition = null; |
| + if (declaration.type == null) { |
| + condition = new HLiteral(true, HType.BOOLEAN); |
| + } else { |
| + Element element = elements[declaration.type]; |
| + if (element == null) { |
| + compiler.cancel('Catch with unresolved type', node: catchBlock); |
| + } |
| + condition = new HIs(elements[declaration.type], exception); |
|
floitsch
2012/02/09 15:06:57
element
ngeoffray
2012/02/09 15:13:48
Done.
|
| + } |
| + push(condition); |
| + } |
| + |
| + void visitThen() { |
| + CatchBlock catchBlock = link.head; |
| + link = link.tail; |
| + VariableDefinitions declaration = catchBlock.formals.nodes.head; |
| + localsHandler.updateLocal(elements[declaration.definitions.nodes.head], |
| + exception); |
| + visit(catchBlock); |
| + } |
| + |
| + Function visitElse; |
| + visitElse = () { |
|
floitsch
2012/02/09 15:06:57
void visitElse() { ...
ngeoffray
2012/02/09 15:13:48
Done.
|
| + if (link.isEmpty()) { |
| + close(new HThrow(exception)); |
| + } else { |
| + CatchBlock newBlock = link.head; |
| + pushCondition(newBlock); |
| + handleIf(visitThen, visitElse); |
| + } |
| + }; |
| + CatchBlock firstBlock = link.head; |
| + pushCondition(firstBlock); |
| + |
| + handleIf(visitThen, visitElse); |
| + |
| if (!isAborted()) blocks.add(close(new HGoto())); |
| } |
| @@ -1863,11 +1913,6 @@ |
| } |
| visitCatchBlock(CatchBlock node) { |
| - NodeList formals = node.formals; |
| - VariableDefinitions exception = formals.nodes.head; |
| - if (exception.type != null) { |
| - compiler.unimplemented('SsaBuilder catch with type', node: node); |
| - } |
| visit(node.block); |
| } |