Commit 9752ec26 authored by Skylot's avatar Skylot

core: fix duplicate regions creation (#314)

parent edc1e5fa
...@@ -5,7 +5,7 @@ import jadx.core.utils.InsnUtils; ...@@ -5,7 +5,7 @@ import jadx.core.utils.InsnUtils;
public class GotoNode extends TargetInsnNode { public class GotoNode extends TargetInsnNode {
protected int target; protected final int target;
public GotoNode(int target) { public GotoNode(int target) {
this(InsnType.GOTO, target, 0); this(InsnType.GOTO, target, 0);
......
...@@ -47,7 +47,6 @@ public class IfNode extends GotoNode { ...@@ -47,7 +47,6 @@ public class IfNode extends GotoNode {
BlockNode tmp = thenBlock; BlockNode tmp = thenBlock;
thenBlock = elseBlock; thenBlock = elseBlock;
elseBlock = tmp; elseBlock = tmp;
target = thenBlock.getStartOffset();
} }
public void changeCondition(IfOp op, InsnArg arg1, InsnArg arg2) { public void changeCondition(IfOp op, InsnArg arg1, InsnArg arg2) {
...@@ -89,6 +88,11 @@ public class IfNode extends GotoNode { ...@@ -89,6 +88,11 @@ public class IfNode extends GotoNode {
} }
@Override @Override
public int getTarget() {
return thenBlock == null ? target : thenBlock.getStartOffset();
}
@Override
public boolean isSame(InsnNode obj) { public boolean isSame(InsnNode obj) {
if (this == obj) { if (this == obj) {
return true; return true;
......
...@@ -240,7 +240,6 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode { ...@@ -240,7 +240,6 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
} }
} }
this.addAttr(new SourceFileAttr(fileName)); this.addAttr(new SourceFileAttr(fileName));
LOG.debug("Class '{}' compiled from '{}'", this, fileName);
} }
@Override @Override
...@@ -486,7 +485,6 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode { ...@@ -486,7 +485,6 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
return clsInfo.equals(other.clsInfo); return clsInfo.equals(other.clsInfo);
} }
return false; return false;
} }
@Override @Override
......
...@@ -5,6 +5,7 @@ import java.util.List; ...@@ -5,6 +5,7 @@ import java.util.List;
import jadx.core.dex.nodes.IContainer; import jadx.core.dex.nodes.IContainer;
import jadx.core.dex.nodes.IRegion; import jadx.core.dex.nodes.IRegion;
import jadx.core.utils.Utils;
public final class Region extends AbstractRegion { public final class Region extends AbstractRegion {
...@@ -39,15 +40,19 @@ public final class Region extends AbstractRegion { ...@@ -39,15 +40,19 @@ public final class Region extends AbstractRegion {
@Override @Override
public String baseString() { public String baseString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(blocks.size()); int size = blocks.size();
for (IContainer cont : blocks) { sb.append('(');
sb.append(cont.baseString()); sb.append(size);
} if (size > 0) {
sb.append(':');
Utils.listToString(sb, blocks, "|", IContainer::baseString);
}
sb.append(')');
return sb.toString(); return sb.toString();
} }
@Override @Override
public String toString() { public String toString() {
return "R:" + baseString(); return "R" + baseString();
} }
} }
...@@ -142,11 +142,10 @@ public final class IfCondition { ...@@ -142,11 +142,10 @@ public final class IfCondition {
Compare c = cond.getCompare(); Compare c = cond.getCompare();
simplifyCmpOp(c); simplifyCmpOp(c);
if (c.getOp() == IfOp.EQ && c.getB().isLiteral() && c.getB().equals(LiteralArg.FALSE)) { if (c.getOp() == IfOp.EQ && c.getB().isLiteral() && c.getB().equals(LiteralArg.FALSE)) {
return not(new IfCondition(c.invert())); cond = not(new IfCondition(c.invert()));
} else { } else {
c.normalize(); c.normalize();
} }
return cond;
} }
List<IfCondition> args = null; List<IfCondition> args = null;
for (int i = 0; i < cond.getArgs().size(); i++) { for (int i = 0; i < cond.getArgs().size(); i++) {
...@@ -225,7 +224,7 @@ public final class IfCondition { ...@@ -225,7 +224,7 @@ public final class IfCondition {
case TERNARY: case TERNARY:
return first() + " ? " + second() + " : " + third(); return first() + " ? " + second() + " : " + third();
case NOT: case NOT:
return "!" + first(); return "!(" + first() + ")";
case AND: case AND:
case OR: case OR:
String op = mode == Mode.OR ? " || " : " && "; String op = mode == Mode.OR ? " || " : " && ";
......
...@@ -79,7 +79,6 @@ public class BlockProcessor extends AbstractVisitor { ...@@ -79,7 +79,6 @@ public class BlockProcessor extends AbstractVisitor {
private static boolean removeEmptyBlock(BlockNode block) { private static boolean removeEmptyBlock(BlockNode block) {
if (canRemoveBlock(block)) { if (canRemoveBlock(block)) {
LOG.debug("Removing empty block: {}", block);
if (block.getSuccessors().size() == 1) { if (block.getSuccessors().size() == 1) {
BlockNode successor = block.getSuccessors().get(0); BlockNode successor = block.getSuccessors().get(0);
block.getPredecessors().forEach(pred -> { block.getPredecessors().forEach(pred -> {
......
...@@ -12,7 +12,6 @@ import java.util.Set; ...@@ -12,7 +12,6 @@ import java.util.Set;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import jadx.core.Consts;
import jadx.core.dex.attributes.AFlag; import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.AType; import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.nodes.EdgeInsnAttr; import jadx.core.dex.attributes.nodes.EdgeInsnAttr;
...@@ -43,7 +42,6 @@ import jadx.core.utils.BlockUtils; ...@@ -43,7 +42,6 @@ import jadx.core.utils.BlockUtils;
import jadx.core.utils.ErrorsCounter; import jadx.core.utils.ErrorsCounter;
import jadx.core.utils.InstructionRemover; import jadx.core.utils.InstructionRemover;
import jadx.core.utils.RegionUtils; import jadx.core.utils.RegionUtils;
import jadx.core.utils.exceptions.JadxOverflowException;
import jadx.core.utils.exceptions.JadxRuntimeException; import jadx.core.utils.exceptions.JadxRuntimeException;
import static jadx.core.dex.visitors.regions.IfMakerHelper.confirmMerge; import static jadx.core.dex.visitors.regions.IfMakerHelper.confirmMerge;
...@@ -62,12 +60,20 @@ public class RegionMaker { ...@@ -62,12 +60,20 @@ public class RegionMaker {
private final MethodNode mth; private final MethodNode mth;
private int regionsCount; private int regionsCount;
private Region[] regionByBlock;
public RegionMaker(MethodNode mth) { public RegionMaker(MethodNode mth) {
this.mth = mth; this.mth = mth;
this.regionByBlock = new Region[mth.getBasicBlocks().size()];
} }
public Region makeRegion(BlockNode startBlock, RegionStack stack) { public Region makeRegion(BlockNode startBlock, RegionStack stack) {
int startBlockId = startBlock.getId();
Region region = regionByBlock[startBlockId];
if (region != null) {
return region;
}
Region r = new Region(stack.peekRegion()); Region r = new Region(stack.peekRegion());
BlockNode next = startBlock; BlockNode next = startBlock;
while (next != null) { while (next != null) {
...@@ -77,6 +83,7 @@ public class RegionMaker { ...@@ -77,6 +83,7 @@ public class RegionMaker {
throw new JadxRuntimeException("Regions count limit reached"); throw new JadxRuntimeException("Regions count limit reached");
} }
} }
regionByBlock[startBlockId] = r;
return r; return r;
} }
......
...@@ -79,9 +79,7 @@ public class BlockUtils { ...@@ -79,9 +79,7 @@ public class BlockUtils {
} }
if (b.contains(AFlag.SYNTHETIC)) { if (b.contains(AFlag.SYNTHETIC)) {
List<BlockNode> s = b.getSuccessors(); List<BlockNode> s = b.getSuccessors();
if (s.size() == 1 && s.get(0).contains(AType.EXC_HANDLER)) { return s.size() == 1 && s.get(0).contains(AType.EXC_HANDLER);
return true;
}
} }
return false; return false;
} }
...@@ -156,7 +154,10 @@ public class BlockUtils { ...@@ -156,7 +154,10 @@ public class BlockUtils {
} }
@Nullable @Nullable
public static InsnNode getLastInsn(IBlock block) { public static InsnNode getLastInsn(@Nullable IBlock block) {
if (block == null) {
return null;
}
List<InsnNode> insns = block.getInstructions(); List<InsnNode> insns = block.getInstructions();
if (insns.isEmpty()) { if (insns.isEmpty()) {
return null; return null;
......
...@@ -4,6 +4,7 @@ import java.io.PrintWriter; ...@@ -4,6 +4,7 @@ import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.function.Function;
import jadx.api.JadxDecompiler; import jadx.api.JadxDecompiler;
...@@ -26,19 +27,30 @@ public class Utils { ...@@ -26,19 +27,30 @@ public class Utils {
return 'L' + obj.replace('.', '/') + ';'; return 'L' + obj.replace('.', '/') + ';';
} }
public static String listToString(Iterable<?> list) { public static String listToString(Iterable<?> objects) {
if (list == null) { return listToString(objects, ", ");
}
public static String listToString(Iterable<?> objects, String joiner) {
if (objects == null) {
return ""; return "";
} }
StringBuilder str = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (Iterator<?> it = list.iterator(); it.hasNext(); ) { listToString(sb, objects, joiner, Object::toString);
Object o = it.next(); return sb.toString();
str.append(o); }
public static <T> void listToString(StringBuilder sb, Iterable<T> objects, String joiner, Function<T, String> toStr) {
if (objects == null) {
return;
}
Iterator<T> it = objects.iterator();
if (it.hasNext()) { if (it.hasNext()) {
str.append(", "); sb.append(toStr.apply(it.next()));
} }
while (it.hasNext()) {
sb.append(joiner).append(toStr.apply(it.next()));
} }
return str.toString();
} }
public static String arrayToString(Object[] array) { public static String arrayToString(Object[] array) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment