Search in sources :

Example 1 with MethodList

use of com.taobao.android.dx.cf.iface.MethodList in project atlas by alibaba.

the class CfTranslator method processMethods.

/**
     * Processes the methods of the given class.
     *
     * @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(DirectClassFile cf, CfOptions cfOptions, DexOptions dexOptions, OptimizerOptions optimizerOptions, 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 && optimizerOptions.shouldOptimize(canonicalName)) {
                    if (DEBUG) {
                        System.err.println("Optimizing " + canonicalName);
                    }
                    nonOptRmeth = rmeth;
                    rmeth = new Optimizer().optimize(rmeth, paramSize, isStatic, cfOptions.localInfo, advice);
                    if (DEBUG) {
                        OptimizerOptions.compareOptimizerStep(nonOptRmeth, paramSize, isStatic, cfOptions, advice, rmeth);
                    }
                    if (cfOptions.statistics) {
                        cfOptions.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(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) {
                if (list.contains(meth.toString())) {
                    System.out.println(meth.toString());
                } else {
                    list.add(meth.toString());
                }
                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.taobao.android.dx.dex.code.DalvCode) RopMethod(com.taobao.android.dx.rop.code.RopMethod) Optimizer(com.taobao.android.dx.ssa.Optimizer) AnnotationsList(com.taobao.android.dx.rop.annotation.AnnotationsList) MethodList(com.taobao.android.dx.cf.iface.MethodList) TranslationAdvice(com.taobao.android.dx.rop.code.TranslationAdvice) DexTranslationAdvice(com.taobao.android.dx.rop.code.DexTranslationAdvice) Method(com.taobao.android.dx.cf.iface.Method) ConcreteMethod(com.taobao.android.dx.cf.code.ConcreteMethod) RopMethod(com.taobao.android.dx.rop.code.RopMethod) EncodedMethod(com.taobao.android.dx.dex.file.EncodedMethod) CstString(com.taobao.android.dx.rop.cst.CstString) CstMethodRef(com.taobao.android.dx.rop.cst.CstMethodRef) LocalVariableInfo(com.taobao.android.dx.rop.code.LocalVariableInfo) Annotations(com.taobao.android.dx.rop.annotation.Annotations) EncodedMethod(com.taobao.android.dx.dex.file.EncodedMethod) CstType(com.taobao.android.dx.rop.cst.CstType) ConcreteMethod(com.taobao.android.dx.cf.code.ConcreteMethod) TypeList(com.taobao.android.dx.rop.type.TypeList)

Example 2 with MethodList

use of com.taobao.android.dx.cf.iface.MethodList in project atlas by alibaba.

the class ClassReferenceListBuilder method addDependencies.

private void addDependencies(DirectClassFile classFile) {
    for (Constant constant : classFile.getConstantPool().getEntries()) {
        if (constant instanceof CstType) {
            checkDescriptor(((CstType) constant).getClassType().getDescriptor());
        } else if (constant instanceof CstFieldRef) {
            checkDescriptor(((CstFieldRef) constant).getType().getDescriptor());
        } else if (constant instanceof CstBaseMethodRef) {
            checkPrototype(((CstBaseMethodRef) constant).getPrototype());
        }
    }
    FieldList fields = classFile.getFields();
    int nbField = fields.size();
    for (int i = 0; i < nbField; i++) {
        checkDescriptor(fields.get(i).getDescriptor().getString());
    }
    MethodList methods = classFile.getMethods();
    int nbMethods = methods.size();
    for (int i = 0; i < nbMethods; i++) {
        checkPrototype(Prototype.intern(methods.get(i).getDescriptor().getString()));
    }
}
Also used : CstBaseMethodRef(com.taobao.android.dx.rop.cst.CstBaseMethodRef) Constant(com.taobao.android.dx.rop.cst.Constant) CstType(com.taobao.android.dx.rop.cst.CstType) CstFieldRef(com.taobao.android.dx.rop.cst.CstFieldRef) MethodList(com.taobao.android.dx.cf.iface.MethodList) FieldList(com.taobao.android.dx.cf.iface.FieldList)

Example 3 with MethodList

use of com.taobao.android.dx.cf.iface.MethodList in project atlas by alibaba.

the class CfTranslator method processMethods.

/**
 * Processes the methods of the given class.
 *
 * @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(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 && OptimizerOptions.shouldOptimize(canonicalName)) {
                    if (DEBUG) {
                        System.err.println("Optimizing " + canonicalName);
                    }
                    nonOptRmeth = rmeth;
                    rmeth = Optimizer.optimize(rmeth, paramSize, isStatic, cfOptions.localInfo, advice);
                    if (DEBUG) {
                        OptimizerOptions.compareOptimizerStep(nonOptRmeth, paramSize, isStatic, cfOptions, advice, rmeth);
                    }
                    if (cfOptions.statistics) {
                        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(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.taobao.android.dx.dex.code.DalvCode) RopMethod(com.taobao.android.dx.rop.code.RopMethod) AnnotationsList(com.taobao.android.dx.rop.annotation.AnnotationsList) MethodList(com.taobao.android.dx.cf.iface.MethodList) TranslationAdvice(com.taobao.android.dx.rop.code.TranslationAdvice) DexTranslationAdvice(com.taobao.android.dx.rop.code.DexTranslationAdvice) Method(com.taobao.android.dx.cf.iface.Method) ConcreteMethod(com.taobao.android.dx.cf.code.ConcreteMethod) RopMethod(com.taobao.android.dx.rop.code.RopMethod) EncodedMethod(com.taobao.android.dx.dex.file.EncodedMethod) CstString(com.taobao.android.dx.rop.cst.CstString) CstMethodRef(com.taobao.android.dx.rop.cst.CstMethodRef) LocalVariableInfo(com.taobao.android.dx.rop.code.LocalVariableInfo) Annotations(com.taobao.android.dx.rop.annotation.Annotations) EncodedMethod(com.taobao.android.dx.dex.file.EncodedMethod) CstType(com.taobao.android.dx.rop.cst.CstType) ConcreteMethod(com.taobao.android.dx.cf.code.ConcreteMethod) TypeList(com.taobao.android.dx.rop.type.TypeList)

Example 4 with MethodList

use of com.taobao.android.dx.cf.iface.MethodList in project atlas by alibaba.

the class AttributeTranslator method translateAnnotationDefaults.

/**
 * Gets the {@code AnnotationDefault} attributes out of a
 * given class, if any, reforming them as an
 * {@code AnnotationDefault} annotation.
 *
 * @param cf {@code non-null;} the class in question
 * @return {@code null-ok;} an appropriately-constructed
 * {@code AnnotationDefault} annotation, if there were any
 * annotation defaults in the class, or {@code null} if not
 */
