use of jadx.api.plugins.input.insns.custom.IArrayPayload in project jadx by skylot.
the class InsnDecoder method decode.
@NotNull
protected InsnNode decode(InsnData insn) throws DecodeException {
switch(insn.getOpcode()) {
case NOP:
return new InsnNode(InsnType.NOP, 0);
// move-result will be process in invoke and filled-new-array instructions
case MOVE_RESULT:
return insn(InsnType.MOVE_RESULT, InsnArg.reg(insn, 0, ArgType.UNKNOWN));
case CONST:
LiteralArg narrowLitArg = InsnArg.lit(insn, ArgType.NARROW);
return insn(InsnType.CONST, InsnArg.reg(insn, 0, narrowLitArg.getType()), narrowLitArg);
case CONST_WIDE:
LiteralArg wideLitArg = InsnArg.lit(insn, ArgType.WIDE);
return insn(InsnType.CONST, InsnArg.reg(insn, 0, wideLitArg.getType()), wideLitArg);
case CONST_STRING:
InsnNode constStrInsn = new ConstStringNode(insn.getIndexAsString());
constStrInsn.setResult(InsnArg.reg(insn, 0, ArgType.STRING));
return constStrInsn;
case CONST_CLASS:
{
ArgType clsType = ArgType.parse(insn.getIndexAsType());
InsnNode constClsInsn = new ConstClassNode(clsType);
constClsInsn.setResult(InsnArg.reg(insn, 0, ArgType.generic(Consts.CLASS_CLASS, clsType)));
return constClsInsn;
}
case MOVE:
return insn(InsnType.MOVE, InsnArg.reg(insn, 0, ArgType.NARROW), InsnArg.reg(insn, 1, ArgType.NARROW));
case MOVE_MULTI:
int len = insn.getRegsCount();
InsnNode mmv = new InsnNode(InsnType.MOVE_MULTI, len);
for (int i = 0; i < len; i++) {
mmv.addArg(InsnArg.reg(insn, i, ArgType.UNKNOWN));
}
return mmv;
case MOVE_WIDE:
return insn(InsnType.MOVE, InsnArg.reg(insn, 0, ArgType.WIDE), InsnArg.reg(insn, 1, ArgType.WIDE));
case MOVE_OBJECT:
return insn(InsnType.MOVE, InsnArg.reg(insn, 0, ArgType.UNKNOWN_OBJECT), InsnArg.reg(insn, 1, ArgType.UNKNOWN_OBJECT));
case ADD_INT:
return arith(insn, ArithOp.ADD, ArgType.INT);
case ADD_DOUBLE:
return arith(insn, ArithOp.ADD, ArgType.DOUBLE);
case ADD_FLOAT:
return arith(insn, ArithOp.ADD, ArgType.FLOAT);
case ADD_LONG:
return arith(insn, ArithOp.ADD, ArgType.LONG);
case ADD_INT_LIT:
return arithLit(insn, ArithOp.ADD, ArgType.INT);
case SUB_INT:
return arith(insn, ArithOp.SUB, ArgType.INT);
case RSUB_INT:
return new ArithNode(ArithOp.SUB, InsnArg.reg(insn, 0, ArgType.INT), InsnArg.lit(insn, ArgType.INT), InsnArg.reg(insn, 1, ArgType.INT));
case SUB_LONG:
return arith(insn, ArithOp.SUB, ArgType.LONG);
case SUB_FLOAT:
return arith(insn, ArithOp.SUB, ArgType.FLOAT);
case SUB_DOUBLE:
return arith(insn, ArithOp.SUB, ArgType.DOUBLE);
case MUL_INT:
return arith(insn, ArithOp.MUL, ArgType.INT);
case MUL_DOUBLE:
return arith(insn, ArithOp.MUL, ArgType.DOUBLE);
case MUL_FLOAT:
return arith(insn, ArithOp.MUL, ArgType.FLOAT);
case MUL_LONG:
return arith(insn, ArithOp.MUL, ArgType.LONG);
case MUL_INT_LIT:
return arithLit(insn, ArithOp.MUL, ArgType.INT);
case DIV_INT:
return arith(insn, ArithOp.DIV, ArgType.INT);
case REM_INT:
return arith(insn, ArithOp.REM, ArgType.INT);
case REM_LONG:
return arith(insn, ArithOp.REM, ArgType.LONG);
case REM_FLOAT:
return arith(insn, ArithOp.REM, ArgType.FLOAT);
case REM_DOUBLE:
return arith(insn, ArithOp.REM, ArgType.DOUBLE);
case DIV_DOUBLE:
return arith(insn, ArithOp.DIV, ArgType.DOUBLE);
case DIV_FLOAT:
return arith(insn, ArithOp.DIV, ArgType.FLOAT);
case DIV_LONG:
return arith(insn, ArithOp.DIV, ArgType.LONG);
case DIV_INT_LIT:
return arithLit(insn, ArithOp.DIV, ArgType.INT);
case REM_INT_LIT:
return arithLit(insn, ArithOp.REM, ArgType.INT);
case AND_INT:
return arith(insn, ArithOp.AND, ArgType.INT);
case AND_INT_LIT:
return arithLit(insn, ArithOp.AND, ArgType.INT);
case XOR_INT_LIT:
return arithLit(insn, ArithOp.XOR, ArgType.INT);
case AND_LONG:
return arith(insn, ArithOp.AND, ArgType.LONG);
case OR_INT:
return arith(insn, ArithOp.OR, ArgType.INT);
case OR_INT_LIT:
return arithLit(insn, ArithOp.OR, ArgType.INT);
case XOR_INT:
return arith(insn, ArithOp.XOR, ArgType.INT);
case OR_LONG:
return arith(insn, ArithOp.OR, ArgType.LONG);
case XOR_LONG:
return arith(insn, ArithOp.XOR, ArgType.LONG);
case USHR_INT:
return arith(insn, ArithOp.USHR, ArgType.INT);
case USHR_LONG:
return arith(insn, ArithOp.USHR, ArgType.LONG);
case SHL_INT:
return arith(insn, ArithOp.SHL, ArgType.INT);
case SHL_LONG:
return arith(insn, ArithOp.SHL, ArgType.LONG);
case SHR_INT:
return arith(insn, ArithOp.SHR, ArgType.INT);
case SHR_LONG:
return arith(insn, ArithOp.SHR, ArgType.LONG);
case SHL_INT_LIT:
return arithLit(insn, ArithOp.SHL, ArgType.INT);
case SHR_INT_LIT:
return arithLit(insn, ArithOp.SHR, ArgType.INT);
case USHR_INT_LIT:
return arithLit(insn, ArithOp.USHR, ArgType.INT);
case NEG_INT:
return neg(insn, ArgType.INT);
case NEG_LONG:
return neg(insn, ArgType.LONG);
case NEG_FLOAT:
return neg(insn, ArgType.FLOAT);
case NEG_DOUBLE:
return neg(insn, ArgType.DOUBLE);
case NOT_INT:
return not(insn, ArgType.INT);
case NOT_LONG:
return not(insn, ArgType.LONG);
case INT_TO_BYTE:
return cast(insn, ArgType.INT, ArgType.BYTE);
case INT_TO_CHAR:
return cast(insn, ArgType.INT, ArgType.CHAR);
case INT_TO_SHORT:
return cast(insn, ArgType.INT, ArgType.SHORT);
case INT_TO_FLOAT:
return cast(insn, ArgType.INT, ArgType.FLOAT);
case INT_TO_DOUBLE:
return cast(insn, ArgType.INT, ArgType.DOUBLE);
case INT_TO_LONG:
return cast(insn, ArgType.INT, ArgType.LONG);
case FLOAT_TO_INT:
return cast(insn, ArgType.FLOAT, ArgType.INT);
case FLOAT_TO_DOUBLE:
return cast(insn, ArgType.FLOAT, ArgType.DOUBLE);
case FLOAT_TO_LONG:
return cast(insn, ArgType.FLOAT, ArgType.LONG);
case DOUBLE_TO_INT:
return cast(insn, ArgType.DOUBLE, ArgType.INT);
case DOUBLE_TO_FLOAT:
return cast(insn, ArgType.DOUBLE, ArgType.FLOAT);
case DOUBLE_TO_LONG:
return cast(insn, ArgType.DOUBLE, ArgType.LONG);
case LONG_TO_INT:
return cast(insn, ArgType.LONG, ArgType.INT);
case LONG_TO_FLOAT:
return cast(insn, ArgType.LONG, ArgType.FLOAT);
case LONG_TO_DOUBLE:
return cast(insn, ArgType.LONG, ArgType.DOUBLE);
case IF_EQ:
case IF_EQZ:
return new IfNode(insn, IfOp.EQ);
case IF_NE:
case IF_NEZ:
return new IfNode(insn, IfOp.NE);
case IF_GT:
case IF_GTZ:
return new IfNode(insn, IfOp.GT);
case IF_GE:
case IF_GEZ:
return new IfNode(insn, IfOp.GE);
case IF_LT:
case IF_LTZ:
return new IfNode(insn, IfOp.LT);
case IF_LE:
case IF_LEZ:
return new IfNode(insn, IfOp.LE);
case CMP_LONG:
return cmp(insn, InsnType.CMP_L, ArgType.LONG);
case CMPL_FLOAT:
return cmp(insn, InsnType.CMP_L, ArgType.FLOAT);
case CMPL_DOUBLE:
return cmp(insn, InsnType.CMP_L, ArgType.DOUBLE);
case CMPG_FLOAT:
return cmp(insn, InsnType.CMP_G, ArgType.FLOAT);
case CMPG_DOUBLE:
return cmp(insn, InsnType.CMP_G, ArgType.DOUBLE);
case GOTO:
return new GotoNode(insn.getTarget());
case THROW:
return insn(InsnType.THROW, null, InsnArg.reg(insn, 0, ArgType.THROWABLE));
case MOVE_EXCEPTION:
return insn(InsnType.MOVE_EXCEPTION, InsnArg.reg(insn, 0, ArgType.UNKNOWN_OBJECT_NO_ARRAY));
case RETURN_VOID:
return new InsnNode(InsnType.RETURN, 0);
case RETURN:
return insn(InsnType.RETURN, null, InsnArg.reg(insn, 0, method.getReturnType()));
case INSTANCE_OF:
InsnNode instInsn = new IndexInsnNode(InsnType.INSTANCE_OF, ArgType.parse(insn.getIndexAsType()), 1);
instInsn.setResult(InsnArg.reg(insn, 0, ArgType.BOOLEAN));
instInsn.addArg(InsnArg.reg(insn, 1, ArgType.UNKNOWN_OBJECT));
return instInsn;
case CHECK_CAST:
ArgType castType = ArgType.parse(insn.getIndexAsType());
InsnNode checkCastInsn = new IndexInsnNode(InsnType.CHECK_CAST, castType, 1);
checkCastInsn.setResult(InsnArg.reg(insn, 0, castType));
checkCastInsn.addArg(InsnArg.reg(insn, insn.getRegsCount() == 2 ? 1 : 0, ArgType.UNKNOWN_OBJECT));
return checkCastInsn;
case IGET:
FieldInfo igetFld = FieldInfo.fromRef(root, insn.getIndexAsField());
InsnNode igetInsn = new IndexInsnNode(InsnType.IGET, igetFld, 1);
igetInsn.setResult(InsnArg.reg(insn, 0, tryResolveFieldType(igetFld)));
igetInsn.addArg(InsnArg.reg(insn, 1, igetFld.getDeclClass().getType()));
return igetInsn;
case IPUT:
FieldInfo iputFld = FieldInfo.fromRef(root, insn.getIndexAsField());
InsnNode iputInsn = new IndexInsnNode(InsnType.IPUT, iputFld, 2);
iputInsn.addArg(InsnArg.reg(insn, 0, tryResolveFieldType(iputFld)));
iputInsn.addArg(InsnArg.reg(insn, 1, iputFld.getDeclClass().getType()));
return iputInsn;
case SGET:
FieldInfo sgetFld = FieldInfo.fromRef(root, insn.getIndexAsField());
InsnNode sgetInsn = new IndexInsnNode(InsnType.SGET, sgetFld, 0);
sgetInsn.setResult(InsnArg.reg(insn, 0, tryResolveFieldType(sgetFld)));
return sgetInsn;
case SPUT:
FieldInfo sputFld = FieldInfo.fromRef(root, insn.getIndexAsField());
InsnNode sputInsn = new IndexInsnNode(InsnType.SPUT, sputFld, 1);
sputInsn.addArg(InsnArg.reg(insn, 0, tryResolveFieldType(sputFld)));
return sputInsn;
case ARRAY_LENGTH:
InsnNode arrLenInsn = new InsnNode(InsnType.ARRAY_LENGTH, 1);
arrLenInsn.setResult(InsnArg.reg(insn, 0, ArgType.INT));
arrLenInsn.addArg(InsnArg.reg(insn, 1, ArgType.array(ArgType.UNKNOWN)));
return arrLenInsn;
case AGET:
return arrayGet(insn, ArgType.INT_FLOAT);
case AGET_BOOLEAN:
return arrayGet(insn, ArgType.BOOLEAN);
case AGET_BYTE:
return arrayGet(insn, ArgType.BYTE);
case AGET_BYTE_BOOLEAN:
return arrayGet(insn, ArgType.BYTE_BOOLEAN);
case AGET_CHAR:
return arrayGet(insn, ArgType.CHAR);
case AGET_SHORT:
return arrayGet(insn, ArgType.SHORT);
case AGET_WIDE:
return arrayGet(insn, ArgType.WIDE);
case AGET_OBJECT:
return arrayGet(insn, ArgType.UNKNOWN_OBJECT);
case APUT:
return arrayPut(insn, ArgType.INT_FLOAT);
case APUT_BOOLEAN:
return arrayPut(insn, ArgType.BOOLEAN);
case APUT_BYTE:
return arrayPut(insn, ArgType.BYTE);
case APUT_BYTE_BOOLEAN:
return arrayPut(insn, ArgType.BYTE_BOOLEAN);
case APUT_CHAR:
return arrayPut(insn, ArgType.CHAR);
case APUT_SHORT:
return arrayPut(insn, ArgType.SHORT);
case APUT_WIDE:
return arrayPut(insn, ArgType.WIDE);
case APUT_OBJECT:
return arrayPut(insn, ArgType.UNKNOWN_OBJECT);
case INVOKE_STATIC:
return invoke(insn, InvokeType.STATIC, false);
case INVOKE_STATIC_RANGE:
return invoke(insn, InvokeType.STATIC, true);
case INVOKE_DIRECT:
return invoke(insn, InvokeType.DIRECT, false);
case INVOKE_INTERFACE:
return invoke(insn, InvokeType.INTERFACE, false);
case INVOKE_SUPER:
return invoke(insn, InvokeType.SUPER, false);
case INVOKE_VIRTUAL:
return invoke(insn, InvokeType.VIRTUAL, false);
case INVOKE_CUSTOM:
return invokeCustom(insn, false);
case INVOKE_SPECIAL:
return invokeSpecial(insn);
case INVOKE_DIRECT_RANGE:
return invoke(insn, InvokeType.DIRECT, true);
case INVOKE_INTERFACE_RANGE:
return invoke(insn, InvokeType.INTERFACE, true);
case INVOKE_SUPER_RANGE:
return invoke(insn, InvokeType.SUPER, true);
case INVOKE_VIRTUAL_RANGE:
return invoke(insn, InvokeType.VIRTUAL, true);
case INVOKE_CUSTOM_RANGE:
return invokeCustom(insn, true);
case NEW_INSTANCE:
ArgType clsType = ArgType.parse(insn.getIndexAsType());
IndexInsnNode newInstInsn = new IndexInsnNode(InsnType.NEW_INSTANCE, clsType, 0);
newInstInsn.setResult(InsnArg.reg(insn, 0, clsType));
return newInstInsn;
case NEW_ARRAY:
return makeNewArray(insn);
case FILL_ARRAY_DATA:
return new FillArrayInsn(InsnArg.reg(insn, 0, ArgType.UNKNOWN_ARRAY), insn.getTarget());
case FILL_ARRAY_DATA_PAYLOAD:
return new FillArrayData(((IArrayPayload) Objects.requireNonNull(insn.getPayload())));
case FILLED_NEW_ARRAY:
return filledNewArray(insn, false);
case FILLED_NEW_ARRAY_RANGE:
return filledNewArray(insn, true);
case PACKED_SWITCH:
return makeSwitch(insn, true);
case SPARSE_SWITCH:
return makeSwitch(insn, false);
case PACKED_SWITCH_PAYLOAD:
case SPARSE_SWITCH_PAYLOAD:
return new SwitchData(((ISwitchPayload) insn.getPayload()));
case MONITOR_ENTER:
return insn(InsnType.MONITOR_ENTER, null, InsnArg.reg(insn, 0, ArgType.UNKNOWN_OBJECT));
case MONITOR_EXIT:
return insn(InsnType.MONITOR_EXIT, null, InsnArg.reg(insn, 0, ArgType.UNKNOWN_OBJECT));
default:
throw new DecodeException("Unknown instruction: '" + insn + '\'');
}
}
Aggregations