Search in sources :

Example 26 with Constant

use of com.taobao.android.dx.rop.cst.Constant in project atlas by alibaba.

the class Form22s method isCompatible.

/** {@inheritDoc} */
@Override
public boolean isCompatible(DalvInsn insn) {
    RegisterSpecList regs = insn.getRegisters();
    if (!((insn instanceof CstInsn) && (regs.size() == 2) && unsignedFitsInNibble(regs.get(0).getReg()) && unsignedFitsInNibble(regs.get(1).getReg()))) {
        return false;
    }
    CstInsn ci = (CstInsn) insn;
    Constant cst = ci.getConstant();
    if (!(cst instanceof CstLiteralBits)) {
        return false;
    }
    CstLiteralBits cb = (CstLiteralBits) cst;
    return cb.fitsInInt() && signedFitsInShort(cb.getIntBits());
}
Also used : CstInsn(com.taobao.android.dx.dex.code.CstInsn) CstLiteralBits(com.taobao.android.dx.rop.cst.CstLiteralBits) Constant(com.taobao.android.dx.rop.cst.Constant) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Example 27 with Constant

use of com.taobao.android.dx.rop.cst.Constant in project atlas by alibaba.

the class Form31c method isCompatible.

/** {@inheritDoc} */
@Override
public boolean isCompatible(DalvInsn insn) {
    if (!(insn instanceof CstInsn)) {
        return false;
    }
    RegisterSpecList regs = insn.getRegisters();
    RegisterSpec reg;
    switch(regs.size()) {
        case 1:
            {
                reg = regs.get(0);
                break;
            }
        case 2:
            {
                /*
                 * This format is allowed for ops that are effectively
                 * 2-arg but where the two args are identical.
                 */
                reg = regs.get(0);
                if (reg.getReg() != regs.get(1).getReg()) {
                    return false;
                }
                break;
            }
        default:
            {
                return false;
            }
    }
    if (!unsignedFitsInByte(reg.getReg())) {
        return false;
    }
    CstInsn ci = (CstInsn) insn;
    Constant cst = ci.getConstant();
    return (cst instanceof CstType) || (cst instanceof CstFieldRef) || (cst instanceof CstString);
}
Also used : CstInsn(com.taobao.android.dx.dex.code.CstInsn) Constant(com.taobao.android.dx.rop.cst.Constant) CstType(com.taobao.android.dx.rop.cst.CstType) CstFieldRef(com.taobao.android.dx.rop.cst.CstFieldRef) CstString(com.taobao.android.dx.rop.cst.CstString) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 28 with Constant

use of com.taobao.android.dx.rop.cst.Constant in project atlas by alibaba.

the class AnnotationParser method parseConstant.

/**
     * Helper for {@link #parseValue}, which parses a constant reference
     * and returns the referred-to constant value.
     *
     * @return {@code non-null;} the parsed value
     */
private Constant parseConstant() throws IOException {
    int constValueIndex = input.readUnsignedShort();
    Constant value = (Constant) pool.get(constValueIndex);
    if (observer != null) {
        String human = (value instanceof CstString) ? ((CstString) value).toQuoted() : value.toHuman();
        parsed(2, "constant_value: " + human);
    }
    return value;
}
Also used : Constant(com.taobao.android.dx.rop.cst.Constant) CstString(com.taobao.android.dx.rop.cst.CstString) CstString(com.taobao.android.dx.rop.cst.CstString)

Example 29 with Constant

use of com.taobao.android.dx.rop.cst.Constant in project atlas by alibaba.

the class BytecodeArray method parseInstruction.

