Search in sources :

Example 6 with CstNat

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

the class AttributeTranslator method translateEnclosingMethod.

/**
 * Gets the {@code EnclosingMethod} attribute out of a given
 * {@link AttributeList}, if any, translating it to an annotation.
 * If the class really has an enclosing method, this returns an
 * {@code EnclosingMethod} annotation; if not, this returns
 * an {@code EnclosingClass} annotation.
 *
 * @param attribs {@code non-null;} the attributes list to search in
 * @return {@code null-ok;} the converted {@code EnclosingMethod} or
 * {@code EnclosingClass} annotation, if there was an
 * attribute to translate
 */
private static Annotation translateEnclosingMethod(AttributeList attribs) {
    AttEnclosingMethod enclosingMethod = (AttEnclosingMethod) attribs.findFirst(AttEnclosingMethod.ATTRIBUTE_NAME);
    if (enclosingMethod == null) {
        return null;
    }
    CstType enclosingClass = enclosingMethod.getEnclosingClass();
    CstNat nat = enclosingMethod.getMethod();
    if (nat == null) {
        /*
             * Dalvik doesn't use EnclosingMethod annotations unless
             * there really is an enclosing method. Anonymous classes
             * are unambiguously identified by having an InnerClass
             * annotation with an empty name along with an appropriate
             * EnclosingClass.
             */
        return AnnotationUtils.makeEnclosingClass(enclosingClass);
    }
    return AnnotationUtils.makeEnclosingMethod(new CstMethodRef(enclosingClass, nat));
}
Also used : CstNat(com.android.dx.rop.cst.CstNat) AttEnclosingMethod(com.android.dx.cf.attrib.AttEnclosingMethod) CstType(com.android.dx.rop.cst.CstType) CstMethodRef(com.android.dx.rop.cst.CstMethodRef)

Example 7 with CstNat

use of com.android.dx.rop.cst.CstNat 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 8 with CstNat

use of com.android.dx.rop.cst.CstNat in project buck by facebook.

the class Main method dumpMethod.

/**
     * Dumps any method with the given name in the given file.
     *
     * @param dex {@code non-null;} the dex file
     * @param fqName {@code non-null;} the fully-qualified name of the
     * method(s)
     * @param out {@code non-null;} where to dump to
     */
private void dumpMethod(DexFile dex, String fqName, OutputStreamWriter out) {
    boolean wildcard = fqName.endsWith("*");
    int lastDot = fqName.lastIndexOf('.');
    if ((lastDot <= 0) || (lastDot == (fqName.length() - 1))) {
        context.err.println("bogus fully-qualified method name: " + fqName);
        return;
    }
    String className = fqName.substring(0, lastDot).replace('.', '/');
    String methodName = fqName.substring(lastDot + 1);
    ClassDefItem clazz = dex.getClassOrNull(className);
    if (clazz == null) {
        context.err.println("no such class: " + className);
        return;
    }
    if (wildcard) {
        methodName = methodName.substring(0, methodName.length() - 1);
    }
    ArrayList<EncodedMethod> allMeths = clazz.getMethods();
    TreeMap<CstNat, EncodedMethod> meths = new TreeMap<CstNat, EncodedMethod>();
    /*
         * Figure out which methods to include in the output, and get them
         * all sorted, so that the printout code is robust with respect to
         * changes in the underlying order.
         */
    for (EncodedMethod meth : allMeths) {
        String methName = meth.getName().getString();
        if ((wildcard && methName.startsWith(methodName)) || (!wildcard && methName.equals(methodName))) {
            meths.put(meth.getRef().getNat(), meth);
        }
    }
    if (meths.size() == 0) {
        context.err.println("no such method: " + fqName);
        return;
    }
    PrintWriter pw = new PrintWriter(out);
    for (EncodedMethod meth : meths.values()) {
        // TODO: Better stuff goes here, perhaps.
        meth.debugPrint(pw, args.verboseDump);
        /*
             * The (default) source file is an attribute of the class, but
             * it's useful to see it in method dumps.
             */
        CstString sourceFile = clazz.getSourceFile();
        if (sourceFile != null) {
            pw.println("  source file: " + sourceFile.toQuoted());
        }
        Annotations methodAnnotations = clazz.getMethodAnnotations(meth.getRef());
        AnnotationsList parameterAnnotations = clazz.getParameterAnnotations(meth.getRef());
        if (methodAnnotations != null) {
            pw.println("  method annotations:");
            for (Annotation a : methodAnnotations.getAnnotations()) {
                pw.println("    " + a);
            }
        }
        if (parameterAnnotations != null) {
            pw.println("  parameter annotations:");
            int sz = parameterAnnotations.size();
            for (int i = 0; i < sz; i++) {
                pw.println("    parameter " + i);
                Annotations annotations = parameterAnnotations.get(i);
                for (Annotation a : annotations.getAnnotations()) {
                    pw.println("      " + a);
                }
            }
        }
    }
    pw.flush();
}
Also used : CstNat(com.android.dx.rop.cst.CstNat) CstString(com.android.dx.rop.cst.CstString) AnnotationsList(com.android.dx.rop.annotation.AnnotationsList) CstString(com.android.dx.rop.cst.CstString) TreeMap(java.util.TreeMap) Annotation(com.android.dx.rop.annotation.Annotation) Annotations(com.android.dx.rop.annotation.Annotations) ClassDefItem(com.android.dx.dex.file.ClassDefItem) EncodedMethod(com.android.dx.dex.file.EncodedMethod) PrintWriter(java.io.PrintWriter)

