Search in sources :

Example 1 with EncodedMethod

use of com.android.dx.dex.file.EncodedMethod in project buck by facebook.

the class CfTranslator method processMethods.

/**
     * Processes the methods of the given class.
     *
     * @param context
     * @param cf {@code non-null;} class being translated
     * @param cfOptions {@code non-null;} options for class translation
     * @param dexOptions {@code non-null;} options for dex output
     * @param out {@code non-null;} output class
     * @param dexFile {@code non-null;} dex output
     */
private static void processMethods(DxContext context, DirectClassFile cf, CfOptions cfOptions, DexOptions dexOptions, ClassDefItem out, DexFile dexFile) {
    CstType thisClass = cf.getThisClass();
    MethodList methods = cf.getMethods();
    int sz = methods.size();
    for (int i = 0; i < sz; i++) {
        Method one = methods.get(i);
        try {
            CstMethodRef meth = new CstMethodRef(thisClass, one.getNat());
            int accessFlags = one.getAccessFlags();
            boolean isStatic = AccessFlags.isStatic(accessFlags);
            boolean isPrivate = AccessFlags.isPrivate(accessFlags);
            boolean isNative = AccessFlags.isNative(accessFlags);
            boolean isAbstract = AccessFlags.isAbstract(accessFlags);
            boolean isConstructor = meth.isInstanceInit() || meth.isClassInit();
            DalvCode code;
            if (isNative || isAbstract) {
                // There's no code for native or abstract methods.
                code = null;
            } else {
                ConcreteMethod concrete = new ConcreteMethod(one, cf, (cfOptions.positionInfo != PositionList.NONE), cfOptions.localInfo);
                TranslationAdvice advice;
                advice = DexTranslationAdvice.THE_ONE;
                RopMethod rmeth = Ropper.convert(concrete, advice, methods);
                RopMethod nonOptRmeth = null;
                int paramSize;
                paramSize = meth.getParameterWordCount(isStatic);
                String canonicalName = thisClass.getClassType().getDescriptor() + "." + one.getName().getString();
                if (cfOptions.optimize && context.optimizerOptions.shouldOptimize(canonicalName)) {
                    if (DEBUG) {
                        System.err.println("Optimizing " + canonicalName);
                    }
                    nonOptRmeth = rmeth;
                    rmeth = Optimizer.optimize(rmeth, paramSize, isStatic, cfOptions.localInfo, advice);
                    if (DEBUG) {
                        context.optimizerOptions.compareOptimizerStep(nonOptRmeth, paramSize, isStatic, cfOptions, advice, rmeth);
                    }
                    if (cfOptions.statistics) {
                        context.codeStatistics.updateRopStatistics(nonOptRmeth, rmeth);
                    }
                }
                LocalVariableInfo locals = null;
                if (cfOptions.localInfo) {
                    locals = LocalVariableExtractor.extract(rmeth);
                }
                code = RopTranslator.translate(rmeth, cfOptions.positionInfo, locals, paramSize, dexOptions);
                if (cfOptions.statistics && nonOptRmeth != null) {
                    updateDexStatistics(context, cfOptions, dexOptions, rmeth, nonOptRmeth, locals, paramSize, concrete.getCode().size());
                }
            }
            // Preserve the synchronized flag as its "declared" variant...
            if (AccessFlags.isSynchronized(accessFlags)) {
                accessFlags |= AccessFlags.ACC_DECLARED_SYNCHRONIZED;
                /*
                     * ...but only native methods are actually allowed to be
                     * synchronized.
                     */
                if (!isNative) {
                    accessFlags &= ~AccessFlags.ACC_SYNCHRONIZED;
                }
            }
            if (isConstructor) {
                accessFlags |= AccessFlags.ACC_CONSTRUCTOR;
            }
            TypeList exceptions = AttributeTranslator.getExceptions(one);
            EncodedMethod mi = new EncodedMethod(meth, accessFlags, code, exceptions);
            if (meth.isInstanceInit() || meth.isClassInit() || isStatic || isPrivate) {
                out.addDirectMethod(mi);
            } else {
                out.addVirtualMethod(mi);
            }
            Annotations annotations = AttributeTranslator.getMethodAnnotations(one);
            if (annotations.size() != 0) {
                out.addMethodAnnotations(meth, annotations, dexFile);
            }
            AnnotationsList list = AttributeTranslator.getParameterAnnotations(one);
            if (list.size() != 0) {
                out.addParameterAnnotations(meth, list, dexFile);
            }
            dexFile.getMethodIds().intern(meth);
        } catch (RuntimeException ex) {
            String msg = "...while processing " + one.getName().toHuman() + " " + one.getDescriptor().toHuman();
            throw ExceptionWithContext.withContext(ex, msg);
        }
    }
}
Also used : DalvCode(com.android.dx.dex.code.DalvCode) RopMethod(com.android.dx.rop.code.RopMethod) AnnotationsList(com.android.dx.rop.annotation.AnnotationsList) MethodList(com.android.dx.cf.iface.MethodList) DexTranslationAdvice(com.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.android.dx.rop.code.TranslationAdvice) EncodedMethod(com.android.dx.dex.file.EncodedMethod) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) RopMethod(com.android.dx.rop.code.RopMethod) Method(com.android.dx.cf.iface.Method) CstString(com.android.dx.rop.cst.CstString) CstMethodRef(com.android.dx.rop.cst.CstMethodRef) LocalVariableInfo(com.android.dx.rop.code.LocalVariableInfo) Annotations(com.android.dx.rop.annotation.Annotations) EncodedMethod(com.android.dx.dex.file.EncodedMethod) CstType(com.android.dx.rop.cst.CstType) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) TypeList(com.android.dx.rop.type.TypeList)