/**
     * Parses the instruction at the indicated offset. Indicate the
     * result by calling the visitor if supplied and by returning the
     * number of bytes consumed by the instruction.
     *
     * <p>In order to simplify further processing, the opcodes passed
     * to the visitor are canonicalized, altering the opcode to a more
     * universal one and making formerly implicit arguments
     * explicit. In particular:</p>
     *
     * <ul>
     * <li>The opcodes to push literal constants of primitive types all become
     *   {@code ldc}.
     *   E.g., {@code fconst_0}, {@code sipush}, and
     *   {@code lconst_0} qualify for this treatment.</li>
     * <li>{@code aconst_null} becomes {@code ldc} of a
     *   "known null."</li>
     * <li>Shorthand local variable accessors become the corresponding
     *   longhand. E.g. {@code aload_2} becomes {@code aload}.</li>
     * <li>{@code goto_w} and {@code jsr_w} become {@code goto}
     *   and {@code jsr} (respectively).</li>
     * <li>{@code ldc_w} becomes {@code ldc}.</li>
     * <li>{@code tableswitch} becomes {@code lookupswitch}.
     * <li>Arithmetic, array, and value-returning ops are collapsed
     *   to the {@code int} variant opcode, with the {@code type}
     *   argument set to indicate the actual type. E.g.,
     *   {@code fadd} becomes {@code iadd}, but
     *   {@code type} is passed as {@code Type.FLOAT} in that
     *   case. Similarly, {@code areturn} becomes
     *   {@code ireturn}. (However, {@code return} remains
     *   unchanged.</li>
     * <li>Local variable access ops are collapsed to the {@code int}
     *   variant opcode, with the {@code type} argument set to indicate
     *   the actual type. E.g., {@code aload} becomes {@code iload},
     *   but {@code type} is passed as {@code Type.OBJECT} in
     *   that case.</li>
     * <li>Numeric conversion ops ({@code i2l}, etc.) are left alone
     *   to avoid too much confustion, but their {@code type} is
     *   the pushed type. E.g., {@code i2b} gets type
     *   {@code Type.INT}, and {@code f2d} gets type
     *   {@code Type.DOUBLE}. Other unaltered opcodes also get
     *   their pushed type. E.g., {@code arraylength} gets type
     *   {@code Type.INT}.</li>
     * </ul>
     *
     * @param offset {@code >= 0, < bytes.size();} offset to the start of the
     * instruction
     * @param visitor {@code null-ok;} visitor to call back to
     * @return the length of the instruction, in bytes
     */
