use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.
the class BlockFinallyExtract method sameInsns.
private static boolean sameInsns(InsnNode remInsn, InsnNode fInsn, BlocksRemoveInfo removeInfo) {
if (!remInsn.isSame(fInsn)) {
return false;
}
// TODO: compare literals
for (int i = 0; i < remInsn.getArgsCount(); i++) {
InsnArg remArg = remInsn.getArg(i);
InsnArg fArg = fInsn.getArg(i);
if (remArg.isRegister() != fArg.isRegister()) {
return false;
}
if (removeInfo != null && fArg.isRegister()) {
RegisterArg remReg = (RegisterArg) remArg;
RegisterArg fReg = (RegisterArg) fArg;
if (remReg.getRegNum() != fReg.getRegNum()) {
RegisterArg mapReg = removeInfo.getRegMap().get(remArg);
if (mapReg == null) {
removeInfo.getRegMap().put(remReg, fReg);
} else if (!mapReg.equalRegisterAndType(fReg)) {
return false;
}
}
}
}
return true;
}
use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.
the class BlockFinallyExtract method performVariablesReMap.
private static void performVariablesReMap(MethodNode mth, List<BlocksRemoveInfo> removes, LiveVarAnalysis laBefore, LiveVarAnalysis laAfter) {
BitSet processed = new BitSet(mth.getRegsCount());
for (BlocksRemoveInfo removeInfo : removes) {
processed.clear();
BlocksPair start = removeInfo.getStart();
BlockNode insertBlockBefore = start.getFirst();
BlockNode insertBlock = start.getSecond();
if (removeInfo.getRegMap().isEmpty() || insertBlock == null) {
continue;
}
for (Map.Entry<RegisterArg, RegisterArg> entry : removeInfo.getRegMap().entrySet()) {
RegisterArg fromReg = entry.getKey();
RegisterArg toReg = entry.getValue();
int fromRegNum = fromReg.getRegNum();
int toRegNum = toReg.getRegNum();
if (!processed.get(fromRegNum)) {
boolean liveFromBefore = laBefore.isLive(insertBlockBefore, fromRegNum);
boolean liveFromAfter = laAfter.isLive(insertBlock, fromRegNum);
// boolean liveToBefore = laBefore.isLive(insertBlock, toRegNum);
boolean liveToAfter = laAfter.isLive(insertBlock, toRegNum);
if (liveToAfter && liveFromBefore) {
// merge 'to' and 'from' registers
InsnNode merge = new InsnNode(InsnType.MERGE, 2);
merge.setResult(toReg.duplicate());
merge.addArg(toReg.duplicate());
merge.addArg(fromReg.duplicate());
injectInsn(mth, insertBlock, merge);
} else if (liveFromBefore) {
// remap variable
InsnNode move = new InsnNode(InsnType.MOVE, 1);
move.setResult(toReg.duplicate());
move.addArg(fromReg.duplicate());
injectInsn(mth, insertBlock, move);
} else if (liveFromAfter) {
// kill variable
InsnNode kill = new InsnNode(InsnType.NOP, 0);
kill.setResult(fromReg.duplicate());
kill.add(AFlag.REMOVE);
injectInsn(mth, insertBlock, kill);
}
processed.set(fromRegNum);
}
}
}
}
use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.
the class TypeInference method processPhiNode.
private static void processPhiNode(PhiInsn phi) {
ArgType type = phi.getResult().getType();
if (!type.isTypeKnown()) {
for (InsnArg arg : phi.getArguments()) {
if (arg.getType().isTypeKnown()) {
type = arg.getType();
break;
}
}
}
phi.getResult().setType(type);
for (int i = 0; i < phi.getArgsCount(); i++) {
RegisterArg arg = phi.getArg(i);
arg.setType(type);
SSAVar sVar = arg.getSVar();
if (sVar != null) {
sVar.setName(phi.getResult().getName());
}
}
}
use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.
the class EliminatePhiNodes method replaceMerge.
/**
* Replace 'MERGE' with 'PHI' insn.
*/
private void replaceMerge(MethodNode mth, BlockNode block, InsnNode insn) {
if (insn.getArgsCount() != 2) {
throw new JadxRuntimeException("Unexpected count of arguments in merge insn: " + insn);
}
RegisterArg oldArg = (RegisterArg) insn.getArg(1);
RegisterArg newArg = (RegisterArg) insn.getArg(0);
int newRegNum = newArg.getRegNum();
if (oldArg.getRegNum() == newRegNum) {
throw new JadxRuntimeException("Unexpected register number in merge insn: " + insn);
}
SSAVar oldSVar = oldArg.getSVar();
RegisterArg assignArg = oldSVar.getAssign();
InsnNode assignParentInsn = assignArg.getParentInsn();
BlockNode assignBlock = BlockUtils.getBlockByInsn(mth, assignParentInsn);
if (assignBlock == null) {
throw new JadxRuntimeException("Unknown assign block for " + assignParentInsn);
}
BlockNode assignPred = null;
for (BlockNode pred : block.getPredecessors()) {
if (BlockUtils.isPathExists(assignBlock, pred)) {
assignPred = pred;
break;
}
}
if (assignPred == null) {
throw new JadxRuntimeException("Assign predecessor not found for " + assignBlock + " from " + block);
}
// all checks passed
RegisterArg newAssignArg = oldArg.duplicate(newRegNum, null);
SSAVar newSVar = mth.makeNewSVar(newRegNum, mth.getNextSVarVersion(newRegNum), newAssignArg);
newSVar.setName(oldSVar.getName());
newSVar.setType(assignArg.getType());
if (assignParentInsn != null) {
assignParentInsn.setResult(newAssignArg);
}
for (RegisterArg useArg : oldSVar.getUseList()) {
RegisterArg newUseArg = useArg.duplicate(newRegNum, newSVar);
InsnNode parentInsn = useArg.getParentInsn();
if (parentInsn != null) {
newSVar.use(newUseArg);
parentInsn.replaceArg(useArg, newUseArg);
}
}
block.getInstructions().remove(0);
PhiInsn phiInsn = SSATransform.addPhi(mth, block, newRegNum);
phiInsn.setResult(insn.getResult());
phiInsn.bindArg(newAssignArg.duplicate(), assignPred);
phiInsn.bindArg(newArg.duplicate(), BlockUtils.selectOtherSafe(assignPred, block.getPredecessors()));
}
use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.
the class LiveVarAnalysis method fillBasicBlockInfo.
private void fillBasicBlockInfo() {
for (BlockNode block : mth.getBasicBlocks()) {
int blockId = block.getId();
BitSet gen = uses[blockId];
BitSet kill = defs[blockId];
for (InsnNode insn : block.getInstructions()) {
for (InsnArg arg : insn.getArguments()) {
if (arg.isRegister()) {
int regNum = ((RegisterArg) arg).getRegNum();
if (!kill.get(regNum)) {
gen.set(regNum);
}
}
}
RegisterArg result = insn.getResult();
if (result != null) {
int regNum = result.getRegNum();
kill.set(regNum);
assignBlocks[regNum].set(blockId);
}
}
}
}
Aggregations