Commit 6fbcf46a authored by Skylot's avatar Skylot

core: refactor return remover visitor

parent a36bc8f2
...@@ -80,7 +80,7 @@ public class ConstInlinerVisitor extends AbstractVisitor { ...@@ -80,7 +80,7 @@ public class ConstInlinerVisitor extends AbstractVisitor {
} }
/** /**
* This is method similar to PostTypeInference.visit method, * This is method similar to PostTypeInference.process method,
* but contains some expensive operations needed only after constant inline * but contains some expensive operations needed only after constant inline
*/ */
private static void fixTypes(MethodNode mth, InsnNode insn, LiteralArg litArg) { private static void fixTypes(MethodNode mth, InsnNode insn, LiteralArg litArg) {
......
...@@ -12,13 +12,11 @@ import jadx.core.dex.regions.IfRegion; ...@@ -12,13 +12,11 @@ import jadx.core.dex.regions.IfRegion;
import jadx.core.dex.regions.LoopRegion; import jadx.core.dex.regions.LoopRegion;
import jadx.core.dex.regions.SwitchRegion; import jadx.core.dex.regions.SwitchRegion;
import jadx.core.dex.visitors.AbstractVisitor; import jadx.core.dex.visitors.AbstractVisitor;
import jadx.core.utils.RegionUtils;
import jadx.core.utils.exceptions.JadxException; import jadx.core.utils.exceptions.JadxException;
import jadx.core.utils.exceptions.JadxRuntimeException;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Set;
/** /**
* Remove unnecessary return instructions for void methods * Remove unnecessary return instructions for void methods
...@@ -85,7 +83,7 @@ public class ReturnVisitor extends AbstractVisitor { ...@@ -85,7 +83,7 @@ public class ReturnVisitor extends AbstractVisitor {
IContainer subBlock = itSubBlock.previous(); IContainer subBlock = itSubBlock.previous();
if (subBlock == curContainer) { if (subBlock == curContainer) {
break; break;
} else if (notEmpty(subBlock)) { } else if (!isEmpty(subBlock)) {
return false; return false;
} }
} }
...@@ -95,25 +93,25 @@ public class ReturnVisitor extends AbstractVisitor { ...@@ -95,25 +93,25 @@ public class ReturnVisitor extends AbstractVisitor {
return true; return true;
} }
private static boolean notEmpty(IContainer subBlock) { /**
if (subBlock.contains(AFlag.RETURN)) { * Check if container not contains instructions,
* don't count one 'return' instruction (it will be removed later).
*/
private static boolean isEmpty(IContainer container) {
if (container instanceof BlockNode) {
BlockNode block = (BlockNode) container;
return block.getInstructions().isEmpty() || block.contains(AFlag.RETURN);
} else if (container instanceof IRegion) {
IRegion region = (IRegion) container;
for (IContainer block : region.getSubBlocks()) {
if(!isEmpty(block)) {
return false; return false;
} }
int insnCount = RegionUtils.insnsCount(subBlock);
if (insnCount > 1) {
return true;
} }
if (insnCount == 1) {
// don't count one 'return' instruction (it will be removed later)
Set<BlockNode> blocks = new HashSet<BlockNode>();
RegionUtils.getAllRegionBlocks(subBlock, blocks);
for (BlockNode node : blocks) {
if (!node.contains(AFlag.RETURN) && !node.getInstructions().isEmpty()) {
return true; return true;
} else {
throw new JadxRuntimeException("Unknown container type: " + container.getClass());
} }
} }
} }
return false;
}
}
} }
...@@ -19,7 +19,7 @@ public class FinishTypeInference extends AbstractVisitor { ...@@ -19,7 +19,7 @@ public class FinishTypeInference extends AbstractVisitor {
change = false; change = false;
for (BlockNode block : mth.getBasicBlocks()) { for (BlockNode block : mth.getBasicBlocks()) {
for (InsnNode insn : block.getInstructions()) { for (InsnNode insn : block.getInstructions()) {
if (PostTypeInference.visit(mth, insn)) { if (PostTypeInference.process(mth, insn)) {
change = true; change = true;
} }
} }
......
...@@ -15,7 +15,7 @@ import java.util.List; ...@@ -15,7 +15,7 @@ import java.util.List;
public class PostTypeInference { public class PostTypeInference {
public static boolean visit(MethodNode mth, InsnNode insn) { public static boolean process(MethodNode mth, InsnNode insn) {
switch (insn.getType()) { switch (insn.getType()) {
case CONST: case CONST:
RegisterArg res = insn.getResult(); RegisterArg res = insn.getResult();
......
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