public int parseInstruction(int offset, Visitor visitor) {
    if (visitor == null) {
        visitor = new BaseVisitor();
    }
    try {
        int opcode = bytes.getUnsignedByte(offset);
        int info = ByteOps.opInfo(opcode);
        int fmt = info & ByteOps.FMT_MASK;
        switch(opcode) {
            case ByteOps.NOP:
                {
                    visitor.visitNoArgs(opcode, offset, 1, Type.VOID);
                    return 1;
                }
            case ByteOps.ACONST_NULL:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstKnownNull.THE_ONE, 0);
                    return 1;
                }
            case ByteOps.ICONST_M1:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstInteger.VALUE_M1, -1);
                    return 1;
                }
            case ByteOps.ICONST_0:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstInteger.VALUE_0, 0);
                    return 1;
                }
            case ByteOps.ICONST_1:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstInteger.VALUE_1, 1);
                    return 1;
                }
            case ByteOps.ICONST_2:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstInteger.VALUE_2, 2);
                    return 1;
                }
            case ByteOps.ICONST_3:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstInteger.VALUE_3, 3);
                    return 1;
                }
            case ByteOps.ICONST_4:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstInteger.VALUE_4, 4);
                    return 1;
                }
            case ByteOps.ICONST_5:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstInteger.VALUE_5, 5);
                    return 1;
                }
            case ByteOps.LCONST_0:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstLong.VALUE_0, 0);
                    return 1;
                }
            case ByteOps.LCONST_1:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstLong.VALUE_1, 0);
                    return 1;
                }
            case ByteOps.FCONST_0:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstFloat.VALUE_0, 0);
                    return 1;
                }
            case ByteOps.FCONST_1:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstFloat.VALUE_1, 0);
                    return 1;
                }
            case ByteOps.FCONST_2:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstFloat.VALUE_2, 0);
                    return 1;
                }
            case ByteOps.DCONST_0:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstDouble.VALUE_0, 0);
                    return 1;
                }
            case ByteOps.DCONST_1:
                {
                    visitor.visitConstant(ByteOps.LDC, offset, 1, CstDouble.VALUE_1, 0);
                    return 1;
                }
            case ByteOps.BIPUSH:
                {
                    int value = bytes.getByte(offset + 1);
                    visitor.visitConstant(ByteOps.LDC, offset, 2, CstInteger.make(value), value);
                    return 2;
                }
            case ByteOps.SIPUSH:
                {
                    int value = bytes.getShort(offset + 1);
                    visitor.visitConstant(ByteOps.LDC, offset, 3, CstInteger.make(value), value);
                    return 3;
                }
            case ByteOps.LDC:
                {
                    int idx = bytes.getUnsignedByte(offset + 1);
                    Constant cst = pool.get(idx);
                    int value = (cst instanceof CstInteger) ? ((CstInteger) cst).getValue() : 0;
                    visitor.visitConstant(ByteOps.LDC, offset, 2, cst, value);
                    return 2;
                }
            case ByteOps.LDC_W:
                {
                    int idx = bytes.getUnsignedShort(offset + 1);
                    Constant cst = pool.get(idx);
                    int value = (cst instanceof CstInteger) ? ((CstInteger) cst).getValue() : 0;
                    visitor.visitConstant(ByteOps.LDC, offset, 3, cst, value);
                    return 3;
                }
            case ByteOps.LDC2_W:
                {
                    int idx = bytes.getUnsignedShort(offset + 1);
                    Constant cst = pool.get(idx);
                    visitor.visitConstant(ByteOps.LDC2_W, offset, 3, cst, 0);
                    return 3;
                }
            case ByteOps.ILOAD:
                {
                    int idx = bytes.getUnsignedByte(offset + 1);
                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx, Type.INT, 0);
                    return 2;
                }
            case ByteOps.LLOAD:
                {
                    int idx = bytes.getUnsignedByte(offset + 1);
                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx, Type.LONG, 0);
                    return 2;
                }
            case ByteOps.FLOAD:
                {
                    int idx = bytes.getUnsignedByte(offset + 1);
                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx, Type.FLOAT, 0);
                    return 2;
                }
            case ByteOps.DLOAD:
                {
                    int idx = bytes.getUnsignedByte(offset + 1);
                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx, Type.DOUBLE, 0);
                    return 2;
                }
            case ByteOps.ALOAD:
                {
                    int idx = bytes.getUnsignedByte(offset + 1);
                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx, Type.OBJECT, 0);
                    return 2;
                }
            case ByteOps.ILOAD_0:
            case ByteOps.ILOAD_1:
            case ByteOps.ILOAD_2:
            case ByteOps.ILOAD_3:
                {
                    int idx = opcode - ByteOps.ILOAD_0;
                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx, Type.INT, 0);
                    return 1;
                }
            case ByteOps.LLOAD_0:
            case ByteOps.LLOAD_1:
            case ByteOps.LLOAD_2:
            case ByteOps.LLOAD_3:
                {
                    int idx = opcode - ByteOps.LLOAD_0;
                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx, Type.LONG, 0);
                    return 1;
                }
            case ByteOps.FLOAD_0:
            case ByteOps.FLOAD_1:
            case ByteOps.FLOAD_2:
            case ByteOps.FLOAD_3:
                {
                    int idx = opcode - ByteOps.FLOAD_0;
                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx, Type.FLOAT, 0);
                    return 1;
                }
            case ByteOps.DLOAD_0:
            case ByteOps.DLOAD_1:
            case ByteOps.DLOAD_2:
            case ByteOps.DLOAD_3:
                {
                    int idx = opcode - ByteOps.DLOAD_0;
                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx, Type.DOUBLE, 0);
                    return 1;
                }
            case ByteOps.ALOAD_0:
            case ByteOps.ALOAD_1:
            case ByteOps.ALOAD_2:
            case ByteOps.ALOAD_3:
                {
                    int idx = opcode - ByteOps.ALOAD_0;
                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx, Type.OBJECT, 0);
                    return 1;
                }
            case ByteOps.IALOAD:
                {
                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.INT);
                    return 1;
                }
            case ByteOps.LALOAD:
                {
                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.LONG);
                    return 1;
                }
            case ByteOps.FALOAD:
                {
                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.FLOAT);
                    return 1;
                }
            case ByteOps.DALOAD:
                {
                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.DOUBLE);
                    return 1;
                }
            case ByteOps.AALOAD:
                {
                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.OBJECT);
                    return 1;
                }
            case ByteOps.BALOAD:
                {
                    /*
                     * Note: This is a load from either a byte[] or a
                     * boolean[].
                     */
                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.BYTE);
                    return 1;
                }
            case ByteOps.CALOAD:
                {
                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.CHAR);
                    return 1;
                }
            case ByteOps.SALOAD:
                {
                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.SHORT);
                    return 1;
                }
            case ByteOps.ISTORE:
                {
                    int idx = bytes.getUnsignedByte(offset + 1);
                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx, Type.INT, 0);
                    return 2;
                }
            case ByteOps.LSTORE:
                {
                    int idx = bytes.getUnsignedByte(offset + 1);
                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx, Type.LONG, 0);
                    return 2;
                }
            case ByteOps.FSTORE:
                {
                    int idx = bytes.getUnsignedByte(offset + 1);
                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx, Type.FLOAT, 0);
                    return 2;
                }
            case ByteOps.DSTORE:
                {
                    int idx = bytes.getUnsignedByte(offset + 1);
                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx, Type.DOUBLE, 0);
                    return 2;
                }
            case ByteOps.ASTORE:
                {
                    int idx = bytes.getUnsignedByte(offset + 1);
                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx, Type.OBJECT, 0);
                    return 2;
                }
            case ByteOps.ISTORE_0:
            case ByteOps.ISTORE_1:
            case ByteOps.ISTORE_2:
            case ByteOps.ISTORE_3:
                {
                    int idx = opcode - ByteOps.ISTORE_0;
                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx, Type.INT, 0);
                    return 1;
                }
            case ByteOps.LSTORE_0:
            case ByteOps.LSTORE_1:
            case ByteOps.LSTORE_2:
            case ByteOps.LSTORE_3:
                {
                    int idx = opcode - ByteOps.LSTORE_0;
                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx, Type.LONG, 0);
                    return 1;
                }
            case ByteOps.FSTORE_0:
            case ByteOps.FSTORE_1:
            case ByteOps.FSTORE_2:
            case ByteOps.FSTORE_3:
                {
                    int idx = opcode - ByteOps.FSTORE_0;
                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx, Type.FLOAT, 0);
                    return 1;
                }
            case ByteOps.DSTORE_0:
            case ByteOps.DSTORE_1:
            case ByteOps.DSTORE_2:
            case ByteOps.DSTORE_3:
                {
                    int idx = opcode - ByteOps.DSTORE_0;
                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx, Type.DOUBLE, 0);
                    return 1;
                }
            case ByteOps.ASTORE_0:
            case ByteOps.ASTORE_1:
            case ByteOps.ASTORE_2:
            case ByteOps.ASTORE_3:
                {
                    int idx = opcode - ByteOps.ASTORE_0;
                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx, Type.OBJECT, 0);
                    return 1;
                }
            case ByteOps.IASTORE:
                {
                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, Type.INT);
                    return 1;
                }
            case ByteOps.LASTORE:
                {
                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, Type.LONG);
                    return 1;
                }
            case ByteOps.FASTORE:
                {
                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, Type.FLOAT);
                    return 1;
                }
            case ByteOps.DASTORE:
                {
                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, Type.DOUBLE);
                    return 1;
                }
            case ByteOps.AASTORE:
                {
                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, Type.OBJECT);
                    return 1;
                }
            case ByteOps.BASTORE:
                {
                    /*
                     * Note: This is a load from either a byte[] or a
                     * boolean[].
                     */
                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, Type.BYTE);
                    return 1;
                }
            case ByteOps.CASTORE:
                {
                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, Type.CHAR);
                    return 1;
                }
            case ByteOps.SASTORE:
                {
                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, Type.SHORT);
                    return 1;
                }
            case ByteOps.POP:
            case ByteOps.POP2:
            case ByteOps.DUP:
            case ByteOps.DUP_X1:
            case ByteOps.DUP_X2:
            case ByteOps.DUP2:
            case ByteOps.DUP2_X1:
            case ByteOps.DUP2_X2:
            case ByteOps.SWAP:
                {
                    visitor.visitNoArgs(opcode, offset, 1, Type.VOID);
                    return 1;
                }
            case ByteOps.IADD:
            case ByteOps.ISUB:
            case ByteOps.IMUL:
            case ByteOps.IDIV:
            case ByteOps.IREM:
            case ByteOps.INEG:
            case ByteOps.ISHL:
            case ByteOps.ISHR:
            case ByteOps.IUSHR:
            case ByteOps.IAND:
            case ByteOps.IOR:
            case ByteOps.IXOR:
                {
                    visitor.visitNoArgs(opcode, offset, 1, Type.INT);
                    return 1;
                }
            case ByteOps.LADD:
            case ByteOps.LSUB:
            case ByteOps.LMUL:
            case ByteOps.LDIV:
            case ByteOps.LREM:
            case ByteOps.LNEG:
            case ByteOps.LSHL:
            case ByteOps.LSHR:
            case ByteOps.LUSHR:
            case ByteOps.LAND:
            case ByteOps.LOR:
            case ByteOps.LXOR:
                {
                    /*
                     * It's "opcode - 1" because, conveniently enough, all
                     * these long ops are one past the int variants.
                     */
                    visitor.visitNoArgs(opcode - 1, offset, 1, Type.LONG);
                    return 1;
                }
            case ByteOps.FADD:
            case ByteOps.FSUB:
            case ByteOps.FMUL:
            case ByteOps.FDIV:
            case ByteOps.FREM:
            case ByteOps.FNEG:
                {
                    /*
                     * It's "opcode - 2" because, conveniently enough, all
                     * these float ops are two past the int variants.
                     */
                    visitor.visitNoArgs(opcode - 2, offset, 1, Type.FLOAT);
                    return 1;
                }
            case ByteOps.DADD:
            case ByteOps.DSUB:
            case ByteOps.DMUL:
            case ByteOps.DDIV:
            case ByteOps.DREM:
            case ByteOps.DNEG:
                {
                    /*
                     * It's "opcode - 3" because, conveniently enough, all
                     * these double ops are three past the int variants.
                     */
                    visitor.visitNoArgs(opcode - 3, offset, 1, Type.DOUBLE);
                    return 1;
                }
            case ByteOps.IINC:
                {
                    int idx = bytes.getUnsignedByte(offset + 1);
                    int value = bytes.getByte(offset + 2);
                    visitor.visitLocal(opcode, offset, 3, idx, Type.INT, value);
                    return 3;
                }
            case ByteOps.I2L:
            case ByteOps.F2L:
            case ByteOps.D2L:
                {
                    visitor.visitNoArgs(opcode, offset, 1, Type.LONG);
                    return 1;
                }
            case ByteOps.I2F:
            case ByteOps.L2F:
            case ByteOps.D2F:
                {
                    visitor.visitNoArgs(opcode, offset, 1, Type.FLOAT);
                    return 1;
                }
            case ByteOps.I2D:
            case ByteOps.L2D:
            case ByteOps.F2D:
                {
                    visitor.visitNoArgs(opcode, offset, 1, Type.DOUBLE);
                    return 1;
                }
            case ByteOps.L2I:
            case ByteOps.F2I:
            case ByteOps.D2I:
            case ByteOps.I2B:
            case ByteOps.I2C:
            case ByteOps.I2S:
            case ByteOps.LCMP:
            case ByteOps.FCMPL:
            case ByteOps.FCMPG:
            case ByteOps.DCMPL:
            case ByteOps.DCMPG:
            case ByteOps.ARRAYLENGTH:
                {
                    visitor.visitNoArgs(opcode, offset, 1, Type.INT);
                    return 1;
                }
            case ByteOps.IFEQ:
            case ByteOps.IFNE:
            case ByteOps.IFLT:
            case ByteOps.IFGE:
            case ByteOps.IFGT:
            case ByteOps.IFLE:
            case ByteOps.IF_ICMPEQ:
            case ByteOps.IF_ICMPNE:
            case ByteOps.IF_ICMPLT:
            case ByteOps.IF_ICMPGE:
            case ByteOps.IF_ICMPGT:
            case ByteOps.IF_ICMPLE:
            case ByteOps.IF_ACMPEQ:
            case ByteOps.IF_ACMPNE:
            case ByteOps.GOTO:
            case ByteOps.JSR:
            case ByteOps.IFNULL:
            case ByteOps.IFNONNULL:
                {
                    int target = offset + bytes.getShort(offset + 1);
                    visitor.visitBranch(opcode, offset, 3, target);
                    return 3;
                }
            case ByteOps.RET:
                {
                    int idx = bytes.getUnsignedByte(offset + 1);
                    visitor.visitLocal(opcode, offset, 2, idx, Type.RETURN_ADDRESS, 0);
                    return 2;
                }
            case ByteOps.TABLESWITCH:
                {
                    return parseTableswitch(offset, visitor);
                }
            case ByteOps.LOOKUPSWITCH:
                {
                    return parseLookupswitch(offset, visitor);
                }
            case ByteOps.IRETURN:
                {
                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1, Type.INT);
                    return 1;
                }
            case ByteOps.LRETURN:
                {
                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1, Type.LONG);
                    return 1;
                }
            case ByteOps.FRETURN:
                {
                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1, Type.FLOAT);
                    return 1;
                }
            case ByteOps.DRETURN:
                {
                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1, Type.DOUBLE);
                    return 1;
                }
            case ByteOps.ARETURN:
                {
                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1, Type.OBJECT);
                    return 1;
                }
            case ByteOps.RETURN:
            case ByteOps.ATHROW:
            case ByteOps.MONITORENTER:
            case ByteOps.MONITOREXIT:
                {
                    visitor.visitNoArgs(opcode, offset, 1, Type.VOID);
                    return 1;
                }
            case ByteOps.GETSTATIC:
            case ByteOps.PUTSTATIC:
            case ByteOps.GETFIELD:
            case ByteOps.PUTFIELD:
            case ByteOps.INVOKEVIRTUAL:
            case ByteOps.INVOKESPECIAL:
            case ByteOps.INVOKESTATIC:
            case ByteOps.NEW:
            case ByteOps.ANEWARRAY:
            case ByteOps.CHECKCAST:
            case ByteOps.INSTANCEOF:
                {
                    int idx = bytes.getUnsignedShort(offset + 1);
                    Constant cst = pool.get(idx);
                    visitor.visitConstant(opcode, offset, 3, cst, 0);
                    return 3;
                }
            case ByteOps.INVOKEINTERFACE:
                {
                    int idx = bytes.getUnsignedShort(offset + 1);
                    int count = bytes.getUnsignedByte(offset + 3);
                    int expectZero = bytes.getUnsignedByte(offset + 4);
                    Constant cst = pool.get(idx);
                    visitor.visitConstant(opcode, offset, 5, cst, count | (expectZero << 8));
                    return 5;
                }
            case ByteOps.INVOKEDYNAMIC:
                {
                    throw new ParseException("invokedynamic not supported");
                }
            case ByteOps.NEWARRAY:
                {
                    return parseNewarray(offset, visitor);
                }
            case ByteOps.WIDE:
                {
                    return parseWide(offset, visitor);
                }
            case ByteOps.MULTIANEWARRAY:
                {
                    int idx = bytes.getUnsignedShort(offset + 1);
                    int dimensions = bytes.getUnsignedByte(offset + 3);
                    Constant cst = pool.get(idx);
                    visitor.visitConstant(opcode, offset, 4, cst, dimensions);
                    return 4;
                }
            case ByteOps.GOTO_W:
            case ByteOps.JSR_W:
                {
                    int target = offset + bytes.getInt(offset + 1);
                    int newop = (opcode == ByteOps.GOTO_W) ? ByteOps.GOTO : ByteOps.JSR;
                    visitor.visitBranch(newop, offset, 5, target);
                    return 5;
                }
            default:
                {
                    visitor.visitInvalid(opcode, offset, 1);
                    return 1;
                }
        }
    } catch (SimException ex) {
        ex.addContext("...at bytecode offset " + Hex.u4(offset));
        throw ex;
    } catch (RuntimeException ex) {
        SimException se = new SimException(ex);
        se.addContext("...at bytecode offset " + Hex.u4(offset));
        throw se;
    }
}
Also used : Constant(com.taobao.android.dx.rop.cst.Constant) CstInteger(com.taobao.android.dx.rop.cst.CstInteger) ParseException(com.taobao.android.dx.cf.iface.ParseException)