private static Annotation translateAnnotationDefaults(DirectClassFile cf) {
    CstType thisClass = cf.getThisClass();
    MethodList methods = cf.getMethods();
    int sz = methods.size();
    Annotation result = new Annotation(thisClass, AnnotationVisibility.EMBEDDED);
    boolean any = false;
    for (int i = 0; i < sz; i++) {
        Method one = methods.get(i);
        AttributeList attribs = one.getAttributes();
        AttAnnotationDefault oneDefault = (AttAnnotationDefault) attribs.findFirst(AttAnnotationDefault.ATTRIBUTE_NAME);
        if (oneDefault != null) {
            NameValuePair pair = new NameValuePair(one.getNat().getName(), oneDefault.getValue());
            result.add(pair);
            any = true;
        }
    }
    if (!any) {
        return null;
    }
    result.setImmutable();
    return AnnotationUtils.makeAnnotationDefault(result);
}
Also used : NameValuePair(com.taobao.android.dx.rop.annotation.NameValuePair) AttributeList(com.taobao.android.dx.cf.iface.AttributeList) CstType(com.taobao.android.dx.rop.cst.CstType) MethodList(com.taobao.android.dx.cf.iface.MethodList) Method(com.taobao.android.dx.cf.iface.Method) AttEnclosingMethod(com.taobao.android.dx.cf.attrib.AttEnclosingMethod) Annotation(com.taobao.android.dx.rop.annotation.Annotation) AttAnnotationDefault(com.taobao.android.dx.cf.attrib.AttAnnotationDefault)

Aggregations

MethodList (com.taobao.android.dx.cf.iface.MethodList)4 CstType (com.taobao.android.dx.rop.cst.CstType)4 Method (com.taobao.android.dx.cf.iface.Method)3 ConcreteMethod (com.taobao.android.dx.cf.code.ConcreteMethod)2 DalvCode (com.taobao.android.dx.dex.code.DalvCode)2 EncodedMethod (com.taobao.android.dx.dex.file.EncodedMethod)2 Annotations (com.taobao.android.dx.rop.annotation.Annotations)2 AnnotationsList (com.taobao.android.dx.rop.annotation.AnnotationsList)2 DexTranslationAdvice (com.taobao.android.dx.rop.code.DexTranslationAdvice)2 LocalVariableInfo (com.taobao.android.dx.rop.code.LocalVariableInfo)2 RopMethod (com.taobao.android.dx.rop.code.RopMethod)2 TranslationAdvice (com.taobao.android.dx.rop.code.TranslationAdvice)2 CstMethodRef (com.taobao.android.dx.rop.cst.CstMethodRef)2 CstString (com.taobao.android.dx.rop.cst.CstString)2 TypeList (com.taobao.android.dx.rop.type.TypeList)2 AttAnnotationDefault (com.taobao.android.dx.cf.attrib.AttAnnotationDefault)1 AttEnclosingMethod (com.taobao.android.dx.cf.attrib.AttEnclosingMethod)1 AttributeList (com.taobao.android.dx.cf.iface.AttributeList)1 FieldList (com.taobao.android.dx.cf.iface.FieldList)1 Annotation (com.taobao.android.dx.rop.annotation.Annotation)1