use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockFinallyExtract method mergeReturns.
private static boolean mergeReturns(MethodNode mth, Set<BlocksPair> outs) {
Set<BlockNode> rightOuts = new HashSet<BlockNode>();
boolean allReturns = true;
for (BlocksPair outPair : outs) {
BlockNode first = outPair.getFirst();
if (!first.isReturnBlock()) {
allReturns = false;
}
rightOuts.add(outPair.getSecond());
}
if (!allReturns || rightOuts.size() != 1) {
return false;
}
Iterator<BlocksPair> it = outs.iterator();
while (it.hasNext()) {
BlocksPair out = it.next();
BlockNode returnBlock = out.getFirst();
if (!returnBlock.contains(AFlag.ORIG_RETURN)) {
markForRemove(mth, returnBlock);
it.remove();
}
}
return true;
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockFinish method visit.
@Override
public void visit(MethodNode mth) {
if (mth.isNoCode()) {
return;
}
for (BlockNode block : mth.getBasicBlocks()) {
block.updateCleanSuccessors();
initBlocksInIfNodes(block);
fixSplitterBlock(block);
}
mth.finishBasicBlocks();
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class ModVisitor method removeStep.
/**
* Remove unnecessary instructions
*/
private static void removeStep(MethodNode mth, InstructionRemover remover) {
for (BlockNode block : mth.getBasicBlocks()) {
remover.setBlock(block);
for (InsnNode insn : block.getInstructions()) {
switch(insn.getType()) {
case NOP:
case GOTO:
case NEW_INSTANCE:
remover.add(insn);
break;
default:
break;
}
}
remover.perform();
}
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockProcessor method splitReturn.
/**
* Splice return block if several predecessors presents
*/
private static boolean splitReturn(MethodNode mth) {
if (mth.getExitBlocks().size() != 1) {
return false;
}
BlockNode exitBlock = mth.getExitBlocks().get(0);
if (exitBlock.getInstructions().size() != 1 || exitBlock.contains(AFlag.SYNTHETIC)) {
return false;
}
List<BlockNode> preds = exitBlock.getPredecessors();
if (preds.size() < 2) {
return false;
}
preds = BlockUtils.filterPredecessors(exitBlock);
if (preds.size() < 2) {
return false;
}
InsnNode returnInsn = exitBlock.getInstructions().get(0);
if (returnInsn.getArgsCount() != 0 && !isReturnArgAssignInPred(preds, returnInsn)) {
return false;
}
boolean first = true;
for (BlockNode pred : preds) {
BlockNode newRetBlock = BlockSplitter.startNewBlock(mth, exitBlock.getStartOffset());
newRetBlock.add(AFlag.SYNTHETIC);
InsnNode newRetInsn;
if (first) {
newRetInsn = returnInsn;
newRetBlock.add(AFlag.ORIG_RETURN);
first = false;
} else {
newRetInsn = duplicateReturnInsn(returnInsn);
}
newRetBlock.getInstructions().add(newRetInsn);
removeConnection(pred, exitBlock);
connect(pred, newRetBlock);
}
cleanExitNodes(mth);
return true;
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockProcessor method computeDominators.
private static void computeDominators(MethodNode mth) {
List<BlockNode> basicBlocks = mth.getBasicBlocks();
int nBlocks = basicBlocks.size();
for (int i = 0; i < nBlocks; i++) {
BlockNode block = basicBlocks.get(i);
block.setId(i);
block.setDoms(new BitSet(nBlocks));
block.getDoms().set(0, nBlocks);
}
BlockNode entryBlock = mth.getEnterBlock();
entryBlock.getDoms().clear();
entryBlock.getDoms().set(entryBlock.getId());
BitSet dset = new BitSet(nBlocks);
boolean changed;
do {
changed = false;
for (BlockNode block : basicBlocks) {
if (block == entryBlock) {
continue;
}
BitSet d = block.getDoms();
if (!changed) {
dset.clear();
dset.or(d);
}
for (BlockNode pred : block.getPredecessors()) {
d.and(pred.getDoms());
}
d.set(block.getId());
if (!changed && !d.equals(dset)) {
changed = true;
}
}
} while (changed);
markLoops(mth);
// clear self dominance
for (BlockNode block : basicBlocks) {
block.getDoms().clear(block.getId());
}
// calculate immediate dominators
for (BlockNode block : basicBlocks) {
if (block == entryBlock) {
continue;
}
BlockNode idom;
List<BlockNode> preds = block.getPredecessors();
if (preds.size() == 1) {
idom = preds.get(0);
} else {
BitSet bs = new BitSet(block.getDoms().length());
bs.or(block.getDoms());
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
BlockNode dom = basicBlocks.get(i);
bs.andNot(dom.getDoms());
}
if (bs.cardinality() != 1) {
throw new JadxRuntimeException("Can't find immediate dominator for block " + block + " in " + bs + " preds:" + preds);
}
idom = basicBlocks.get(bs.nextSetBit(0));
}
block.setIDom(idom);
idom.addDominatesOn(block);
}
}
Aggregations