use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.
the class ConstInlineVisitor method replaceConst.
private static boolean replaceConst(MethodNode mth, InsnNode constInsn, long literal) {
SSAVar sVar = constInsn.getResult().getSVar();
List<RegisterArg> use = new ArrayList<RegisterArg>(sVar.getUseList());
int replaceCount = 0;
for (RegisterArg arg : use) {
InsnNode useInsn = arg.getParentInsn();
if (useInsn == null || useInsn.getType() == InsnType.PHI || useInsn.getType() == InsnType.MERGE) {
continue;
}
LiteralArg litArg;
ArgType argType = arg.getType();
if (argType.isObject() && literal != 0) {
argType = ArgType.NARROW_NUMBERS;
}
if (use.size() == 1 || arg.isTypeImmutable()) {
// arg used only in one place
litArg = InsnArg.lit(literal, argType);
} else if (useInsn.getType() == InsnType.MOVE && !useInsn.getResult().getType().isTypeKnown()) {
// save type for 'move' instructions (hard to find type in chains of 'move')
litArg = InsnArg.lit(literal, argType);
} else {
// in most cases type not equal arg.getType()
// just set unknown type and run type fixer
litArg = InsnArg.lit(literal, ArgType.UNKNOWN);
}
if (useInsn.replaceArg(arg, litArg)) {
fixTypes(mth, useInsn, litArg);
replaceCount++;
if (useInsn.getType() == InsnType.RETURN) {
useInsn.setSourceLine(constInsn.getSourceLine());
}
FieldNode f = null;
ArgType litArgType = litArg.getType();
if (litArgType.isTypeKnown()) {
f = mth.getParentClass().getConstFieldByLiteralArg(litArg);
} else if (litArgType.contains(PrimitiveType.INT)) {
f = mth.getParentClass().getConstField((int) literal, false);
}
if (f != null) {
litArg.wrapInstruction(new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0));
}
}
}
return replaceCount == use.size();
}
use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.
the class DebugInfoParser method merge.
private static void merge(InsnArg arg, LocalVar var) {
if (arg == null || !arg.isRegister()) {
return;
}
RegisterArg reg = (RegisterArg) arg;
if (var.getRegNum() != reg.getRegNum()) {
return;
}
boolean mergeRequired = false;
SSAVar ssaVar = reg.getSVar();
if (ssaVar != null) {
int ssaEnd = ssaVar.getEndAddr();
int ssaStart = ssaVar.getStartAddr();
int localStart = var.getStartAddr();
int localEnd = var.getEndAddr();
boolean isIntersected = !(localEnd < ssaStart || ssaEnd < localStart);
if (isIntersected && ssaEnd <= localEnd) {
mergeRequired = true;
}
} else {
mergeRequired = true;
}
if (mergeRequired) {
reg.mergeDebugInfo(var.getType(), var.getName());
}
}
use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.
the class SSATransform method replacePhiWithMove.
private static boolean replacePhiWithMove(MethodNode mth, BlockNode block, PhiInsn phi, RegisterArg arg) {
List<InsnNode> insns = block.getInstructions();
int phiIndex = InsnList.getIndex(insns, phi);
if (phiIndex == -1) {
return false;
}
SSAVar assign = phi.getResult().getSVar();
SSAVar argVar = arg.getSVar();
if (argVar != null) {
argVar.removeUse(arg);
argVar.setUsedInPhi(null);
}
// try inline
if (inlinePhiInsn(mth, block, phi)) {
insns.remove(phiIndex);
} else {
assign.setUsedInPhi(null);
InsnNode m = new InsnNode(InsnType.MOVE, 1);
m.add(AFlag.SYNTHETIC);
m.setResult(phi.getResult());
m.addArg(arg);
arg.getSVar().use(arg);
insns.set(phiIndex, m);
}
return true;
}
use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.
the class TypeInference method visit.
@Override
public void visit(MethodNode mth) throws JadxException {
if (mth.isNoCode()) {
return;
}
DexNode dex = mth.dex();
for (SSAVar var : mth.getSVars()) {
// inference variable type
ArgType type = processType(dex, var);
if (type == null) {
type = ArgType.UNKNOWN;
}
var.setType(type);
// search variable name
String name = processVarName(var);
var.setName(name);
}
// fix type for vars used only in Phi nodes
for (SSAVar sVar : mth.getSVars()) {
PhiInsn phi = sVar.getUsedInPhi();
if (phi != null) {
processPhiNode(phi);
}
}
}
use of jadx.core.dex.instructions.args.SSAVar 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());
}
}
}
Aggregations