| Index: sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
|
| index e29a7aa9871beccf9e3e6c81bae1ddf04dacf301..ac51d423f860b53af33943595fc1496386bb17cb 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
|
| @@ -19,6 +19,7 @@ abstract class HVisitor<R> {
|
| R visitDivide(HDivide node);
|
| R visitEquals(HEquals node);
|
| R visitExit(HExit node);
|
| + R visitExitTry(HExitTry node);
|
| R visitFieldGet(HFieldGet node);
|
| R visitFieldSet(HFieldSet node);
|
| R visitForeign(HForeign node);
|
| @@ -220,7 +221,6 @@ class HGraph {
|
| HBasicBlock block = blocks[i];
|
| List<HBasicBlock> predecessors = block.predecessors;
|
| if (block.isLoopHeader()) {
|
| - assert(predecessors.length >= 2);
|
| block.assignCommonDominator(predecessors[0]);
|
| } else {
|
| for (int j = predecessors.length - 1; j >= 0; j--) {
|
| @@ -279,6 +279,7 @@ class HBaseVisitor extends HGraphVisitor implements HVisitor {
|
| visitDivide(HDivide node) => visitBinaryArithmetic(node);
|
| visitEquals(HEquals node) => visitRelational(node);
|
| visitExit(HExit node) => visitControlFlow(node);
|
| + visitExitTry(HExitTry node) => visitControlFlow(node);
|
| visitFieldGet(HFieldGet node) => visitFieldAccess(node);
|
| visitFieldSet(HFieldSet node) => visitFieldAccess(node);
|
| visitForeign(HForeign node) => visitInstruction(node);
|
| @@ -2033,6 +2034,18 @@ class HTry extends HControlFlow {
|
| HBasicBlock get joinBlock => this.block.successors.last;
|
| }
|
|
|
| +// An [HExitTry] control flow node is used when the body of a try or
|
| +// the body of a catch contains a return, break or continue. To build
|
| +// the control flow graph, we explicitely mark the body that
|
| +// leads to one of this instruction a predecessor of catch and
|
| +// finally.
|
| +class HExitTry extends HControlFlow {
|
| + HExitTry() : super(const <HInstruction>[]);
|
| + toString() => 'exit try';
|
| + accept(HVisitor visitor) => visitor.visitExitTry(this);
|
| + HBasicBlock get bodyTrySuccessor => block.successors[0];
|
| +}
|
| +
|
| class HIf extends HConditionalBranch {
|
| HBlockFlow blockInformation = null;
|
| HIf(HInstruction condition) : super(<HInstruction>[condition]);
|
| @@ -2914,7 +2927,7 @@ class HLoopBlockInformation implements HStatementInformation {
|
|
|
| HBasicBlock get end {
|
| if (updates != null) return updates.end;
|
| - if (kind == DO_WHILE_LOOP) {
|
| + if (kind == DO_WHILE_LOOP && condition != null) {
|
| return condition.end;
|
| }
|
| return body.end;
|
|
|