use of jadx.core.dex.regions.Region in project jadx by skylot.
the class IfRegionVisitor method markElseIfChains.
/**
* Mark if-else-if chains
*/
private static void markElseIfChains(IfRegion ifRegion) {
if (hasSimpleReturnBlock(ifRegion.getThenRegion())) {
return;
}
IContainer elsRegion = ifRegion.getElseRegion();
if (elsRegion instanceof Region) {
List<IContainer> subBlocks = ((Region) elsRegion).getSubBlocks();
if (subBlocks.size() == 1 && subBlocks.get(0) instanceof IfRegion) {
subBlocks.get(0).add(AFlag.ELSE_IF_CHAIN);
elsRegion.add(AFlag.ELSE_IF_CHAIN);
}
}
}
use of jadx.core.dex.regions.Region in project jadx by skylot.
the class DebugUtils method printRegions.
public static void printRegions(MethodNode mth, boolean printInsns) {
Region mthRegion = mth.getRegion();
if (mthRegion == null) {
return;
}
printRegion(mth, mthRegion, printInsns);
}
use of jadx.core.dex.regions.Region in project jadx by skylot.
the class PrepareForCodeGen method moveConstructorInConstructor.
/**
* Check that 'super' or 'this' call in constructor is a first instruction.
* Otherwise move to top and add a warning if code breaks.
*/
private void moveConstructorInConstructor(MethodNode mth) {
if (mth.isConstructor()) {
ConstructorInsn constrInsn = searchConstructorCall(mth);
if (constrInsn != null && !constrInsn.contains(AFlag.DONT_GENERATE)) {
Region oldRootRegion = mth.getRegion();
boolean firstInsn = BlockUtils.isFirstInsn(mth, constrInsn);
DeclareVariablesAttr declVarsAttr = oldRootRegion.get(AType.DECLARE_VARIABLES);
if (firstInsn && declVarsAttr == null) {
// move not needed
return;
}
// move constructor instruction to new root region
String callType = constrInsn.getCallType().toString().toLowerCase();
BlockNode blockByInsn = BlockUtils.getBlockByInsn(mth, constrInsn);
if (blockByInsn == null) {
mth.addWarn("Failed to move " + callType + " instruction to top");
return;
}
InsnList.remove(blockByInsn, constrInsn);
Region region = new Region(null);
region.add(new InsnContainer(Collections.singletonList(constrInsn)));
region.add(oldRootRegion);
mth.setRegion(region);
if (!firstInsn) {
Set<RegisterArg> regArgs = new HashSet<>();
constrInsn.getRegisterArgs(regArgs);
regArgs.remove(mth.getThisArg());
mth.getArgRegs().forEach(regArgs::remove);
if (!regArgs.isEmpty()) {
mth.addWarn("Illegal instructions before constructor call");
} else {
mth.addWarnComment("'" + callType + "' call moved to the top of the method (can break code semantics)");
}
}
}
}
}
use of jadx.core.dex.regions.Region in project jadx by skylot.
the class ProcessTryCatchRegions method wrapBlocks.
/**
* Extract all block dominated by 'dominator' to separate region and mark as try/catch block
*/
private static boolean wrapBlocks(IRegion replaceRegion, TryCatchBlockAttr tb, BlockNode dominator) {
if (replaceRegion == null) {
return false;
}
if (replaceRegion instanceof LoopRegion) {
LoopRegion loop = (LoopRegion) replaceRegion;
return wrapBlocks(loop.getBody(), tb, dominator);
}
if (replaceRegion instanceof IBranchRegion) {
return wrapBlocks(replaceRegion.getParent(), tb, dominator);
}
Region tryRegion = new Region(replaceRegion);
List<IContainer> subBlocks = replaceRegion.getSubBlocks();
for (IContainer cont : subBlocks) {
if (RegionUtils.hasPathThroughBlock(dominator, cont)) {
if (isHandlerPath(tb, cont)) {
break;
}
tryRegion.getSubBlocks().add(cont);
}
}
if (tryRegion.getSubBlocks().isEmpty()) {
return false;
}
TryCatchRegion tryCatchRegion = new TryCatchRegion(replaceRegion, tryRegion);
tryRegion.setParent(tryCatchRegion);
tryCatchRegion.setTryCatchBlock(tb);
// replace first node by region
IContainer firstNode = tryRegion.getSubBlocks().get(0);
if (!replaceRegion.replaceSubBlock(firstNode, tryCatchRegion)) {
return false;
}
subBlocks.removeAll(tryRegion.getSubBlocks());
// fix parents for tryRegion sub blocks
for (IContainer cont : tryRegion.getSubBlocks()) {
if (cont instanceof AbstractRegion) {
AbstractRegion aReg = (AbstractRegion) cont;
aReg.setParent(tryRegion);
}
}
return true;
}
Aggregations