FileDocCategorySizeDatePackage
CodeItem.javaAPI DocAndroid 5.1 API9890Thu Mar 12 22:18:30 GMT 2015com.android.dx.dex.file

CodeItem

public final class CodeItem extends OffsettedItem
Representation of all the parts needed for concrete methods in a {@code dex} file.

Fields Summary
private static final int
ALIGNMENT
file alignment of this class, in bytes
private static final int
HEADER_SIZE
write size of the header of this class, in bytes
private final com.android.dx.rop.cst.CstMethodRef
ref
{@code non-null;} method that this code implements
private final com.android.dx.dex.code.DalvCode
code
{@code non-null;} the bytecode instructions and associated data
private CatchStructs
catches
{@code null-ok;} the catches, if needed; set in {@link #addContents}
private final boolean
isStatic
whether this instance is for a {@code static} method
private final com.android.dx.rop.type.TypeList
throwsList
{@code non-null;} list of possibly-thrown exceptions; just used in generating debugging output (listings)
private DebugInfoItem
debugInfo
{@code null-ok;} the debug info or {@code null} if there is none; set in {@link #addContents}
Constructors Summary
public CodeItem(com.android.dx.rop.cst.CstMethodRef ref, com.android.dx.dex.code.DalvCode code, boolean isStatic, com.android.dx.rop.type.TypeList throwsList)
Constructs an instance.

param
ref {@code non-null;} method that this code implements
param
code {@code non-null;} the underlying code
param
isStatic whether this instance is for a {@code static} method
param
throwsList {@code non-null;} list of possibly-thrown exceptions, just used in generating debugging output (listings)


                                                      
          
              
        super(ALIGNMENT, -1);

        if (ref == null) {
            throw new NullPointerException("ref == null");
        }

        if (code == null) {
            throw new NullPointerException("code == null");
        }

        if (throwsList == null) {
            throw new NullPointerException("throwsList == null");
        }

        this.ref = ref;
        this.code = code;
        this.isStatic = isStatic;
        this.throwsList = throwsList;
        this.catches = null;
        this.debugInfo = null;
    
Methods Summary
public voidaddContents(DexFile file)
{@inheritDoc}

        MixedItemSection byteData = file.getByteData();
        TypeIdsSection typeIds = file.getTypeIds();

        if (code.hasPositions() || code.hasLocals()) {
            debugInfo = new DebugInfoItem(code, isStatic, ref);
            byteData.add(debugInfo);
        }

        if (code.hasAnyCatches()) {
            for (Type type : code.getCatchTypes()) {
                typeIds.intern(type);
            }
            catches = new CatchStructs(code);
        }

        for (Constant c : code.getInsnConstants()) {
            file.internIfAppropriate(c);
        }
    
public voiddebugPrint(java.io.PrintWriter out, java.lang.String prefix, boolean verbose)
Does a human-friendly dump of this instance.

param
out {@code non-null;} where to dump
param
prefix {@code non-null;} per-line prefix to use
param
verbose whether to be verbose with the output

        out.println(ref.toHuman() + ":");

        DalvInsnList insns = code.getInsns();
        out.println("regs: " + Hex.u2(getRegistersSize()) +
                "; ins: " + Hex.u2(getInsSize()) + "; outs: " +
                Hex.u2(getOutsSize()));

        insns.debugPrint(out, prefix, verbose);

        String prefix2 = prefix + "  ";

        if (catches != null) {
            out.print(prefix);
            out.println("catches");
            catches.debugPrint(out, prefix2);
        }

        if (debugInfo != null) {
            out.print(prefix);
            out.println("debug info");
            debugInfo.debugPrint(out, prefix2);
        }
    
private intgetInsSize()
Get the in registers count.

return
the count

        return ref.getParameterWordCount(isStatic);
    
private intgetOutsSize()
Get the out registers count.

return
the count

        return code.getInsns().getOutsSize();
    
public com.android.dx.rop.cst.CstMethodRefgetRef()
Gets the reference to the method this instance implements.

return
{@code non-null;} the method reference

        return ref;
    
private intgetRegistersSize()
Get the total registers count.

return
the count

        return code.getInsns().getRegistersSize();
    
public ItemTypeitemType()
{@inheritDoc}

        return ItemType.TYPE_CODE_ITEM;
    
protected voidplace0(Section addedTo, int offset)
{@inheritDoc}

        final DexFile file = addedTo.getFile();
        int catchesSize;

        /*
         * In order to get the catches and insns, all the code's
         * constants need to be assigned indices.
         */
        code.assignIndices(new DalvCode.AssignIndicesCallback() {
                public int getIndex(Constant cst) {
                    IndexedItem item = file.findItemOrNull(cst);
                    if (item == null) {
                        return -1;
                    }
                    return item.getIndex();
                }
            });

        if (catches != null) {
            catches.encode(file);
            catchesSize = catches.writeSize();
        } else {
            catchesSize = 0;
        }

        /*
         * The write size includes the header, two bytes per code
         * unit, post-code padding if necessary, and however much
         * space the catches need.
         */

        int insnsSize = code.getInsns().codeSize();
        if ((insnsSize & 1) != 0) {
            insnsSize++;
        }

        setWriteSize(HEADER_SIZE + (insnsSize * 2) + catchesSize);
    
public java.lang.StringtoHuman()
{@inheritDoc}

        return ref.toHuman();
    
public java.lang.StringtoString()
{@inheritDoc}

        return "CodeItem{" + toHuman() + "}";
    
private voidwriteCodes(DexFile file, com.android.dx.util.AnnotatedOutput out)
Helper for {@link #writeTo0} which writes out the actual bytecode.

param
file {@code non-null;} file we are part of
param
out {@code non-null;} where to write to

        DalvInsnList insns = code.getInsns();

        try {
            insns.writeTo(out);
        } catch (RuntimeException ex) {
            throw ExceptionWithContext.withContext(ex, "...while writing " +
                    "instructions for " + ref.toHuman());
        }
    
protected voidwriteTo0(DexFile file, com.android.dx.util.AnnotatedOutput out)
{@inheritDoc}

        boolean annotates = out.annotates();
        int regSz = getRegistersSize();
        int outsSz = getOutsSize();
        int insSz = getInsSize();
        int insnsSz = code.getInsns().codeSize();
        boolean needPadding = (insnsSz & 1) != 0;
        int triesSz = (catches == null) ? 0 : catches.triesSize();
        int debugOff = (debugInfo == null) ? 0 : debugInfo.getAbsoluteOffset();

        if (annotates) {
            out.annotate(0, offsetString() + ' " + ref.toHuman());
            out.annotate(2, "  registers_size: " + Hex.u2(regSz));
            out.annotate(2, "  ins_size:       " + Hex.u2(insSz));
            out.annotate(2, "  outs_size:      " + Hex.u2(outsSz));
            out.annotate(2, "  tries_size:     " + Hex.u2(triesSz));
            out.annotate(4, "  debug_off:      " + Hex.u4(debugOff));
            out.annotate(4, "  insns_size:     " + Hex.u4(insnsSz));

            // This isn't represented directly here, but it is useful to see.
            int size = throwsList.size();
            if (size != 0) {
                out.annotate(0, "  throws " + StdTypeList.toHuman(throwsList));
            }
        }

        out.writeShort(regSz);
        out.writeShort(insSz);
        out.writeShort(outsSz);
        out.writeShort(triesSz);
        out.writeInt(debugOff);
        out.writeInt(insnsSz);

        writeCodes(file, out);

        if (catches != null) {
            if (needPadding) {
                if (annotates) {
                    out.annotate(2, "  padding: 0");
                }
                out.writeShort(0);
            }

            catches.writeTo(file, out);
        }

        if (annotates) {
            /*
             * These are pointed at in the code header (above), but it's less
             * distracting to expand on them at the bottom of the code.
             */
            if (debugInfo != null) {
                out.annotate(0, "  debug info");
                debugInfo.annotateTo(file, out, "    ");
            }
        }