Search in sources :

Example 1 with Method

use of com.android.dx.cf.iface.Method in project buck by facebook.

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.android.dx.rop.annotation.NameValuePair) AttributeList(com.android.dx.cf.iface.AttributeList) CstType(com.android.dx.rop.cst.CstType) MethodList(com.android.dx.cf.iface.MethodList) AttEnclosingMethod(com.android.dx.cf.attrib.AttEnclosingMethod) Method(com.android.dx.cf.iface.Method) Annotation(com.android.dx.rop.annotation.Annotation) AttAnnotationDefault(com.android.dx.cf.attrib.AttAnnotationDefault)

Example 2 with Method

use of com.android.dx.cf.iface.Method 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 3 with Method

use of com.android.dx.cf.iface.Method in project buck by facebook.

the class DotDumper method endParsingMember.

public void endParsingMember(ByteArray bytes, int offset, String name, String descriptor, Member member) {
    if (!(member instanceof Method)) {
        return;
    }
    if (!shouldDumpMethod(name)) {
        return;
    }
    ConcreteMethod meth = new ConcreteMethod((Method) member, classFile, true, true);
    TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
    RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());
    if (optimize) {
        boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
        rmeth = Optimizer.optimize(rmeth, BaseDumper.computeParamWidth(meth, isStatic), isStatic, true, advice);
    }
    System.out.println("digraph " + name + "{");
    System.out.println("\tfirst -> n" + Hex.u2(rmeth.getFirstLabel()) + ";");
    BasicBlockList blocks = rmeth.getBlocks();
    int sz = blocks.size();
    for (int i = 0; i < sz; i++) {
        BasicBlock bb = blocks.get(i);
        int label = bb.getLabel();
        IntList successors = bb.getSuccessors();
        if (successors.size() == 0) {
            System.out.println("\tn" + Hex.u2(label) + " -> returns;");
        } else if (successors.size() == 1) {
            System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(successors.get(0)) + ";");
        } else {
            System.out.print("\tn" + Hex.u2(label) + " -> {");
            for (int j = 0; j < successors.size(); j++) {
                int successor = successors.get(j);
                if (successor != bb.getPrimarySuccessor()) {
                    System.out.print(" n" + Hex.u2(successor) + " ");
                }
            }
            System.out.println("};");
            System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(bb.getPrimarySuccessor()) + " [label=\"primary\"];");
        }
    }
    System.out.println("}");
}
Also used : RopMethod(com.android.dx.rop.code.RopMethod) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) BasicBlock(com.android.dx.rop.code.BasicBlock) DexTranslationAdvice(com.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.android.dx.rop.code.TranslationAdvice) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) RopMethod(com.android.dx.rop.code.RopMethod) Method(com.android.dx.cf.iface.Method) BasicBlockList(com.android.dx.rop.code.BasicBlockList) IntList(com.android.dx.util.IntList)

Example 4 with Method

use of com.android.dx.cf.iface.Method in project buck by facebook.

the class SsaDumper method endParsingMember.

