// move-result will be process in invoke and filled-new-array instructions
case Opcodes.MOVE_RESULT:
case Opcodes.MOVE_RESULT_WIDE:
case Opcodes.MOVE_RESULT_OBJECT:
return new InsnNode(InsnType.NOP, 0);
case Opcodes.CONST:
case Opcodes.CONST_4:
case Opcodes.CONST_16:
case Opcodes.CONST_HIGH16:
return insn(InsnType.CONST, InsnArg.reg(insn, 0, ArgType.NARROW),
InsnArg.lit(insn, ArgType.NARROW));
case Opcodes.CONST_WIDE:
case Opcodes.CONST_WIDE_16:
case Opcodes.CONST_WIDE_32:
case Opcodes.CONST_WIDE_HIGH16:
return insn(InsnType.CONST, InsnArg.reg(insn, 0, ArgType.WIDE),
InsnArg.lit(insn, ArgType.WIDE));
case Opcodes.CONST_STRING:
case Opcodes.CONST_STRING_JUMBO: {
InsnNode node = new ConstStringNode(dex.getString(insn.getIndex()));
node.setResult(InsnArg.reg(insn, 0, ArgType.STRING));
return node;
}
case Opcodes.CONST_CLASS: {
InsnNode node = new ConstClassNode(dex.getType(insn.getIndex()));
node.setResult(InsnArg.reg(insn, 0, ArgType.CLASS));
return node;
}
case Opcodes.MOVE:
case Opcodes.MOVE_16:
case Opcodes.MOVE_FROM16:
return insn(InsnType.MOVE,
InsnArg.reg(insn, 0, ArgType.NARROW),
InsnArg.reg(insn, 1, ArgType.NARROW));
case Opcodes.MOVE_WIDE:
case Opcodes.MOVE_WIDE_16:
case Opcodes.MOVE_WIDE_FROM16:
return insn(InsnType.MOVE,
InsnArg.reg(insn, 0, ArgType.WIDE),
InsnArg.reg(insn, 1, ArgType.WIDE));
case Opcodes.MOVE_OBJECT:
case Opcodes.MOVE_OBJECT_16:
case Opcodes.MOVE_OBJECT_FROM16:
return insn(InsnType.MOVE,
InsnArg.reg(insn, 0, ArgType.UNKNOWN_OBJECT),
InsnArg.reg(insn, 1, ArgType.UNKNOWN_OBJECT));
case Opcodes.ADD_INT:
case Opcodes.ADD_INT_2ADDR:
return arith(insn, ArithOp.ADD, ArgType.INT);
case Opcodes.ADD_DOUBLE:
case Opcodes.ADD_DOUBLE_2ADDR:
return arith(insn, ArithOp.ADD, ArgType.DOUBLE);
case Opcodes.ADD_FLOAT:
case Opcodes.ADD_FLOAT_2ADDR:
return arith(insn, ArithOp.ADD, ArgType.FLOAT);
case Opcodes.ADD_LONG:
case Opcodes.ADD_LONG_2ADDR:
return arith(insn, ArithOp.ADD, ArgType.LONG);
case Opcodes.ADD_INT_LIT8:
case Opcodes.ADD_INT_LIT16:
return arithLit(insn, ArithOp.ADD, ArgType.INT);
case Opcodes.SUB_INT:
case Opcodes.SUB_INT_2ADDR:
return arith(insn, ArithOp.SUB, ArgType.INT);
case Opcodes.RSUB_INT_LIT8:
case Opcodes.RSUB_INT: // LIT16
return new ArithNode(ArithOp.SUB,
InsnArg.reg(insn, 0, ArgType.INT),
InsnArg.lit(insn, ArgType.INT),
InsnArg.reg(insn, 1, ArgType.INT));
case Opcodes.SUB_LONG:
case Opcodes.SUB_LONG_2ADDR:
return arith(insn, ArithOp.SUB, ArgType.LONG);
case Opcodes.SUB_FLOAT:
case Opcodes.SUB_FLOAT_2ADDR:
return arith(insn, ArithOp.SUB, ArgType.FLOAT);
case Opcodes.SUB_DOUBLE:
case Opcodes.SUB_DOUBLE_2ADDR:
return arith(insn, ArithOp.SUB, ArgType.DOUBLE);
case Opcodes.MUL_INT:
case Opcodes.MUL_INT_2ADDR:
return arith(insn, ArithOp.MUL, ArgType.INT);
case Opcodes.MUL_DOUBLE:
case Opcodes.MUL_DOUBLE_2ADDR:
return arith(insn, ArithOp.MUL, ArgType.DOUBLE);
case Opcodes.MUL_FLOAT:
case Opcodes.MUL_FLOAT_2ADDR:
return arith(insn, ArithOp.MUL, ArgType.FLOAT);
case Opcodes.MUL_LONG:
case Opcodes.MUL_LONG_2ADDR:
return arith(insn, ArithOp.MUL, ArgType.LONG);
case Opcodes.MUL_INT_LIT8:
case Opcodes.MUL_INT_LIT16:
return arithLit(insn, ArithOp.MUL, ArgType.INT);
case Opcodes.DIV_INT:
case Opcodes.DIV_INT_2ADDR:
return arith(insn, ArithOp.DIV, ArgType.INT);
case Opcodes.REM_INT:
case Opcodes.REM_INT_2ADDR:
return arith(insn, ArithOp.REM, ArgType.INT);
case Opcodes.REM_LONG:
case Opcodes.REM_LONG_2ADDR:
return arith(insn, ArithOp.REM, ArgType.LONG);
case Opcodes.REM_FLOAT:
case Opcodes.REM_FLOAT_2ADDR:
return arith(insn, ArithOp.REM, ArgType.FLOAT);
case Opcodes.REM_DOUBLE:
case Opcodes.REM_DOUBLE_2ADDR:
return arith(insn, ArithOp.REM, ArgType.DOUBLE);
case Opcodes.DIV_DOUBLE:
case Opcodes.DIV_DOUBLE_2ADDR:
return arith(insn, ArithOp.DIV, ArgType.DOUBLE);
case Opcodes.DIV_FLOAT:
case Opcodes.DIV_FLOAT_2ADDR:
return arith(insn, ArithOp.DIV, ArgType.FLOAT);
case Opcodes.DIV_LONG:
case Opcodes.DIV_LONG_2ADDR:
return arith(insn, ArithOp.DIV, ArgType.LONG);
case Opcodes.DIV_INT_LIT8:
case Opcodes.DIV_INT_LIT16:
return arithLit(insn, ArithOp.DIV, ArgType.INT);
case Opcodes.REM_INT_LIT8:
case Opcodes.REM_INT_LIT16:
return arithLit(insn, ArithOp.REM, ArgType.INT);
case Opcodes.AND_INT:
case Opcodes.AND_INT_2ADDR:
return arith(insn, ArithOp.AND, ArgType.INT);
case Opcodes.AND_INT_LIT8:
case Opcodes.AND_INT_LIT16:
return arithLit(insn, ArithOp.AND, ArgType.INT);
case Opcodes.XOR_INT_LIT8:
case Opcodes.XOR_INT_LIT16:
return arithLit(insn, ArithOp.XOR, ArgType.INT);
case Opcodes.AND_LONG:
case Opcodes.AND_LONG_2ADDR:
return arith(insn, ArithOp.AND, ArgType.LONG);
case Opcodes.OR_INT:
case Opcodes.OR_INT_2ADDR:
return arith(insn, ArithOp.OR, ArgType.INT);
case Opcodes.OR_INT_LIT8:
case Opcodes.OR_INT_LIT16:
return arithLit(insn, ArithOp.OR, ArgType.INT);
case Opcodes.XOR_INT:
case Opcodes.XOR_INT_2ADDR:
return arith(insn, ArithOp.XOR, ArgType.INT);
case Opcodes.OR_LONG:
case Opcodes.OR_LONG_2ADDR:
return arith(insn, ArithOp.OR, ArgType.LONG);
case Opcodes.XOR_LONG:
case Opcodes.XOR_LONG_2ADDR:
return arith(insn, ArithOp.XOR, ArgType.LONG);
case Opcodes.USHR_INT:
case Opcodes.USHR_INT_2ADDR:
return arith(insn, ArithOp.USHR, ArgType.INT);
case Opcodes.USHR_LONG:
case Opcodes.USHR_LONG_2ADDR:
return arith(insn, ArithOp.USHR, ArgType.LONG);
case Opcodes.SHL_INT:
case Opcodes.SHL_INT_2ADDR:
return arith(insn, ArithOp.SHL, ArgType.INT);
case Opcodes.SHL_LONG:
case Opcodes.SHL_LONG_2ADDR:
return arith(insn, ArithOp.SHL, ArgType.LONG);
case Opcodes.SHR_INT:
case Opcodes.SHR_INT_2ADDR:
return arith(insn, ArithOp.SHR, ArgType.INT);
case Opcodes.SHR_LONG:
case Opcodes.SHR_LONG_2ADDR:
return arith(insn, ArithOp.SHR, ArgType.LONG);
case Opcodes.SHL_INT_LIT8:
return arithLit(insn, ArithOp.SHL, ArgType.INT);
case Opcodes.SHR_INT_LIT8:
return arithLit(insn, ArithOp.SHR, ArgType.INT);
case Opcodes.USHR_INT_LIT8:
return arithLit(insn, ArithOp.USHR, ArgType.INT);
case Opcodes.NEG_INT:
return neg(insn, ArgType.INT);
case Opcodes.NEG_LONG:
return neg(insn, ArgType.LONG);
case Opcodes.NEG_FLOAT:
return neg(insn, ArgType.FLOAT);
case Opcodes.NEG_DOUBLE:
return neg(insn, ArgType.DOUBLE);
case Opcodes.INT_TO_BYTE:
return cast(insn, ArgType.INT, ArgType.BYTE);
case Opcodes.INT_TO_CHAR:
return cast(insn, ArgType.INT, ArgType.CHAR);
case Opcodes.INT_TO_SHORT:
return cast(insn, ArgType.INT, ArgType.SHORT);
case Opcodes.INT_TO_FLOAT:
return cast(insn, ArgType.INT, ArgType.FLOAT);
case Opcodes.INT_TO_DOUBLE:
return cast(insn, ArgType.INT, ArgType.DOUBLE);
case Opcodes.INT_TO_LONG:
return cast(insn, ArgType.INT, ArgType.LONG);
case Opcodes.FLOAT_TO_INT:
return cast(insn, ArgType.FLOAT, ArgType.INT);
case Opcodes.FLOAT_TO_DOUBLE:
return cast(insn, ArgType.FLOAT, ArgType.DOUBLE);
case Opcodes.FLOAT_TO_LONG:
return cast(insn, ArgType.FLOAT, ArgType.LONG);
case Opcodes.DOUBLE_TO_INT:
return cast(insn, ArgType.DOUBLE, ArgType.INT);
case Opcodes.DOUBLE_TO_FLOAT:
return cast(insn, ArgType.DOUBLE, ArgType.FLOAT);
case Opcodes.DOUBLE_TO_LONG:
return cast(insn, ArgType.DOUBLE, ArgType.LONG);
case Opcodes.LONG_TO_INT:
return cast(insn, ArgType.LONG, ArgType.INT);
case Opcodes.LONG_TO_FLOAT:
return cast(insn, ArgType.LONG, ArgType.FLOAT);
case Opcodes.LONG_TO_DOUBLE:
return cast(insn, ArgType.LONG, ArgType.DOUBLE);
case Opcodes.IF_EQ:
case Opcodes.IF_EQZ:
return new IfNode(insn, IfOp.EQ);
case Opcodes.IF_NE:
case Opcodes.IF_NEZ:
return new IfNode(insn, IfOp.NE);
case Opcodes.IF_GT:
case Opcodes.IF_GTZ:
return new IfNode(insn, IfOp.GT);
case Opcodes.IF_GE:
case Opcodes.IF_GEZ:
return new IfNode(insn, IfOp.GE);
case Opcodes.IF_LT:
case Opcodes.IF_LTZ:
return new IfNode(insn, IfOp.LT);
case Opcodes.IF_LE:
case Opcodes.IF_LEZ:
return new IfNode(insn, IfOp.LE);
case Opcodes.CMP_LONG:
return cmp(insn, InsnType.CMP_L, ArgType.LONG);
case Opcodes.CMPL_FLOAT:
return cmp(insn, InsnType.CMP_L, ArgType.FLOAT);
case Opcodes.CMPL_DOUBLE:
return cmp(insn, InsnType.CMP_L, ArgType.DOUBLE);
case Opcodes.CMPG_FLOAT:
return cmp(insn, InsnType.CMP_G, ArgType.FLOAT);
case Opcodes.CMPG_DOUBLE:
return cmp(insn, InsnType.CMP_G, ArgType.DOUBLE);
case Opcodes.GOTO:
case Opcodes.GOTO_16:
case Opcodes.GOTO_32:
return new GotoNode(insn.getTarget());
case Opcodes.THROW:
return insn(InsnType.THROW, null,
InsnArg.reg(insn, 0, ArgType.unknown(PrimitiveType.OBJECT)));
case Opcodes.MOVE_EXCEPTION:
return insn(InsnType.MOVE_EXCEPTION,
InsnArg.reg(insn, 0, ArgType.unknown(PrimitiveType.OBJECT)));
case Opcodes.RETURN_VOID:
return new InsnNode(InsnType.RETURN, 0);
case Opcodes.RETURN:
case Opcodes.RETURN_WIDE:
case Opcodes.RETURN_OBJECT:
return insn(InsnType.RETURN,
null,
InsnArg.reg(insn, 0, method.getReturnType()));
case Opcodes.INSTANCE_OF: {
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;
}
case Opcodes.CHECK_CAST: {
ArgType castType = dex.getType(insn.getIndex());
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;
}
case Opcodes.IGET:
case Opcodes.IGET_BOOLEAN:
case Opcodes.IGET_BYTE:
case Opcodes.IGET_CHAR:
case Opcodes.IGET_SHORT:
case Opcodes.IGET_WIDE:
case Opcodes.IGET_OBJECT: {
FieldInfo field = FieldInfo.fromDex(dex, insn.getIndex());
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;
}
case Opcodes.IPUT:
case Opcodes.IPUT_BOOLEAN:
case Opcodes.IPUT_BYTE:
case Opcodes.IPUT_CHAR:
case Opcodes.IPUT_SHORT:
case Opcodes.IPUT_WIDE:
case Opcodes.IPUT_OBJECT: {
FieldInfo field = FieldInfo.fromDex(dex, insn.getIndex());
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;
}
case Opcodes.SGET:
case Opcodes.SGET_BOOLEAN:
case Opcodes.SGET_BYTE:
case Opcodes.SGET_CHAR:
case Opcodes.SGET_SHORT:
case Opcodes.SGET_WIDE:
case Opcodes.SGET_OBJECT: {
FieldInfo field = FieldInfo.fromDex(dex, insn.getIndex());
InsnNode node = new IndexInsnNode(InsnType.SGET, field, 0);
node.setResult(InsnArg.reg(insn, 0, field.getType()));
return node;
}
case Opcodes.SPUT:
case Opcodes.SPUT_BOOLEAN:
case Opcodes.SPUT_BYTE:
case Opcodes.SPUT_CHAR:
case Opcodes.SPUT_SHORT:
case Opcodes.SPUT_WIDE:
case Opcodes.SPUT_OBJECT: {
FieldInfo field = FieldInfo.fromDex(dex, insn.getIndex());
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(InsnType.ARRAY_LENGTH, 1);
node.setResult(InsnArg.reg(insn, 0, ArgType.INT));
node.addArg(InsnArg.reg(insn, 1, ArgType.array(ArgType.UNKNOWN)));
return node;
}
case Opcodes.AGET:
return arrayGet(insn, ArgType.NARROW);