Example 2 with EncodedMethod

use of com.android.dx.dex.file.EncodedMethod in project J2ME-Loader by nikita36078.

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 3 with EncodedMethod

use of com.android.dx.dex.file.EncodedMethod 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 4 with EncodedMethod

use of com.android.dx.dex.file.EncodedMethod in project J2ME-Loader by nikita36078.

the class CfTranslator method processMethods.

/**
 * Processes the methods of the given class.
 *
 * @param context {@code non-null;} the state global to this invocation.
 * @param cf {@code non-null;} class being translated
 * @param cfOptions {@code non-null;} options for class translation
 * @param dexOptions {@code non-null;} options for dex output
 * @param out {@code non-null;} output class
 * @param dexFile {@code non-null;} dex output
 */
private static void processMethods(DxContext context, DirectClassFile cf, CfOptions cfOptions, DexOptions dexOptions, ClassDefItem out, DexFile dexFile) {
    CstType thisClass = cf.getThisClass();
    MethodList methods = cf.getMethods();
    int sz = methods.size();
    for (int i = 0; i < sz; i++) {
        Method one = methods.get(i);
        try {
            CstMethodRef meth = new CstMethodRef(thisClass, one.getNat());
            int accessFlags = one.getAccessFlags();
            boolean isStatic = AccessFlags.isStatic(accessFlags);
            boolean isPrivate = AccessFlags.isPrivate(accessFlags);
            boolean isNative = AccessFlags.isNative(accessFlags);
            boolean isAbstract = AccessFlags.isAbstract(accessFlags);
            boolean isConstructor = meth.isInstanceInit() || meth.isClassInit();
            DalvCode code;
            if (isNative || isAbstract) {
                // There's no code for native or abstract methods.
                code = null;
            } else {
                ConcreteMethod concrete = new ConcreteMethod(one, cf, (cfOptions.positionInfo != PositionList.NONE), cfOptions.localInfo);
                TranslationAdvice advice;
                advice = DexTranslationAdvice.THE_ONE;
                RopMethod rmeth = Ropper.convert(concrete, advice, methods, dexOptions);
                RopMethod nonOptRmeth = null;
                int paramSize;
                paramSize = meth.getParameterWordCount(isStatic);
                String canonicalName = thisClass.getClassType().getDescriptor() + "." + one.getName().getString();
                if (cfOptions.optimize && context.optimizerOptions.shouldOptimize(canonicalName)) {
                    if (DEBUG) {
                        System.err.println("Optimizing " + canonicalName);
                    }
                    nonOptRmeth = rmeth;
                    rmeth = Optimizer.optimize(rmeth, paramSize, isStatic, cfOptions.localInfo, advice);
                    if (DEBUG) {
                        context.optimizerOptions.compareOptimizerStep(nonOptRmeth, paramSize, isStatic, cfOptions, advice, rmeth);
                    }
                    if (cfOptions.statistics) {
                        context.codeStatistics.updateRopStatistics(nonOptRmeth, rmeth);
                    }
                }
                LocalVariableInfo locals = null;
                if (cfOptions.localInfo) {
                    locals = LocalVariableExtractor.extract(rmeth);
                }
                code = RopTranslator.translate(rmeth, cfOptions.positionInfo, locals, paramSize, dexOptions);
                if (cfOptions.statistics && nonOptRmeth != null) {
                    updateDexStatistics(context, cfOptions, dexOptions, rmeth, nonOptRmeth, locals, paramSize, concrete.getCode().size());
                }
            }
            // Preserve the synchronized flag as its "declared" variant...
            if (AccessFlags.isSynchronized(accessFlags)) {
                accessFlags |= AccessFlags.ACC_DECLARED_SYNCHRONIZED;
                /*
                     * ...but only native methods are actually allowed to be
                     * synchronized.
                     */
                if (!isNative) {
                    accessFlags &= ~AccessFlags.ACC_SYNCHRONIZED;
                }
            }
            if (isConstructor) {
                accessFlags |= AccessFlags.ACC_CONSTRUCTOR;
            }
            TypeList exceptions = AttributeTranslator.getExceptions(one);
            EncodedMethod mi = new EncodedMethod(meth, accessFlags, code, exceptions);
            if (meth.isInstanceInit() || meth.isClassInit() || isStatic || isPrivate) {
                out.addDirectMethod(mi);
            } else {
                out.addVirtualMethod(mi);
            }
            Annotations annotations = AttributeTranslator.getMethodAnnotations(one);
            if (annotations.size() != 0) {
                out.addMethodAnnotations(meth, annotations, dexFile);
            }
            AnnotationsList list = AttributeTranslator.getParameterAnnotations(one);
            if (list.size() != 0) {
                out.addParameterAnnotations(meth, list, dexFile);
            }
            dexFile.getMethodIds().intern(meth);
        } catch (RuntimeException ex) {
            String msg = "...while processing " + one.getName().toHuman() + " " + one.getDescriptor().toHuman();
            throw ExceptionWithContext.withContext(ex, msg);
        }
    }
}
Also used : DalvCode(com.android.dx.dex.code.DalvCode) RopMethod(com.android.dx.rop.code.RopMethod) AnnotationsList(com.android.dx.rop.annotation.AnnotationsList) MethodList(com.android.dx.cf.iface.MethodList) DexTranslationAdvice(com.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.android.dx.rop.code.TranslationAdvice) EncodedMethod(com.android.dx.dex.file.EncodedMethod) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) RopMethod(com.android.dx.rop.code.RopMethod) Method(com.android.dx.cf.iface.Method) CstString(com.android.dx.rop.cst.CstString) CstMethodRef(com.android.dx.rop.cst.CstMethodRef) LocalVariableInfo(com.android.dx.rop.code.LocalVariableInfo) Annotations(com.android.dx.rop.annotation.Annotations) EncodedMethod(com.android.dx.dex.file.EncodedMethod) CstType(com.android.dx.rop.cst.CstType) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) TypeList(com.android.dx.rop.type.TypeList)

