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(); return code.toString();
} }
@Override
public String toString() {
return "AccessInfo: " + type + " " + accFlags + " (" + makeString() + ")";
}
} }

View File

@ -68,6 +68,10 @@ public final class MethodInfo {
return args; return args;
} }
public int getArgsCount() {
return args.size();
}
public boolean isConstructor() { public boolean isConstructor() {
return name.equals("<init>"); 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.InsnArg;
import jadx.dex.instructions.args.RegisterArg; import jadx.dex.instructions.args.RegisterArg;
import jadx.dex.nodes.InsnNode; import jadx.dex.nodes.InsnNode;
import jadx.dex.nodes.MethodNode;
import jadx.utils.InsnUtils; import jadx.utils.InsnUtils;
import com.android.dx.io.instructions.DecodedInstruction; import com.android.dx.io.instructions.DecodedInstruction;
@ -13,9 +12,8 @@ public class ArithNode extends InsnNode {
private final ArithOp op; private final ArithOp op;
public ArithNode(MethodNode mth, DecodedInstruction insn, ArithOp op, ArgType type, public ArithNode(DecodedInstruction insn, ArithOp op, ArgType type, boolean literal) {
boolean literal) { super(InsnType.ARITH, 2);
super(mth, InsnType.ARITH, 2);
this.op = op; this.op = op;
setResult(InsnArg.reg(insn, 0, type)); setResult(InsnArg.reg(insn, 0, type));
@ -44,16 +42,16 @@ public class ArithNode extends InsnNode {
assert getArgsCount() == 2; assert getArgsCount() == 2;
} }
public ArithNode(MethodNode mth, ArithOp op, RegisterArg res, InsnArg a, InsnArg b) { public ArithNode(ArithOp op, RegisterArg res, InsnArg a, InsnArg b) {
super(mth, InsnType.ARITH, 2); super(InsnType.ARITH, 2);
setResult(res); setResult(res);
addArg(a); addArg(a);
addArg(b); addArg(b);
this.op = op; this.op = op;
} }
public ArithNode(MethodNode mth, ArithOp op, RegisterArg res, InsnArg a) { public ArithNode(ArithOp op, RegisterArg res, InsnArg a) {
super(mth, InsnType.ARITH, 1); super(InsnType.ARITH, 1);
setResult(res); setResult(res);
addArg(a); addArg(a);
this.op = op; 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.InsnArg;
import jadx.dex.instructions.args.PrimitiveType; import jadx.dex.instructions.args.PrimitiveType;
import jadx.dex.nodes.InsnNode; import jadx.dex.nodes.InsnNode;
import jadx.dex.nodes.MethodNode;
import com.android.dx.io.instructions.FillArrayDataPayloadDecodedInstruction; import com.android.dx.io.instructions.FillArrayDataPayloadDecodedInstruction;
@ -12,8 +11,8 @@ public class FillArrayOp extends InsnNode {
private final Object data; private final Object data;
public FillArrayOp(MethodNode method, int resReg, FillArrayDataPayloadDecodedInstruction payload) { public FillArrayOp(int resReg, FillArrayDataPayloadDecodedInstruction payload) {
super(method, InsnType.FILL_ARRAY, 0); super(InsnType.FILL_ARRAY, 0);
this.data = payload.getData(); this.data = payload.getData();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -358,7 +358,7 @@ public class BlockMakerVisitor extends AbstractVisitor {
// make copy of return block and connect to predecessor // make copy of return block and connect to predecessor
BlockNode newRetBlock = startNewBlock(mth, origRetBlock.getStartOffset()); BlockNode newRetBlock = startNewBlock(mth, origRetBlock.getStartOffset());
InsnNode ret = new InsnNode(mth, InsnType.RETURN, 1); InsnNode ret = new InsnNode(InsnType.RETURN, 1);
if (retArg != null) if (retArg != null)
ret.addArg(InsnArg.reg(retArg.getRegNum(), retArg.getType())); ret.addArg(InsnArg.reg(retArg.getRegNum(), retArg.getType()));
ret.getAttributes().addAll(origReturnInsn.getAttributes()); 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); LOG.debug("parent insn null in " + useInsnArg + " from " + insn + " mth: " + mth);
} else if (useInsn != insn) { } else if (useInsn != insn) {
boolean wrap = false; 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)) { if (BlockUtils.blockContains(block, useInsn)) {
// wrap insn from current block
wrap = true; wrap = true;
} else { } else {
// TODO implement rules for shrink insn from different blocks // 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) // use 'a++' instead 'a = a + 1' (similar for minus)
boolean inc = ((op == ArithOp.ADD && lit == 1) boolean inc = ((op == ArithOp.ADD && lit == 1)
|| (op == ArithOp.SUB && 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)' // fix 'c + (-1)' => 'c - (1)'
if (invert) { if (invert) {
return new ArithNode(mth, ArithOp.SUB, return new ArithNode(ArithOp.SUB,
arith.getResult(), insn.getArg(0), arith.getResult(), insn.getArg(0),
InsnArg.lit(-lit, litArg.getType())); InsnArg.lit(-lit, litArg.getType()));
} }

View File

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