use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockUtils method skipPredSyntheticPaths.
/**
* Set 'SKIP' flag for all synthetic predecessors from start block.
*/
public static void skipPredSyntheticPaths(BlockNode block) {
for (BlockNode pred : block.getPredecessors()) {
if (pred.contains(AFlag.SYNTHETIC) && !pred.contains(AFlag.EXC_TOP_SPLITTER) && !pred.contains(AFlag.EXC_BOTTOM_SPLITTER) && pred.getInstructions().isEmpty()) {
pred.add(AFlag.DONT_GENERATE);
skipPredSyntheticPaths(pred);
}
}
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockUtils method collectPredecessors.
public static List<BlockNode> collectPredecessors(MethodNode mth, BlockNode start, Collection<BlockNode> stopBlocks) {
BitSet bs = newBlocksBitSet(mth);
if (!stopBlocks.isEmpty()) {
bs.or(blocksToBitSet(mth, stopBlocks));
}
List<BlockNode> list = new ArrayList<>();
traversePredecessors(start, bs, list::add);
return list;
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockUtils method visitBlocksOnPath.
/**
* Visit blocks on any path from start to end.
* Only one path will be visited!
*/
public static boolean visitBlocksOnPath(MethodNode mth, BlockNode start, BlockNode end, Consumer<BlockNode> visitor) {
visitor.accept(start);
if (start == end) {
return true;
}
if (start.getCleanSuccessors().contains(end)) {
visitor.accept(end);
return true;
}
// DFS on clean successors
BitSet visited = newBlocksBitSet(mth);
Deque<BlockNode> queue = new ArrayDeque<>();
queue.addLast(start);
while (true) {
BlockNode current = queue.peekLast();
if (current == null) {
return false;
}
boolean added = false;
for (BlockNode next : current.getCleanSuccessors()) {
if (next == end) {
// start already visited
queue.removeFirst();
queue.addLast(next);
queue.forEach(visitor);
return true;
}
int id = next.getId();
if (!visited.get(id)) {
visited.set(id);
queue.addLast(next);
added = true;
break;
}
}
if (!added) {
queue.pollLast();
if (queue.isEmpty()) {
return false;
}
}
}
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockUtils method calcPartialPostDominance.
public static Map<BlockNode, BitSet> calcPartialPostDominance(MethodNode mth, Collection<BlockNode> blockNodes, BlockNode exitBlock) {
int blocksCount = mth.getBasicBlocks().size();
Map<BlockNode, BitSet> map = new HashMap<>(blocksCount);
BitSet initSet = new BitSet(blocksCount);
for (BlockNode block : blockNodes) {
initSet.set(block.getId());
}
for (BlockNode block : blockNodes) {
BitSet postDoms = new BitSet(blocksCount);
postDoms.or(initSet);
map.put(block, postDoms);
}
BitSet exitBitSet = map.get(exitBlock);
exitBitSet.clear();
exitBitSet.set(exitBlock.getId());
BitSet domSet = new BitSet(blocksCount);
boolean changed;
do {
changed = false;
for (BlockNode block : blockNodes) {
if (block == exitBlock) {
continue;
}
BitSet d = map.get(block);
if (!changed) {
domSet.clear();
domSet.or(d);
}
for (BlockNode scc : block.getSuccessors()) {
BitSet scPDoms = map.get(scc);
if (scPDoms != null) {
d.and(scPDoms);
}
}
d.set(block.getId());
if (!changed && !d.equals(domSet)) {
changed = true;
map.put(block, d);
}
}
} while (changed);
blockNodes.forEach(block -> {
BitSet postDoms = map.get(block);
postDoms.clear(block.getId());
if (postDoms.isEmpty()) {
map.put(block, EmptyBitSet.EMPTY);
}
});
return map;
}
use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.
the class BlockUtils method collectInsnsWithLimit.
/**
* Return limited number of instructions from method.
* Return empty list if method contains more than limit.
*/
public static List<InsnNode> collectInsnsWithLimit(List<BlockNode> blocks, int limit) {
List<InsnNode> insns = new ArrayList<>(limit);
for (BlockNode block : blocks) {
List<InsnNode> blockInsns = block.getInstructions();
int blockSize = blockInsns.size();
if (blockSize == 0) {
continue;
}
if (insns.size() + blockSize > limit) {
return Collections.emptyList();
}
insns.addAll(blockInsns);
}
return insns;
}
Aggregations