Refactoring: remove unused arg in InsnNode

This commit is contained in:
Skylot 2013-04-21 19:57:53 +04:00
parent 96e3e887ce
commit e60b599260
16 changed files with 86 additions and 78 deletions

View File

@ -165,4 +165,8 @@ public class AccessInfo {
return code.toString();
}
@Override
public String toString() {
return "AccessInfo: " + type + " " + accFlags + " (" + makeString() + ")";
}
}

View File

@ -68,6 +68,10 @@ public final class MethodInfo {
return args;
}
public int getArgsCount() {
return args.size();
}
public boolean isConstructor() {
return name.equals("<init>");
}

View File

@ -4,7 +4,6 @@ import jadx.dex.instructions.args.ArgType;
import jadx.dex.instructions.args.InsnArg;
import jadx.dex.instructions.args.RegisterArg;
import jadx.dex.nodes.InsnNode;
import jadx.dex.nodes.MethodNode;
import jadx.utils.InsnUtils;
import com.android.dx.io.instructions.DecodedInstruction;
@ -13,9 +12,8 @@ public class ArithNode extends InsnNode {
private final ArithOp op;
public ArithNode(MethodNode mth, DecodedInstruction insn, ArithOp op, ArgType type,
boolean literal) {
super(mth, InsnType.ARITH, 2);
public ArithNode(DecodedInstruction insn, ArithOp op, ArgType type, boolean literal) {
super(InsnType.ARITH, 2);
this.op = op;
setResult(InsnArg.reg(insn, 0, type));
@ -44,16 +42,16 @@ public class ArithNode extends InsnNode {
assert getArgsCount() == 2;
}
public ArithNode(MethodNode mth, ArithOp op, RegisterArg res, InsnArg a, InsnArg b) {
super(mth, InsnType.ARITH, 2);
public ArithNode(ArithOp op, RegisterArg res, InsnArg a, InsnArg b) {
super(InsnType.ARITH, 2);
setResult(res);
addArg(a);
addArg(b);
this.op = op;
}
public ArithNode(MethodNode mth, ArithOp op, RegisterArg res, InsnArg a) {
super(mth, InsnType.ARITH, 1);
public ArithNode(ArithOp op, RegisterArg res, InsnArg a) {
super(InsnType.ARITH, 1);
setResult(res);
addArg(a);
this.op = op;

View File

@ -4,7 +4,6 @@ import jadx.dex.instructions.args.ArgType;
import jadx.dex.instructions.args.InsnArg;
import jadx.dex.instructions.args.PrimitiveType;
import jadx.dex.nodes.InsnNode;
import jadx.dex.nodes.MethodNode;
import com.android.dx.io.instructions.FillArrayDataPayloadDecodedInstruction;
@ -12,8 +11,8 @@ public class FillArrayOp extends InsnNode {
private final Object data;
public FillArrayOp(MethodNode method, int resReg, FillArrayDataPayloadDecodedInstruction payload) {
super(method, InsnType.FILL_ARRAY, 0);
public FillArrayOp(int resReg, FillArrayDataPayloadDecodedInstruction payload) {
super(InsnType.FILL_ARRAY, 0);
this.data = payload.getData();

View File

@ -1,19 +1,18 @@
package jadx.dex.instructions;
import jadx.dex.nodes.InsnNode;
import jadx.dex.nodes.MethodNode;
import jadx.utils.InsnUtils;
public class GotoNode extends InsnNode {
protected int target;
public GotoNode(MethodNode mth, int target) {
this(mth, InsnType.GOTO, target);
public GotoNode(int target) {
this(InsnType.GOTO, target);
}
protected GotoNode(MethodNode mth, InsnType type, int target) {
super(mth, type);
protected GotoNode(InsnType type, int target) {
super(type);
this.target = target;
}

View File

@ -4,7 +4,6 @@ import jadx.dex.instructions.args.ArgType;
import jadx.dex.instructions.args.InsnArg;
import jadx.dex.instructions.args.LiteralArg;
import jadx.dex.instructions.args.PrimitiveType;
import jadx.dex.nodes.MethodNode;
import jadx.utils.InsnUtils;
import com.android.dx.io.instructions.DecodedInstruction;
@ -14,8 +13,8 @@ public class IfNode extends GotoNode {
protected boolean zeroCmp;
protected IfOp op;
public IfNode(MethodNode mth, IfOp op, int targ, InsnArg then, InsnArg els) {
super(mth, InsnType.IF, targ);
public IfNode(IfOp op, int targ, InsnArg then, InsnArg els) {
super(InsnType.IF, targ);
addArg(then);
if (els == null) {
zeroCmp = true;
@ -25,8 +24,8 @@ public class IfNode extends GotoNode {
}
}
public IfNode(MethodNode mth, DecodedInstruction insn, IfOp op) {
super(mth, InsnType.IF, insn.getTarget());
public IfNode(DecodedInstruction insn, IfOp op) {
super(InsnType.IF, insn.getTarget());
this.op = op;
ArgType type = ArgType.unknown(

View File

@ -1,15 +1,14 @@
package jadx.dex.instructions;
import jadx.dex.nodes.InsnNode;
import jadx.dex.nodes.MethodNode;
import jadx.utils.InsnUtils;
public class IndexInsnNode extends InsnNode {
protected final Object index;
public IndexInsnNode(MethodNode mth, InsnType type, Object index, int argCount) {
super(mth, type, argCount);
public IndexInsnNode(InsnType type, Object index, int argCount) {
super(type, argCount);
this.index = index;
}

View File

@ -1,6 +1,7 @@
package jadx.dex.instructions;
import jadx.dex.info.FieldInfo;
import jadx.dex.info.MethodInfo;
import jadx.dex.instructions.args.ArgType;
import jadx.dex.instructions.args.InsnArg;
import jadx.dex.instructions.args.PrimitiveType;
@ -76,7 +77,7 @@ public class InsnDecoder {
case Opcodes.MOVE_RESULT:
case Opcodes.MOVE_RESULT_WIDE:
case Opcodes.MOVE_RESULT_OBJECT:
return new InsnNode(method, InsnType.NOP, 0);
return new InsnNode(InsnType.NOP, 0);
case Opcodes.CONST:
case Opcodes.CONST_4:
@ -94,13 +95,13 @@ public class InsnDecoder {
case Opcodes.CONST_STRING:
case Opcodes.CONST_STRING_JUMBO: {
InsnNode node = new IndexInsnNode(method, InsnType.CONST, dex.getString(insn.getIndex()), 0);
InsnNode node = new IndexInsnNode(InsnType.CONST, dex.getString(insn.getIndex()), 0);
node.setResult(InsnArg.reg(insn, 0, ArgType.STRING));
return node;
}
case Opcodes.CONST_CLASS: {
InsnNode node = new IndexInsnNode(method, InsnType.CONST, dex.getType(insn.getIndex()), 0);
InsnNode node = new IndexInsnNode(InsnType.CONST, dex.getType(insn.getIndex()), 0);
node.setResult(InsnArg.reg(insn, 0, ArgType.CLASS));
return node;
}
@ -151,13 +152,13 @@ public class InsnDecoder {
return arith(insn, ArithOp.SUB, ArgType.INT);
case Opcodes.RSUB_INT:
return new ArithNode(method, ArithOp.SUB,
return new ArithNode(ArithOp.SUB,
InsnArg.reg(insn, 0, ArgType.INT),
InsnArg.reg(insn, 2, ArgType.INT),
InsnArg.reg(insn, 1, ArgType.INT));
case Opcodes.RSUB_INT_LIT8:
return new ArithNode(method, ArithOp.SUB,
return new ArithNode(ArithOp.SUB,
InsnArg.reg(insn, 0, ArgType.INT),
InsnArg.lit(insn, ArgType.INT),
InsnArg.reg(insn, 1, ArgType.INT));
@ -346,27 +347,27 @@ public class InsnDecoder {
case Opcodes.IF_EQ:
case Opcodes.IF_EQZ:
return new IfNode(method, insn, IfOp.EQ);
return new IfNode(insn, IfOp.EQ);
case Opcodes.IF_NE:
case Opcodes.IF_NEZ:
return new IfNode(method, insn, IfOp.NE);
return new IfNode(insn, IfOp.NE);
case Opcodes.IF_GT:
case Opcodes.IF_GTZ:
return new IfNode(method, insn, IfOp.GT);
return new IfNode(insn, IfOp.GT);
case Opcodes.IF_GE:
case Opcodes.IF_GEZ:
return new IfNode(method, insn, IfOp.GE);
return new IfNode(insn, IfOp.GE);
case Opcodes.IF_LT:
case Opcodes.IF_LTZ:
return new IfNode(method, insn, IfOp.LT);
return new IfNode(insn, IfOp.LT);
case Opcodes.IF_LE:
case Opcodes.IF_LEZ:
return new IfNode(method, insn, IfOp.LE);
return new IfNode(insn, IfOp.LE);
case Opcodes.CMP_LONG:
return cmp(insn, InsnType.CMP_L, ArgType.LONG);
@ -383,7 +384,7 @@ public class InsnDecoder {
case Opcodes.GOTO:
case Opcodes.GOTO_16:
case Opcodes.GOTO_32:
return new GotoNode(method, insn.getTarget());
return new GotoNode(insn.getTarget());
case Opcodes.THROW:
return insn(InsnType.THROW, null,
@ -394,7 +395,7 @@ public class InsnDecoder {
InsnArg.reg(insn, 0, ArgType.unknown(PrimitiveType.OBJECT)));
case Opcodes.RETURN_VOID:
return new InsnNode(method, InsnType.RETURN, 0);
return new InsnNode(InsnType.RETURN, 0);
case Opcodes.RETURN:
case Opcodes.RETURN_WIDE:
@ -404,7 +405,7 @@ public class InsnDecoder {
InsnArg.reg(insn, 0, method.getReturnType()));
case Opcodes.INSTANCE_OF: {
InsnNode node = new IndexInsnNode(method, InsnType.INSTANCE_OF, dex.getType(insn.getIndex()), 1);
InsnNode node = new IndexInsnNode(InsnType.INSTANCE_OF, dex.getType(insn.getIndex()), 1);
node.setResult(InsnArg.reg(insn, 0, ArgType.BOOLEAN));
node.addArg(InsnArg.reg(insn, 1, ArgType.UNKNOWN_OBJECT));
return node;
@ -412,7 +413,7 @@ public class InsnDecoder {
case Opcodes.CHECK_CAST: {
ArgType castType = dex.getType(insn.getIndex());
InsnNode node = new IndexInsnNode(method, InsnType.CHECK_CAST, castType, 1);
InsnNode node = new IndexInsnNode(InsnType.CHECK_CAST, castType, 1);
node.setResult(InsnArg.reg(insn, 0, castType));
node.addArg(InsnArg.reg(insn, 0, ArgType.UNKNOWN_OBJECT));
return node;
@ -426,7 +427,7 @@ public class InsnDecoder {
case Opcodes.IGET_WIDE:
case Opcodes.IGET_OBJECT: {
FieldInfo field = FieldInfo.fromDex(dex, insn.getIndex());
InsnNode node = new IndexInsnNode(method, InsnType.IGET, field, 1);
InsnNode node = new IndexInsnNode(InsnType.IGET, field, 1);
node.setResult(InsnArg.reg(insn, 0, field.getType()));
node.addArg(InsnArg.reg(insn, 1, field.getDeclClass().getType()));
return node;
@ -440,7 +441,7 @@ public class InsnDecoder {
case Opcodes.IPUT_WIDE:
case Opcodes.IPUT_OBJECT: {
FieldInfo field = FieldInfo.fromDex(dex, insn.getIndex());
InsnNode node = new IndexInsnNode(method, InsnType.IPUT, field, 2);
InsnNode node = new IndexInsnNode(InsnType.IPUT, field, 2);
node.addArg(InsnArg.reg(insn, 0, field.getType()));
node.addArg(InsnArg.reg(insn, 1, field.getDeclClass().getType()));
return node;
@ -454,7 +455,7 @@ public class InsnDecoder {
case Opcodes.SGET_WIDE:
case Opcodes.SGET_OBJECT: {
FieldInfo field = FieldInfo.fromDex(dex, insn.getIndex());
InsnNode node = new IndexInsnNode(method, InsnType.SGET, field, 0);
InsnNode node = new IndexInsnNode(InsnType.SGET, field, 0);
node.setResult(InsnArg.reg(insn, 0, field.getType()));
return node;
}
@ -467,13 +468,13 @@ public class InsnDecoder {
case Opcodes.SPUT_WIDE:
case Opcodes.SPUT_OBJECT: {
FieldInfo field = FieldInfo.fromDex(dex, insn.getIndex());
InsnNode node = new IndexInsnNode(method, InsnType.SPUT, field, 1);
InsnNode node = new IndexInsnNode(InsnType.SPUT, field, 1);
node.addArg(InsnArg.reg(insn, 0, field.getType()));
return node;
}
case Opcodes.ARRAY_LENGTH: {
InsnNode node = new InsnNode(method, InsnType.ARRAY_LENGTH, 1);
InsnNode node = new InsnNode(InsnType.ARRAY_LENGTH, 1);
node.setResult(InsnArg.reg(insn, 0, ArgType.INT));
node.addArg(InsnArg.reg(insn, 1, ArgType.unknown(PrimitiveType.ARRAY)));
return node;
@ -592,13 +593,12 @@ public class InsnDecoder {
targets[i] = targets[i] - payloadOffset + offset;
}
int nextOffset = getNextInsnOffset(insnArr, offset);
return new SwitchNode(method, InsnArg.reg(insn, 0, ArgType.NARROW),
keys, targets, nextOffset);
return new SwitchNode(InsnArg.reg(insn, 0, ArgType.NARROW), keys, targets, nextOffset);
}
private InsnNode fillArray(DecodedInstruction insn) {
DecodedInstruction payload = insnArr[insn.getTarget()];
return new FillArrayOp(method, insn.getA(), (FillArrayDataPayloadDecodedInstruction) payload);
return new FillArrayOp(insn.getA(), (FillArrayDataPayloadDecodedInstruction) payload);
}
private InsnNode filledNewArray(DecodedInstruction insn, int offset, boolean isRange) {
@ -622,7 +622,7 @@ public class InsnDecoder {
}
private InsnNode cmp(DecodedInstruction insn, InsnType itype, ArgType argType) {
InsnNode inode = new InsnNode(method, itype, 2);
InsnNode inode = new InsnNode(itype, 2);
inode.setResult(InsnArg.reg(insn, 0, ArgType.INT));
inode.addArg(InsnArg.reg(insn, 1, argType));
inode.addArg(InsnArg.reg(insn, 2, argType));
@ -630,7 +630,7 @@ public class InsnDecoder {
}
private InsnNode cast(DecodedInstruction insn, ArgType from, ArgType to) {
InsnNode inode = new IndexInsnNode(method, InsnType.CAST, to, 1);
InsnNode inode = new IndexInsnNode(InsnType.CAST, to, 1);
inode.setResult(InsnArg.reg(insn, 0, to));
inode.addArg(InsnArg.reg(insn, 1, from));
return inode;
@ -638,11 +638,12 @@ public class InsnDecoder {
private InsnNode invoke(DecodedInstruction insn, int offset, InvokeType type, boolean isRange) {
int resReg = getMoveResultRegister(insnArr, offset);
return new InvokeNode(method, insn, type, isRange, resReg);
MethodInfo mth = MethodInfo.fromDex(dex, insn.getIndex());
return new InvokeNode(mth, insn, type, isRange, resReg);
}
private InsnNode arrayGet(DecodedInstruction insn, ArgType argType) {
InsnNode inode = new InsnNode(method, InsnType.AGET, 2);
InsnNode inode = new InsnNode(InsnType.AGET, 2);
inode.setResult(InsnArg.reg(insn, 0, argType));
inode.addArg(InsnArg.reg(insn, 1, ArgType.unknown(PrimitiveType.ARRAY)));
inode.addArg(InsnArg.reg(insn, 2, ArgType.INT));
@ -650,7 +651,7 @@ public class InsnDecoder {
}
private InsnNode arrayPut(DecodedInstruction insn, ArgType argType) {
InsnNode inode = new InsnNode(method, InsnType.APUT, 3);
InsnNode inode = new InsnNode(InsnType.APUT, 3);
inode.addArg(InsnArg.reg(insn, 1, ArgType.unknown(PrimitiveType.ARRAY)));
inode.addArg(InsnArg.reg(insn, 2, ArgType.INT));
inode.addArg(InsnArg.reg(insn, 0, argType));
@ -658,22 +659,22 @@ public class InsnDecoder {
}
private InsnNode arith(DecodedInstruction insn, ArithOp op, ArgType type) {
return new ArithNode(method, insn, op, type, false);
return new ArithNode(insn, op, type, false);
}
private InsnNode arith_lit(DecodedInstruction insn, ArithOp op, ArgType type) {
return new ArithNode(method, insn, op, type, true);
return new ArithNode(insn, op, type, true);
}
private InsnNode neg(DecodedInstruction insn, ArgType type) {
InsnNode inode = new InsnNode(method, InsnType.NEG, 1);
InsnNode inode = new InsnNode(InsnType.NEG, 1);
inode.setResult(InsnArg.reg(insn, 0, type));
inode.addArg(InsnArg.reg(insn, 1, type));
return inode;
}
private InsnNode insn(InsnType type, RegisterArg res, InsnArg... args) {
InsnNode inode = new InsnNode(method, type, args == null ? 0 : args.length);
InsnNode inode = new InsnNode(type, args == null ? 0 : args.length);
inode.setResult(res);
if (args != null)
for (InsnArg arg : args)

View File

@ -4,7 +4,6 @@ import jadx.dex.info.MethodInfo;
import jadx.dex.instructions.args.ArgType;
import jadx.dex.instructions.args.InsnArg;
import jadx.dex.nodes.InsnNode;
import jadx.dex.nodes.MethodNode;
import jadx.utils.InsnUtils;
import jadx.utils.Utils;
@ -15,10 +14,9 @@ public class InvokeNode extends InsnNode {
private final InvokeType type;
private final MethodInfo mth;
public InvokeNode(MethodNode method, DecodedInstruction insn, InvokeType type, boolean isRange,
int resReg) {
super(method, InsnType.INVOKE);
this.mth = MethodInfo.fromDex(method.dex(), insn.getIndex());
public InvokeNode(MethodInfo mth, DecodedInstruction insn, InvokeType type, boolean isRange, int resReg) {
super(InsnType.INVOKE, mth.getArgsCount() + (type != InvokeType.STATIC ? 1 : 0));
this.mth = mth;
this.type = type;
if (resReg >= 0)

View File

@ -2,7 +2,6 @@ package jadx.dex.instructions;
import jadx.dex.instructions.args.InsnArg;
import jadx.dex.nodes.InsnNode;
import jadx.dex.nodes.MethodNode;
import jadx.utils.InsnUtils;
import java.util.Arrays;
@ -13,8 +12,8 @@ public class SwitchNode extends InsnNode {
private final int[] targets;
private final int def; // next instruction
public SwitchNode(MethodNode mth, InsnArg arg, int[] keys, int[] targets, int def) {
super(mth, InsnType.SWITCH, 1);
public SwitchNode(InsnArg arg, int[] keys, int[] targets, int def) {
super(InsnType.SWITCH, 1);
this.keys = keys;
this.targets = targets;
this.def = def;

View File

@ -22,7 +22,7 @@ public class ConstructorInsn extends InsnNode {
private final CallType callType;
public ConstructorInsn(MethodNode mth, InvokeNode invoke) {
super(mth, InsnType.CONSTRUCTOR, invoke.getArgsCount() - 1);
super(InsnType.CONSTRUCTOR, invoke.getArgsCount() - 1);
this.callMth = invoke.getCallMth();
ClassInfo classType = callMth.getDeclClass();

View File

@ -5,14 +5,13 @@ import jadx.dex.instructions.IfOp;
import jadx.dex.instructions.InsnType;
import jadx.dex.instructions.args.InsnArg;
import jadx.dex.nodes.InsnNode;
import jadx.dex.nodes.MethodNode;
import jadx.utils.InsnUtils;
import jadx.utils.Utils;
public class TernaryInsn extends IfNode {
public TernaryInsn(MethodNode mth, IfOp op, InsnNode then, InsnNode els) {
super(mth, op, then.getOffset(),
public TernaryInsn(IfOp op, InsnNode then, InsnNode els) {
super(op, then.getOffset(),
InsnArg.wrap(then),
els == null ? null : InsnArg.wrap(els));
}

View File

@ -24,11 +24,11 @@ public class InsnNode extends AttrNode {
protected int offset;
protected int insnHashCode = super.hashCode();
protected InsnNode(MethodNode mth, InsnType type) {
this(mth, type, 3);
protected InsnNode(InsnType type) {
this(type, 1);
}
public InsnNode(MethodNode mth, InsnType type, int argsCount) {
public InsnNode(InsnType type, int argsCount) {
this.insnType = type;
this.offset = -1;
@ -85,11 +85,15 @@ public class InsnNode extends AttrNode {
public boolean replaceArg(InsnArg from, InsnArg to) {
int count = getArgsCount();
for (int i = 0; i < count; i++) {
if (arguments.get(i) == from) {
InsnArg arg = arguments.get(i);
if (arg == from) {
// TODO correct remove from use list
// from.getTypedVar().getUseList().remove(from);
setArg(i, to);
return true;
} else if (arg.isInsnWrap()) {
if (((InsnWrapArg) arg).getWrapInsn().replaceArg(from, to))
return true;
}
}
return false;

View File

@ -358,7 +358,7 @@ public class BlockMakerVisitor extends AbstractVisitor {
// make copy of return block and connect to predecessor
BlockNode newRetBlock = startNewBlock(mth, origRetBlock.getStartOffset());
InsnNode ret = new InsnNode(mth, InsnType.RETURN, 1);
InsnNode ret = new InsnNode(InsnType.RETURN, 1);
if (retArg != null)
ret.addArg(InsnArg.reg(retArg.getRegNum(), retArg.getType()));
ret.getAttributes().addAll(origReturnInsn.getAttributes());

View File

@ -57,8 +57,12 @@ public class CodeShrinker extends AbstractVisitor {
LOG.debug("parent insn null in " + useInsnArg + " from " + insn + " mth: " + mth);
} else if (useInsn != insn) {
boolean wrap = false;
// wrap insn from current block
// TODO don't reorder methods invocations
// if (insn.getResult().getTypedVar().getName() != null) {
// wrap = false;
// } else
if (BlockUtils.blockContains(block, useInsn)) {
// wrap insn from current block
wrap = true;
} else {
// TODO implement rules for shrink insn from different blocks
@ -129,14 +133,14 @@ public class CodeShrinker extends AbstractVisitor {
// use 'a++' instead 'a = a + 1' (similar for minus)
boolean inc = ((op == ArithOp.ADD && lit == 1)
|| (op == ArithOp.SUB && lit == -1));
return new ArithNode(mth, inc ? ArithOp.INC : ArithOp.DEC, null, v0);
return new ArithNode(inc ? ArithOp.INC : ArithOp.DEC, null, v0);
}
}
}
// fix 'c + (-1)' => 'c - (1)'
if (invert) {
return new ArithNode(mth, ArithOp.SUB,
return new ArithNode(ArithOp.SUB,
arith.getResult(), insn.getArg(0),
InsnArg.lit(-lit, litArg.getType()));
}

View File

@ -82,7 +82,8 @@ public class ModVisitor extends AbstractVisitor {
replaceInsn(block, i, co);
}
} else if (co.isThis() && co.getArgsCount() == 0) {
MethodNode defCo = mth.getParentClass().searchMethodById(co.getCallMth().getShortId());
MethodNode defCo = mth.getParentClass()
.searchMethodByName(co.getCallMth().getShortId());
if (defCo == null || defCo.isNoCode()) {
// default constructor not implemented
remover.add(insn);
@ -101,7 +102,7 @@ public class ModVisitor extends AbstractVisitor {
IndexInsnNode node = (IndexInsnNode) insn;
FieldNode f = mth.getParentClass().getConstFields().get(node.getIndex());
if (f != null) {
InsnNode inode = new IndexInsnNode(mth, InsnType.SGET, f, 0);
InsnNode inode = new IndexInsnNode(InsnType.SGET, f, 0);
inode.setResult(insn.getResult());
replaceInsn(block, i, inode);
}