Search in sources :

Example 26 with Constant

use of com.android.dx.rop.cst.Constant in project J2ME-Loader by nikita36078.

the class ConstantPoolParser method parse0.

/**
 * Parses the constant for the given index if it hasn't already been
 * parsed, also storing it in the constant pool. This will also
 * have the side effect of parsing any entries the indicated one
 * depends on.
 *
 * @param idx which constant
 * @return {@code non-null;} the parsed constant
 */
private Constant parse0(int idx, BitSet wasUtf8) {
    Constant cst = pool.getOrNull(idx);
    if (cst != null) {
        return cst;
    }
    int at = offsets[idx];
    try {
        int tag = bytes.getUnsignedByte(at);
        switch(tag) {
            case CONSTANT_Utf8:
                {
                    cst = parseUtf8(at);
                    wasUtf8.set(idx);
                    break;
                }
            case CONSTANT_Integer:
                {
                    int value = bytes.getInt(at + 1);
                    cst = CstInteger.make(value);
                    break;
                }
            case CONSTANT_Float:
                {
                    int bits = bytes.getInt(at + 1);
                    cst = CstFloat.make(bits);
                    break;
                }
            case CONSTANT_Long:
                {
                    long value = bytes.getLong(at + 1);
                    cst = CstLong.make(value);
                    break;
                }
            case CONSTANT_Double:
                {
                    long bits = bytes.getLong(at + 1);
                    cst = CstDouble.make(bits);
                    break;
                }
            case CONSTANT_Class:
                {
                    int nameIndex = bytes.getUnsignedShort(at + 1);
                    CstString name = (CstString) parse0(nameIndex, wasUtf8);
                    cst = new CstType(Type.internClassName(name.getString()));
                    break;
                }
            case CONSTANT_String:
                {
                    int stringIndex = bytes.getUnsignedShort(at + 1);
                    cst = parse0(stringIndex, wasUtf8);
                    break;
                }
            case CONSTANT_Fieldref:
                {
                    int classIndex = bytes.getUnsignedShort(at + 1);
                    CstType type = (CstType) parse0(classIndex, wasUtf8);
                    int natIndex = bytes.getUnsignedShort(at + 3);
                    CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
                    cst = new CstFieldRef(type, nat);
                    break;
                }
            case CONSTANT_Methodref:
                {
                    int classIndex = bytes.getUnsignedShort(at + 1);
                    CstType type = (CstType) parse0(classIndex, wasUtf8);
                    int natIndex = bytes.getUnsignedShort(at + 3);
                    CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
                    cst = new CstMethodRef(type, nat);
                    break;
                }
            case CONSTANT_InterfaceMethodref:
                {
                    int classIndex = bytes.getUnsignedShort(at + 1);
                    CstType type = (CstType) parse0(classIndex, wasUtf8);
                    int natIndex = bytes.getUnsignedShort(at + 3);
                    CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
                    cst = new CstInterfaceMethodRef(type, nat);
                    break;
                }
            case CONSTANT_NameAndType:
                {
                    int nameIndex = bytes.getUnsignedShort(at + 1);
                    CstString name = (CstString) parse0(nameIndex, wasUtf8);
                    int descriptorIndex = bytes.getUnsignedShort(at + 3);
                    CstString descriptor = (CstString) parse0(descriptorIndex, wasUtf8);
                    cst = new CstNat(name, descriptor);
                    break;
                }
            case CONSTANT_MethodHandle:
                {
                    int kind = bytes.getUnsignedByte(at + 1);
                    int constantIndex = bytes.getUnsignedShort(at + 2);
                    Constant ref;
                    switch(kind) {
                        case CstMethodHandle.KIND_GETFIELD:
                        case CstMethodHandle.KIND_GETSTATIC:
                        case CstMethodHandle.KIND_PUTFIELD:
                        case CstMethodHandle.KIND_PUTSTATIC:
                            CstFieldRef field = (CstFieldRef) parse0(constantIndex, wasUtf8);
                            ref = field;
                            break;
                        case CstMethodHandle.KIND_INVOKEVIRTUAL:
                        case CstMethodHandle.KIND_NEWINVOKESPECIAL:
                            CstMethodRef method = (CstMethodRef) parse0(constantIndex, wasUtf8);
                            ref = method;
                            break;
                        case CstMethodHandle.KIND_INVOKESTATIC:
                        case CstMethodHandle.KIND_INVOKESPECIAL:
                            ref = parse0(constantIndex, wasUtf8);
                            if (!(ref instanceof CstMethodRef || ref instanceof CstInterfaceMethodRef)) {
                                throw new ParseException("Unsupported ref constant type for MethodHandle " + ref.getClass());
                            }
                            break;
                        case CstMethodHandle.KIND_INVOKEINTERFACE:
                            CstInterfaceMethodRef interfaceMethod = (CstInterfaceMethodRef) parse0(constantIndex, wasUtf8);
                            ref = interfaceMethod;
                            break;
                        default:
                            throw new ParseException("Unsupported MethodHandle kind: " + kind);
                    }
                    cst = CstMethodHandle.make(kind, ref);
                    break;
                }
            case CONSTANT_MethodType:
                {
                    int descriptorIndex = bytes.getUnsignedShort(at + 1);
                    CstString descriptor = (CstString) parse0(descriptorIndex, wasUtf8);
                    cst = CstMethodType.make(descriptor);
                    break;
                }
            case CONSTANT_InvokeDynamic:
                {
                    int bootstrapMethodIndex = bytes.getUnsignedShort(at + 1);
                    int natIndex = bytes.getUnsignedShort(at + 3);
                    CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
                    cst = CstInvokeDynamic.make(bootstrapMethodIndex, nat);
                    break;
                }
            default:
                {
                    throw new ParseException("unknown tag byte: " + Hex.u1(tag));
                }
        }
    } catch (ParseException ex) {
        ex.addContext("...while parsing cst " + Hex.u2(idx) + " at offset " + Hex.u4(at));
        throw ex;
    } catch (RuntimeException ex) {
        ParseException pe = new ParseException(ex);
        pe.addContext("...while parsing cst " + Hex.u2(idx) + " at offset " + Hex.u4(at));
        throw pe;
    }
    pool.set(idx, cst);
    return cst;
}
Also used : CstNat(com.android.dx.rop.cst.CstNat) Constant(com.android.dx.rop.cst.Constant) CstType(com.android.dx.rop.cst.CstType) CstString(com.android.dx.rop.cst.CstString) CstFieldRef(com.android.dx.rop.cst.CstFieldRef) CstInterfaceMethodRef(com.android.dx.rop.cst.CstInterfaceMethodRef) ParseException(com.android.dx.cf.iface.ParseException) CstMethodRef(com.android.dx.rop.cst.CstMethodRef)