Example 30 with Constant

use of com.taobao.android.dx.rop.cst.Constant in project atlas by alibaba.

the class OutputFinisher method addConstants.

/**
     * Helper for {@link #getAllConstants} which adds all the info for
     * a single instruction.
     *
     * @param result {@code non-null;} result set to add to
     * @param insn {@code non-null;} instruction to scrutinize
     */
private static void addConstants(HashSet<Constant> result, DalvInsn insn) {
    if (insn instanceof CstInsn) {
        Constant cst = ((CstInsn) insn).getConstant();
        result.add(cst);
    } else if (insn instanceof LocalSnapshot) {
        RegisterSpecSet specs = ((LocalSnapshot) insn).getLocals();
        int size = specs.size();
        for (int i = 0; i < size; i++) {
            addConstants(result, specs.get(i));
        }
    } else if (insn instanceof LocalStart) {
        RegisterSpec spec = ((LocalStart) insn).getLocal();
        addConstants(result, spec);
    }
}
Also used : RegisterSpecSet(com.taobao.android.dx.rop.code.RegisterSpecSet) Constant(com.taobao.android.dx.rop.cst.Constant) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Aggregations

Constant (com.taobao.android.dx.rop.cst.Constant)42 RegisterSpecList (com.taobao.android.dx.rop.code.RegisterSpecList)17 CstType (com.taobao.android.dx.rop.cst.CstType)13 CstInsn (com.taobao.android.dx.dex.code.CstInsn)12 CstString (com.taobao.android.dx.rop.cst.CstString)12 RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)10 TypedConstant (com.taobao.android.dx.rop.cst.TypedConstant)10 CstLiteralBits (com.taobao.android.dx.rop.cst.CstLiteralBits)9 CstFieldRef (com.taobao.android.dx.rop.cst.CstFieldRef)6 CstInteger (com.taobao.android.dx.rop.cst.CstInteger)6 Type (com.taobao.android.dx.rop.type.Type)5 NameValuePair (com.taobao.android.dx.rop.annotation.NameValuePair)4 Insn (com.taobao.android.dx.rop.code.Insn)4 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)4 CstMethodRef (com.taobao.android.dx.rop.cst.CstMethodRef)4 TypeBearer (com.taobao.android.dx.rop.type.TypeBearer)4 Rop (com.taobao.android.dx.rop.code.Rop)3 ThrowingCstInsn (com.taobao.android.dx.rop.code.ThrowingCstInsn)3 ArrayList (java.util.ArrayList)3 CstInsn (com.taobao.android.dx.rop.code.CstInsn)2