Example 9 with CstNat

use of com.android.dx.rop.cst.CstNat in project buck by facebook.

the class AttributeTranslator method translateEnclosingMethod.

/**
     * Gets the {@code EnclosingMethod} attribute out of a given
     * {@link AttributeList}, if any, translating it to an annotation.
     * If the class really has an enclosing method, this returns an
     * {@code EnclosingMethod} annotation; if not, this returns
     * an {@code EnclosingClass} annotation.
     *
     * @param attribs {@code non-null;} the attributes list to search in
     * @return {@code null-ok;} the converted {@code EnclosingMethod} or
     * {@code EnclosingClass} annotation, if there was an
     * attribute to translate
     */
private static Annotation translateEnclosingMethod(AttributeList attribs) {
    AttEnclosingMethod enclosingMethod = (AttEnclosingMethod) attribs.findFirst(AttEnclosingMethod.ATTRIBUTE_NAME);
    if (enclosingMethod == null) {
        return null;
    }
    CstType enclosingClass = enclosingMethod.getEnclosingClass();
    CstNat nat = enclosingMethod.getMethod();
    if (nat == null) {
        /*
             * Dalvik doesn't use EnclosingMethod annotations unless
             * there really is an enclosing method. Anonymous classes
             * are unambiguously identified by having an InnerClass
             * annotation with an empty name along with an appropriate
             * EnclosingClass.
             */
        return AnnotationUtils.makeEnclosingClass(enclosingClass);
    }
    return AnnotationUtils.makeEnclosingMethod(new CstMethodRef(enclosingClass, nat));
}
Also used : CstNat(com.android.dx.rop.cst.CstNat) AttEnclosingMethod(com.android.dx.cf.attrib.AttEnclosingMethod) CstType(com.android.dx.rop.cst.CstType) CstMethodRef(com.android.dx.rop.cst.CstMethodRef)

Example 10 with CstNat

use of com.android.dx.rop.cst.CstNat in project buck by facebook.

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:
                {
                    throw new ParseException("MethodHandle not supported");
                }
            case CONSTANT_MethodType:
                {
                    throw new ParseException("MethodType not supported");
                }
            case CONSTANT_InvokeDynamic:
                {
                    throw new ParseException("InvokeDynamic not supported");
                }
            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)

Aggregations

CstNat (com.android.dx.rop.cst.CstNat)16 CstString (com.android.dx.rop.cst.CstString)10 CstType (com.android.dx.rop.cst.CstType)10 ParseException (com.android.dx.cf.iface.ParseException)6 CstMethodRef (com.android.dx.rop.cst.CstMethodRef)6 AttEnclosingMethod (com.android.dx.cf.attrib.AttEnclosingMethod)4 Annotation (com.android.dx.rop.annotation.Annotation)4 AnnotationsList (com.android.dx.rop.annotation.AnnotationsList)4 ConstantPool (com.android.dx.rop.cst.ConstantPool)4 ByteArray (com.android.dx.util.ByteArray)4 Attribute (com.android.dx.cf.iface.Attribute)2 Member (com.android.dx.cf.iface.Member)2 StdAttributeList (com.android.dx.cf.iface.StdAttributeList)2 ClassDefItem (com.android.dx.dex.file.ClassDefItem)2 EncodedMethod (com.android.dx.dex.file.EncodedMethod)2 Annotations (com.android.dx.rop.annotation.Annotations)2 RegisterSpec (com.android.dx.rop.code.RegisterSpec)2 Constant (com.android.dx.rop.cst.Constant)2 CstAnnotation (com.android.dx.rop.cst.CstAnnotation)2 CstArray (com.android.dx.rop.cst.CstArray)2