Example 27 with Constant

use of com.android.dx.rop.cst.Constant in project J2ME-Loader by nikita36078.

the class StdAttributeFactory method annotationDefault.

/**
 * Parses an {@code AnnotationDefault} attribute.
 */
private Attribute annotationDefault(DirectClassFile cf, int offset, int length, ParseObserver observer) {
    if (length < 2) {
        throwSeverelyTruncated();
    }
    AnnotationParser ap = new AnnotationParser(cf, offset, length, observer);
    Constant cst = ap.parseValueAttribute();
    return new AttAnnotationDefault(cst, length);
}
Also used : Constant(com.android.dx.rop.cst.Constant) TypedConstant(com.android.dx.rop.cst.TypedConstant) AttAnnotationDefault(com.android.dx.cf.attrib.AttAnnotationDefault)

Example 28 with Constant

use of com.android.dx.rop.cst.Constant in project J2ME-Loader by nikita36078.

the class CfTranslator method updateDexStatistics.

/**
 * Helper that updates the dex statistics.
 */
private static void updateDexStatistics(DxContext context, CfOptions cfOptions, DexOptions dexOptions, RopMethod optRmeth, RopMethod nonOptRmeth, LocalVariableInfo locals, int paramSize, int originalByteCount) {
    /*
         * Run rop->dex again on optimized vs. non-optimized method to
         * collect statistics. We have to totally convert both ways,
         * since converting the "real" method getting added to the
         * file would corrupt it (by messing with its constant pool
         * indices).
         */
    DalvCode optCode = RopTranslator.translate(optRmeth, cfOptions.positionInfo, locals, paramSize, dexOptions);
    DalvCode nonOptCode = RopTranslator.translate(nonOptRmeth, cfOptions.positionInfo, locals, paramSize, dexOptions);
    /*
         * Fake out the indices, so code.getInsns() can work well enough
         * for the current purpose.
         */
    DalvCode.AssignIndicesCallback callback = new DalvCode.AssignIndicesCallback() {

        public int getIndex(Constant cst) {
            // Everything is at index 0!
            return 0;
        }
    };
    optCode.assignIndices(callback);
    nonOptCode.assignIndices(callback);
    context.codeStatistics.updateDexStatistics(nonOptCode, optCode);
    context.codeStatistics.updateOriginalByteCount(originalByteCount);
}
Also used : DalvCode(com.android.dx.dex.code.DalvCode) Constant(com.android.dx.rop.cst.Constant) TypedConstant(com.android.dx.rop.cst.TypedConstant)

Example 29 with Constant

use of com.android.dx.rop.cst.Constant in project J2ME-Loader by nikita36078.

the class SCCP method simulateMath.

/**
 * Simulates math insns, if possible.
 *
 * @param insn non-null insn to simulate
 * @param resultType basic type of the result
 * @return constant result or null if not simulatable.
 */