Aggregations

EncodedMethod (com.android.dx.dex.file.EncodedMethod)4 Annotations (com.android.dx.rop.annotation.Annotations)4 AnnotationsList (com.android.dx.rop.annotation.AnnotationsList)4 CstString (com.android.dx.rop.cst.CstString)4 ConcreteMethod (com.android.dx.cf.code.ConcreteMethod)2 Method (com.android.dx.cf.iface.Method)2 MethodList (com.android.dx.cf.iface.MethodList)2 DalvCode (com.android.dx.dex.code.DalvCode)2 ClassDefItem (com.android.dx.dex.file.ClassDefItem)2 Annotation (com.android.dx.rop.annotation.Annotation)2 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)2 LocalVariableInfo (com.android.dx.rop.code.LocalVariableInfo)2 RopMethod (com.android.dx.rop.code.RopMethod)2 TranslationAdvice (com.android.dx.rop.code.TranslationAdvice)2 CstMethodRef (com.android.dx.rop.cst.CstMethodRef)2 CstNat (com.android.dx.rop.cst.CstNat)2 CstType (com.android.dx.rop.cst.CstType)2 TypeList (com.android.dx.rop.type.TypeList)2 PrintWriter (java.io.PrintWriter)2 TreeMap (java.util.TreeMap)2