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

Unified Diff: frog/leg/ssa/codegen.dart

Issue 9421035: Support break and labeled statements. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: frog/leg/ssa/codegen.dart
diff --git a/frog/leg/ssa/codegen.dart b/frog/leg/ssa/codegen.dart
index 222ced5db3b35fc15fb38744d745150a70897a4d..89241acdfaabc3c94cd9c6dc6e47d44ec86d0f52 100644
--- a/frog/leg/ssa/codegen.dart
+++ b/frog/leg/ssa/codegen.dart
@@ -211,12 +211,43 @@ class SsaCodeGenerator implements HVisitor {
return node.accept(this);
}
+ void handleLabeledBlock(HBasicBlock node) {
+ HLabeledBlockInformation labeledBlockInfo = node.labeledBlockInformation;
+ if (labeledBlockInfo.start === node) {
+ addIndentation();
+ for (SourceString label in labeledBlockInfo.labels) {
+ addLabel(label);
+ buffer.add(":");
+ }
+ buffer.add("{\n");
+ indent++;
+ } else {
+ assert(labeledBlockInfo.end === node);
+ assert((){
+ // Check that this block is (transitively) dominated by the start block.
+ HBasicBlock block = node;
+ while (block.dominator !== null) {
+ block = block.dominator;
+ if (block === labeledBlockInfo.start) return true;
+ }
+ return false;
+ });
+ indent--;
+ addIndentation();
+ buffer.add("}\n");
+ }
+ }
+
visitBasicBlock(HBasicBlock node) {
currentBlock = node;
- // While loop will be closed by the conditional loop-branch.
- // TODO(floitsch): HACK HACK HACK.
- if (currentBlock.isLoopHeader()) beginLoop(node);
+ if (node.hasLabeledBlockInformation()) {
+ handleLabeledBlock(node);
+ } else if (currentBlock.isLoopHeader()) {
+ // While loop will be closed by the conditional loop-branch.
+ // TODO(floitsch): HACK HACK HACK.
+ beginLoop(node);
+ }
HInstruction instruction = node.first;
while (instruction != null) {
@@ -350,6 +381,33 @@ class SsaCodeGenerator implements HVisitor {
visitBasicBlock(dominated[0]);
}
+ void addLabel(SourceString label) {
+ buffer.add(label.toString());
+ }
+
+ visitBreak(HBreak node) {
+ assert(currentBlock.successors.length == 1);
+ addIndentation();
+ buffer.add("break");
+ if (node.label !== null) {
+ buffer.add(" ");
+ addLabel(node.label);
+ }
+ buffer.add(";\n");
+ List<HBasicBlock> dominated = currentBlock.dominatedBlocks;
+ // No block finishing with a 'throw' can have more than
+ // one dominated block (since it has only one successor).
+ // If the successor is dominated by another block, then the other block
+ // is responsible for visiting the successor.
+ if (dominated.isEmpty()) return;
+ if (dominated.length > 2) unreachable();
+ if (dominated.length == 2 && currentBlock !== currentGraph.entry) {
+ unreachable();
+ }
+ assert(dominated[0] == currentBlock.successors[0]);
+ visitBasicBlock(dominated[0]);
+ }
+
visitTry(HTry node) {
addIndentation();
buffer.add('try {\n');
@@ -427,7 +485,6 @@ class SsaCodeGenerator implements HVisitor {
// too. The if happens to dominate the exit-block.
assert(!node.hasElse);
assert(dominatedCount == 3);
- assert(dominated.last().isExitBlock());
visitBasicBlock(dominated[1]);
visitBasicBlock(dominated[2]);
}
@@ -579,13 +636,11 @@ class SsaCodeGenerator implements HVisitor {
}
endLoop(node.block);
visitBasicBlock(branchBlock.successors[1]);
- // TODO(floitsch): with labeled breaks we can have more dominated blocks.
- assert(dominated.length <= 3);
- if (dominated.length == 3) {
- // This happens when the body contains a 'return', and the exit-block is
- // not dominated by a dominator of the while loop.
- assert(dominated[2].isExitBlock());
- visitBasicBlock(dominated[2]);
+ // With labeled breaks we can have more dominated blocks.
+ if (dominated.length >= 3) {
+ for (int i = 2; i < dominated.length; i++) {
+ visitBasicBlock(dominated[i]);
+ }
}
}
@@ -896,6 +951,9 @@ class SsaOptimizedCodeGenerator extends SsaCodeGenerator {
void beginLoop(HBasicBlock block) {
addIndentation();
+ for (SourceString label in block.loopInformation.labels) {
+ buffer.add("${label.stringValue}:");
+ }
buffer.add('while (true) {\n');
indent++;
}
@@ -1057,6 +1115,10 @@ class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator {
buffer.add('}\n'); // Close 'switch'.
}
+ void addLabel(SourceString label) {
+ buffer.add("\$$label");
+ }
+
void beginLoop(HBasicBlock block) {
// TODO(ngeoffray): Don't put labels on loops that don't bailout.
String newLabel = pushLabel();
@@ -1065,6 +1127,10 @@ class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator {
}
addIndentation();
+ for (SourceString label in block.loopInformation.labels) {
+ addLabel(label);
+ buffer.add(":");
+ }
buffer.add('$newLabel: while (true) {\n');
indent++;
« no previous file with comments | « frog/leg/ssa/builder.dart ('k') | frog/leg/ssa/nodes.dart » ('j') | frog/leg/ssa/nodes.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698