private Constant simulateMath(SsaInsn insn, int resultType) {
    Insn ropInsn = insn.getOriginalRopInsn();
    int opcode = insn.getOpcode().getOpcode();
    RegisterSpecList sources = insn.getSources();
    int regA = sources.get(0).getReg();
    Constant cA;
    Constant cB;
    if (latticeValues[regA] != CONSTANT) {
        cA = null;
    } else {
        cA = latticeConstants[regA];
    }
    if (sources.size() == 1) {
        CstInsn cstInsn = (CstInsn) ropInsn;
        cB = cstInsn.getConstant();
    } else {
        /* sources.size() == 2 */
        int regB = sources.get(1).getReg();
        if (latticeValues[regB] != CONSTANT) {
            cB = null;
        } else {
            cB = latticeConstants[regB];
        }
    }
    if (cA == null || cB == null) {
        // TODO handle a constant of 0 with MUL or AND
        return null;
    }
    switch(resultType) {
        case Type.BT_INT:
            int vR;
            boolean skip = false;
            int vA = ((CstInteger) cA).getValue();
            int vB = ((CstInteger) cB).getValue();
            switch(opcode) {
                case RegOps.ADD:
                    vR = vA + vB;
                    break;
                case RegOps.SUB:
                    // 1 source for reverse sub, 2 sources for regular sub
                    if (sources.size() == 1) {
                        vR = vB - vA;
                    } else {
                        vR = vA - vB;
                    }
                    break;
                case RegOps.MUL:
                    vR = vA * vB;
                    break;
                case RegOps.DIV:
                    if (vB == 0) {
                        skip = true;
                        // just to hide a warning
                        vR = 0;
                    } else {
                        vR = vA / vB;
                    }
                    break;
                case RegOps.AND:
                    vR = vA & vB;
                    break;
                case RegOps.OR:
                    vR = vA | vB;
                    break;
                case RegOps.XOR:
                    vR = vA ^ vB;
                    break;
                case RegOps.SHL:
                    vR = vA << vB;
                    break;
                case RegOps.SHR:
                    vR = vA >> vB;
                    break;
                case RegOps.USHR:
                    vR = vA >>> vB;
                    break;
                case RegOps.REM:
                    if (vB == 0) {
                        skip = true;
                        // just to hide a warning
                        vR = 0;
                    } else {
                        vR = vA % vB;
                    }
                    break;
                default:
                    throw new RuntimeException("Unexpected op");
            }
            return skip ? null : CstInteger.make(vR);
        default:
            // not yet supported
            return null;
    }
}
Also used : CstInsn(com.android.dx.rop.code.CstInsn) Insn(com.android.dx.rop.code.Insn) PlainInsn(com.android.dx.rop.code.PlainInsn) CstInsn(com.android.dx.rop.code.CstInsn) Constant(com.android.dx.rop.cst.Constant) TypedConstant(com.android.dx.rop.cst.TypedConstant) CstInteger(com.android.dx.rop.cst.CstInteger) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList)

Example 30 with Constant

use of com.android.dx.rop.cst.Constant in project J2ME-Loader by nikita36078.

the class OutputFinisher method assignIndices.

/**
 * Helper for {@link #assignIndices} which does assignment for one
 * instruction.
 *
 * @param insn {@code non-null;} the instruction
 * @param callback {@code non-null;} the callback
 */
private static void assignIndices(MultiCstInsn insn, DalvCode.AssignIndicesCallback callback) {
    for (int i = 0; i < insn.getNumberOfConstants(); ++i) {
        Constant cst = insn.getConstant(i);
        int index = callback.getIndex(cst);
        insn.setIndex(i, index);
        if (cst instanceof CstMemberRef) {
            CstMemberRef member = (CstMemberRef) cst;
            CstType definer = member.getDefiningClass();
            index = callback.getIndex(definer);
            insn.setClassIndex(index);
        }
    }
}
Also used : CstMemberRef(com.android.dx.rop.cst.CstMemberRef) Constant(com.android.dx.rop.cst.Constant) CstType(com.android.dx.rop.cst.CstType)

Aggregations

Constant (com.android.dx.rop.cst.Constant)91 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)36 CstType (com.android.dx.rop.cst.CstType)30 CstString (com.android.dx.rop.cst.CstString)27 CstInsn (com.android.dx.dex.code.CstInsn)24 RegisterSpec (com.android.dx.rop.code.RegisterSpec)20 TypedConstant (com.android.dx.rop.cst.TypedConstant)20 CstLiteralBits (com.android.dx.rop.cst.CstLiteralBits)18 CstFieldRef (com.android.dx.rop.cst.CstFieldRef)17 CstMethodRef (com.android.dx.rop.cst.CstMethodRef)14 CstInteger (com.android.dx.rop.cst.CstInteger)12 NameValuePair (com.android.dx.rop.annotation.NameValuePair)8 Insn (com.android.dx.rop.code.Insn)8 PlainInsn (com.android.dx.rop.code.PlainInsn)8 Type (com.android.dx.rop.type.Type)8 TypeBearer (com.android.dx.rop.type.TypeBearer)8 Rop (com.android.dx.rop.code.Rop)6 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)6 ArrayList (java.util.ArrayList)6 ParseException (com.android.dx.cf.iface.ParseException)4