use of jadx.core.dex.attributes.nodes.PhiListAttr in project jadx by skylot.
the class EliminatePhiNodes method removePhiInstructions.
private static void removePhiInstructions(MethodNode mth) {
for (BlockNode block : mth.getBasicBlocks()) {
PhiListAttr phiList = block.get(AType.PHI_LIST);
if (phiList == null) {
continue;
}
List<PhiInsn> list = phiList.getList();
for (PhiInsn phiInsn : list) {
removeInsn(mth, block, phiInsn);
}
}
}
use of jadx.core.dex.attributes.nodes.PhiListAttr in project jadx by skylot.
the class SSATransform method renameVar.
private static void renameVar(MethodNode mth, SSAVar[] vars, int[] vers, BlockNode block) {
SSAVar[] inputVars = Arrays.copyOf(vars, vars.length);
for (InsnNode insn : block.getInstructions()) {
if (insn.getType() != InsnType.PHI) {
for (InsnArg arg : insn.getArguments()) {
if (!arg.isRegister()) {
continue;
}
RegisterArg reg = (RegisterArg) arg;
int regNum = reg.getRegNum();
SSAVar var = vars[regNum];
if (var == null) {
throw new JadxRuntimeException("Not initialized variable reg: " + regNum + ", insn: " + insn + ", block:" + block + ", method: " + mth);
}
var.use(reg);
}
}
RegisterArg result = insn.getResult();
if (result != null) {
int regNum = result.getRegNum();
vars[regNum] = newSSAVar(mth, vers, result, regNum);
}
}
for (BlockNode s : block.getSuccessors()) {
PhiListAttr phiList = s.get(AType.PHI_LIST);
if (phiList == null) {
continue;
}
for (PhiInsn phiInsn : phiList.getList()) {
int regNum = phiInsn.getResult().getRegNum();
SSAVar var = vars[regNum];
if (var == null) {
continue;
}
RegisterArg arg = phiInsn.bindArg(block);
var.use(arg);
var.setUsedInPhi(phiInsn);
}
}
for (BlockNode domOn : block.getDominatesOn()) {
renameVar(mth, vars, vers, domOn);
}
System.arraycopy(inputVars, 0, vars, 0, vars.length);
}
use of jadx.core.dex.attributes.nodes.PhiListAttr in project jadx by skylot.
the class DebugUtils method checkPHI.
private static void checkPHI(MethodNode mth) {
for (BlockNode block : mth.getBasicBlocks()) {
List<PhiInsn> phis = new ArrayList<PhiInsn>();
for (InsnNode insn : block.getInstructions()) {
if (insn.getType() == InsnType.PHI) {
PhiInsn phi = (PhiInsn) insn;
phis.add(phi);
if (phi.getArgsCount() != phi.getBlockBinds().size()) {
throw new JadxRuntimeException("Incorrect args and binds in PHI");
}
if (phi.getArgsCount() == 0) {
throw new JadxRuntimeException("No args and binds in PHI");
}
for (InsnArg arg : insn.getArguments()) {
if (arg instanceof RegisterArg) {
BlockNode b = phi.getBlockByArg((RegisterArg) arg);
if (b == null) {
throw new JadxRuntimeException("Predecessor block not found");
}
} else {
throw new JadxRuntimeException("Not register in phi insn");
}
}
}
}
PhiListAttr phiListAttr = block.get(AType.PHI_LIST);
if (phiListAttr == null) {
if (!phis.isEmpty()) {
throw new JadxRuntimeException("Missing PHI list attribute");
}
} else {
List<PhiInsn> phiList = phiListAttr.getList();
if (phiList.isEmpty()) {
throw new JadxRuntimeException("Empty PHI list attribute");
}
if (!phis.containsAll(phiList) || !phiList.containsAll(phis)) {
throw new JadxRuntimeException("Instructions not match");
}
}
}
for (SSAVar ssaVar : mth.getSVars()) {
PhiInsn usedInPhi = ssaVar.getUsedInPhi();
if (usedInPhi != null) {
boolean found = false;
for (RegisterArg useArg : ssaVar.getUseList()) {
InsnNode parentInsn = useArg.getParentInsn();
if (parentInsn != null && parentInsn == usedInPhi) {
found = true;
}
}
if (!found) {
throw new JadxRuntimeException("Used in phi incorrect");
}
}
}
}
use of jadx.core.dex.attributes.nodes.PhiListAttr in project jadx by skylot.
the class DebugChecks method checkPHI.
private static void checkPHI(MethodNode mth) {
for (BlockNode block : mth.getBasicBlocks()) {
List<PhiInsn> phis = new ArrayList<>();
for (InsnNode insn : block.getInstructions()) {
if (insn.getType() == InsnType.PHI) {
PhiInsn phi = (PhiInsn) insn;
phis.add(phi);
if (phi.getArgsCount() == 0) {
throw new JadxRuntimeException("No args and binds in PHI");
}
for (InsnArg arg : insn.getArguments()) {
if (arg instanceof RegisterArg) {
BlockNode b = phi.getBlockByArg((RegisterArg) arg);
if (b == null) {
throw new JadxRuntimeException("Predecessor block not found");
}
} else {
throw new JadxRuntimeException("Not register in phi insn");
}
}
}
}
PhiListAttr phiListAttr = block.get(AType.PHI_LIST);
if (phiListAttr == null) {
if (!phis.isEmpty()) {
throw new JadxRuntimeException("Missing PHI list attribute");
}
} else {
List<PhiInsn> phiList = phiListAttr.getList();
if (phiList.isEmpty()) {
throw new JadxRuntimeException("Empty PHI list attribute");
}
if (!phis.containsAll(phiList) || !phiList.containsAll(phis)) {
throw new JadxRuntimeException("Instructions not match");
}
}
}
for (SSAVar ssaVar : mth.getSVars()) {
for (PhiInsn usedInPhi : ssaVar.getUsedInPhi()) {
boolean found = false;
for (RegisterArg useArg : ssaVar.getUseList()) {
InsnNode parentInsn = useArg.getParentInsn();
if (parentInsn != null && parentInsn == usedInPhi) {
found = true;
break;
}
}
if (!found) {
throw new JadxRuntimeException("Used in phi incorrect");
}
}
}
}
use of jadx.core.dex.attributes.nodes.PhiListAttr in project jadx by skylot.
the class TypeInferenceVisitor method tryInsertAdditionalMove.
private boolean tryInsertAdditionalMove(MethodNode mth) {
int insnsAdded = 0;
for (BlockNode block : mth.getBasicBlocks()) {
PhiListAttr phiListAttr = block.get(AType.PHI_LIST);
if (phiListAttr != null) {
for (PhiInsn phiInsn : phiListAttr.getList()) {
insnsAdded += tryInsertAdditionalInsn(mth, phiInsn);
}
}
}
if (insnsAdded == 0) {
return false;
}
if (Consts.DEBUG_TYPE_INFERENCE) {
mth.addDebugComment("Additional " + insnsAdded + " move instructions added to help type inference");
}
InitCodeVariables.rerun(mth);
initTypeBounds(mth);
if (runTypePropagation(mth) && checkTypes(mth)) {
return true;
}
return tryDeduceTypes(mth);
}
Aggregations