Fix 'switch' codegen for empty case block

This commit is contained in:
Skylot
2013-04-24 23:49:31 +04:00
parent e60b599260
commit 4e7ef9f4d2
6 changed files with 90 additions and 25 deletions
@@ -36,6 +36,13 @@ public class CodeWriter {
return this;
}
public CodeWriter startLine(char c) {
buf.append(NL);
buf.append(indentStr);
buf.append(c);
return this;
}
public CodeWriter startLine(int ind, String str) {
buf.append(NL);
buf.append(indentStr);
+30 -18
View File
@@ -107,7 +107,7 @@ public class RegionGen extends InsnGen {
IfNode insn = region.getIfInsn();
code.add("if ").add(makeCondition(insn)).add(" {");
makeRegionIndent(code, region.getThenRegion());
code.startLine("}");
code.startLine('}');
IContainer els = region.getElseRegion();
if (els != null && RegionUtils.notEmpty(els)) {
@@ -123,11 +123,11 @@ public class RegionGen extends InsnGen {
}
}
code.add("{");
code.add('{');
code.incIndent();
makeRegion(code, els);
code.decIndent();
code.startLine("}");
code.startLine('}');
}
}
@@ -136,7 +136,7 @@ public class RegionGen extends InsnGen {
// infinite loop
code.startLine("while (true) {");
makeRegionIndent(code, region.getBody());
code.startLine("}");
code.startLine('}');
return code;
}
@@ -144,11 +144,11 @@ public class RegionGen extends InsnGen {
if (!region.isConditionAtEnd()) {
code.startLine("while ").add(makeCondition(insn)).add(" {");
makeRegionIndent(code, region.getBody());
code.startLine("}");
code.startLine('}');
} else {
code.startLine("do {");
makeRegionIndent(code, region.getBody());
code.startLine("} while ").add(makeCondition(insn)).add(";");
code.startLine("} while ").add(makeCondition(insn)).add(';');
}
return code;
}
@@ -156,7 +156,7 @@ public class RegionGen extends InsnGen {
private void makeSynchronizedRegion(SynchronizedRegion cont, CodeWriter code) throws CodegenException {
code.startLine("synchronized(").add(arg(cont.getArg())).add(") {");
makeRegionIndent(code, cont.getRegion());
code.startLine("}");
code.startLine('}');
}
private String makeCondition(IfNode insn) throws CodegenException {
@@ -194,25 +194,37 @@ public class RegionGen extends InsnGen {
List<Integer> keys = sw.getKeys().get(i);
IContainer c = sw.getCases().get(i);
for (Integer k : keys) {
code.startLine("case ")
.add(TypeGen.literalToString(k, arg.getType()))
.add(":");
code.startLine("case ");
code.add(TypeGen.literalToString(k, arg.getType()));
code.add(':');
}
makeRegionIndent(code, c);
if (RegionUtils.hasExitEdge(c))
code.startLine(1, "break;");
makeCaseBlock(c, code);
}
if (sw.getDefaultCase() != null) {
code.startLine("default:");
makeRegionIndent(code, sw.getDefaultCase());
if (RegionUtils.hasExitEdge(sw.getDefaultCase()))
code.startLine(1, "break;");
makeCaseBlock(sw.getDefaultCase(), code);
}
code.decIndent();
code.startLine("}");
code.startLine('}');
return code;
}
private void makeCaseBlock(IContainer c, CodeWriter code) throws CodegenException {
if (RegionUtils.notEmpty(c)) {
boolean closeBlock = RegionUtils.hasExitEdge(c);
if (closeBlock) {
code.add(" {");
}
makeRegionIndent(code, c);
if (closeBlock) {
code.startLine(1, "break;");
code.startLine('}');
}
} else {
code.startLine(1, "break;");
}
}
private void makeTryCatch(IContainer region, TryCatchBlock tryCatchBlock, CodeWriter code)
throws CodegenException {
code.startLine("try {");
@@ -235,7 +247,7 @@ public class RegionGen extends InsnGen {
code.startLine("} finally {");
makeRegionIndent(code, tryCatchBlock.getFinalBlock());
}
code.startLine("}");
code.startLine('}');
}
private void makeCatchBlock(CodeWriter code, ExceptionHandler handler)
@@ -148,10 +148,13 @@ public class ModVisitor extends AbstractVisitor {
break;
case RETURN:
if (insn.getArgsCount() == 0
&& mth.getBasicBlocks().size() == 1
&& i == size - 1)
remover.add(insn);
if (insn.getArgsCount() == 0) {
if (mth.getBasicBlocks().size() == 1 && i == size - 1) {
remover.add(insn);
} else if (mth.getMethodInfo().isClassInit()) {
remover.add(insn);
}
}
break;
default:
@@ -404,7 +404,6 @@ public class RegionMaker {
}
Map<BlockNode, List<Integer>> blocksMap = new LinkedHashMap<BlockNode, List<Integer>>(len);
for (Entry<Integer, List<Integer>> entry : casesMap.entrySet()) {
BlockNode c = BlockUtils.getBlockByOffset(entry.getKey(), block.getSuccessors());
assert c != null;
@@ -413,7 +412,7 @@ public class RegionMaker {
BitSet succ = BlockUtils.blocksToBitSet(mth, block.getSuccessors());
BitSet domsOn = BlockUtils.blocksToBitSet(mth, block.getDominatesOn());
domsOn.andNot(succ); // filter 'out' block
domsOn.and(succ); // filter 'out' block
BlockNode defCase = BlockUtils.getBlockByOffset(insn.getDefaultCaseOffset(), block.getSuccessors());
if (defCase != null) {
@@ -458,7 +457,12 @@ public class RegionMaker {
}
for (Entry<BlockNode, List<Integer>> entry : blocksMap.entrySet()) {
BlockNode c = entry.getKey();
sw.addCase(entry.getValue(), makeRegion(c, stack));
if (stack.containsExit(c)) {
// empty case block
sw.addCase(entry.getValue(), new Region(stack.peekRegion()));
} else {
sw.addCase(entry.getValue(), makeRegion(c, stack));
}
}
stack.pop();