IContainer thenRegion = ifRegion.getThenRegion();
IContainer elseRegion = ifRegion.getElseRegion();
if (thenRegion == null || elseRegion == null) {
return false;
}
BlockNode tb = getTernaryInsnBlock(thenRegion);
BlockNode eb = getTernaryInsnBlock(elseRegion);
if (tb == null || eb == null) {
return false;
}
BlockNode header = ifRegion.getHeader();
InsnNode t = tb.getInstructions().get(0);
InsnNode e = eb.getInstructions().get(0);
if (t.getSourceLine() != e.getSourceLine()) {
if (t.getSourceLine() != 0 && e.getSourceLine() != 0) {
// sometimes source lines incorrect
if (!checkLineStats(t, e)) {
return false;
}
} else {
// no debug info
if (containsTernary(t) || containsTernary(e)) {
// don't make nested ternary by default
// TODO: add addition checks
return false;
}
}
}
if (t.getResult() != null && e.getResult() != null) {
PhiInsn phi = t.getResult().getSVar().getUsedInPhi();
if (phi == null || !t.getResult().equalRegisterAndType(e.getResult())) {
return false;
}
if (!ifRegion.getParent().replaceSubBlock(ifRegion, header)) {
return false;
}
InsnList.remove(tb, t);
InsnList.remove(eb, e);
RegisterArg resArg;
if (phi.getArgsCount() == 2) {
resArg = phi.getResult();
} else {
resArg = t.getResult();
phi.removeArg(e.getResult());
}
TernaryInsn ternInsn = new TernaryInsn(ifRegion.getCondition(),
resArg, InsnArg.wrapArg(t), InsnArg.wrapArg(e));
ternInsn.setSourceLine(t.getSourceLine());
// remove 'if' instruction
header.getInstructions().clear();
header.getInstructions().add(ternInsn);
// shrink method again
CodeShrinker.shrinkMethod(mth);
return true;
}
if (!mth.getReturnType().equals(ArgType.VOID)
&& t.getType() == InsnType.RETURN && e.getType() == InsnType.RETURN) {
if (!ifRegion.getParent().replaceSubBlock(ifRegion, header)) {
return false;
}
InsnList.remove(tb, t);
InsnList.remove(eb, e);
tb.remove(AFlag.RETURN);
eb.remove(AFlag.RETURN);
TernaryInsn ternInsn = new TernaryInsn(ifRegion.getCondition(), null, t.getArg(0), e.getArg(0));
ternInsn.setSourceLine(t.getSourceLine());
InsnNode retInsn = new InsnNode(InsnType.RETURN, 1);
retInsn.addArg(InsnArg.wrapArg(ternInsn));
header.getInstructions().clear();
header.getInstructions().add(retInsn);
header.add(AFlag.RETURN);
CodeShrinker.shrinkMethod(mth);
return true;
}
return false;