/** {@inheritDoc} */
@Override
public void endParsingMember(ByteArray bytes, int offset, String name, String descriptor, Member member) {
    if (!(member instanceof Method)) {
        return;
    }
    if (!shouldDumpMethod(name)) {
        return;
    }
    if ((member.getAccessFlags() & (AccessFlags.ACC_ABSTRACT | AccessFlags.ACC_NATIVE)) != 0) {
        return;
    }
    ConcreteMethod meth = new ConcreteMethod((Method) member, classFile, true, true);
    TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
    RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());
    SsaMethod ssaMeth = null;
    boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
    int paramWidth = computeParamWidth(meth, isStatic);
    if (args.ssaStep == null) {
        ssaMeth = Optimizer.debugNoRegisterAllocation(rmeth, paramWidth, isStatic, true, advice, EnumSet.allOf(Optimizer.OptionalStep.class));
    } else if ("edge-split".equals(args.ssaStep)) {
        ssaMeth = Optimizer.debugEdgeSplit(rmeth, paramWidth, isStatic, true, advice);
    } else if ("phi-placement".equals(args.ssaStep)) {
        ssaMeth = Optimizer.debugPhiPlacement(rmeth, paramWidth, isStatic, true, advice);
    } else if ("renaming".equals(args.ssaStep)) {
        ssaMeth = Optimizer.debugRenaming(rmeth, paramWidth, isStatic, true, advice);
    } else if ("dead-code".equals(args.ssaStep)) {
        ssaMeth = Optimizer.debugDeadCodeRemover(rmeth, paramWidth, isStatic, true, advice);
    }
    StringBuffer sb = new StringBuffer(2000);
    sb.append("first ");
    sb.append(Hex.u2(ssaMeth.blockIndexToRopLabel(ssaMeth.getEntryBlockIndex())));
    sb.append('\n');
    ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
    ArrayList<SsaBasicBlock> sortedBlocks = (ArrayList<SsaBasicBlock>) blocks.clone();
    Collections.sort(sortedBlocks, SsaBasicBlock.LABEL_COMPARATOR);
    for (SsaBasicBlock block : sortedBlocks) {
        sb.append("block ").append(Hex.u2(block.getRopLabel())).append('\n');
        BitSet preds = block.getPredecessors();
        for (int i = preds.nextSetBit(0); i >= 0; i = preds.nextSetBit(i + 1)) {
            sb.append("  pred ");
            sb.append(Hex.u2(ssaMeth.blockIndexToRopLabel(i)));
            sb.append('\n');
        }
        sb.append("  live in:" + block.getLiveInRegs());
        sb.append("\n");
        for (SsaInsn insn : block.getInsns()) {
            sb.append("  ");
            sb.append(insn.toHuman());
            sb.append('\n');
        }
        if (block.getSuccessors().cardinality() == 0) {
            sb.append("  returns\n");
        } else {
            int primary = block.getPrimarySuccessorRopLabel();
            IntList succLabelList = block.getRopLabelSuccessorList();
            int szSuccLabels = succLabelList.size();
            for (int i = 0; i < szSuccLabels; i++) {
                sb.append("  next ");
                sb.append(Hex.u2(succLabelList.get(i)));
                if (szSuccLabels != 1 && primary == succLabelList.get(i)) {
                    sb.append(" *");
                }
                sb.append('\n');
            }
        }
        sb.append("  live out:" + block.getLiveOutRegs());
        sb.append("\n");
    }
    suppressDump = false;
    setAt(bytes, 0);
    parsed(bytes, 0, bytes.size(), sb.toString());
    suppressDump = true;
}
Also used : RopMethod(com.android.dx.rop.code.RopMethod) Optimizer(com.android.dx.ssa.Optimizer) SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) ArrayList(java.util.ArrayList) BitSet(java.util.BitSet) DexTranslationAdvice(com.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.android.dx.rop.code.TranslationAdvice) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) RopMethod(com.android.dx.rop.code.RopMethod) SsaMethod(com.android.dx.ssa.SsaMethod) Method(com.android.dx.cf.iface.Method) IntList(com.android.dx.util.IntList) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) SsaMethod(com.android.dx.ssa.SsaMethod) SsaInsn(com.android.dx.ssa.SsaInsn)

Aggregations

Method (com.android.dx.cf.iface.Method)4 ConcreteMethod (com.android.dx.cf.code.ConcreteMethod)3 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)3 RopMethod (com.android.dx.rop.code.RopMethod)3 TranslationAdvice (com.android.dx.rop.code.TranslationAdvice)3 MethodList (com.android.dx.cf.iface.MethodList)2 CstType (com.android.dx.rop.cst.CstType)2 IntList (com.android.dx.util.IntList)2 AttAnnotationDefault (com.android.dx.cf.attrib.AttAnnotationDefault)1 AttEnclosingMethod (com.android.dx.cf.attrib.AttEnclosingMethod)1 AttributeList (com.android.dx.cf.iface.AttributeList)1 DalvCode (com.android.dx.dex.code.DalvCode)1 EncodedMethod (com.android.dx.dex.file.EncodedMethod)1 Annotation (com.android.dx.rop.annotation.Annotation)1 Annotations (com.android.dx.rop.annotation.Annotations)1 AnnotationsList (com.android.dx.rop.annotation.AnnotationsList)1 NameValuePair (com.android.dx.rop.annotation.NameValuePair)1 BasicBlock (com.android.dx.rop.code.BasicBlock)1 BasicBlockList (com.android.dx.rop.code.BasicBlockList)1 LocalVariableInfo (com.android.dx.rop.code.LocalVariableInfo)1