Search in sources :

Example 1 with AttCode

use of com.android.dx.cf.attrib.AttCode in project buck by facebook.

the class StdAttributeFactory method code.

/**
     * Parses a {@code Code} attribute.
     */
private Attribute code(DirectClassFile cf, int offset, int length, ParseObserver observer) {
    if (length < 12) {
        return throwSeverelyTruncated();
    }
    ByteArray bytes = cf.getBytes();
    ConstantPool pool = cf.getConstantPool();
    // u2 max_stack
    int maxStack = bytes.getUnsignedShort(offset);
    // u2 max_locals
    int maxLocals = bytes.getUnsignedShort(offset + 2);
    // u4 code_length
    int codeLength = bytes.getInt(offset + 4);
    int origOffset = offset;
    if (observer != null) {
        observer.parsed(bytes, offset, 2, "max_stack: " + Hex.u2(maxStack));
        observer.parsed(bytes, offset + 2, 2, "max_locals: " + Hex.u2(maxLocals));
        observer.parsed(bytes, offset + 4, 4, "code_length: " + Hex.u4(codeLength));
    }
    offset += 8;
    length -= 8;
    if (length < (codeLength + 4)) {
        return throwTruncated();
    }
    int codeOffset = offset;
    offset += codeLength;
    length -= codeLength;
    BytecodeArray code = new BytecodeArray(bytes.slice(codeOffset, codeOffset + codeLength), pool);
    if (observer != null) {
        code.forEach(new CodeObserver(code.getBytes(), observer));
    }
    // u2 exception_table_length
    int exceptionTableLength = bytes.getUnsignedShort(offset);
    ByteCatchList catches = (exceptionTableLength == 0) ? ByteCatchList.EMPTY : new ByteCatchList(exceptionTableLength);
    if (observer != null) {
        observer.parsed(bytes, offset, 2, "exception_table_length: " + Hex.u2(exceptionTableLength));
    }
    offset += 2;
    length -= 2;
    if (length < (exceptionTableLength * 8 + 2)) {
        return throwTruncated();
    }
    for (int i = 0; i < exceptionTableLength; i++) {
        if (observer != null) {
            observer.changeIndent(1);
        }
        int startPc = bytes.getUnsignedShort(offset);
        int endPc = bytes.getUnsignedShort(offset + 2);
        int handlerPc = bytes.getUnsignedShort(offset + 4);
        int catchTypeIdx = bytes.getUnsignedShort(offset + 6);
        CstType catchType = (CstType) pool.get0Ok(catchTypeIdx);
        catches.set(i, startPc, endPc, handlerPc, catchType);
        if (observer != null) {
            observer.parsed(bytes, offset, 8, Hex.u2(startPc) + ".." + Hex.u2(endPc) + " -> " + Hex.u2(handlerPc) + " " + ((catchType == null) ? "<any>" : catchType.toHuman()));
        }
        offset += 8;
        length -= 8;
        if (observer != null) {
            observer.changeIndent(-1);
        }
    }
    catches.setImmutable();
    AttributeListParser parser = new AttributeListParser(cf, CTX_CODE, offset, this);
    parser.setObserver(observer);
    StdAttributeList attributes = parser.getList();
    attributes.setImmutable();
    int attributeByteCount = parser.getEndOffset() - offset;
    if (attributeByteCount != length) {
        return throwBadLength(attributeByteCount + (offset - origOffset));
    }
    return new AttCode(maxStack, maxLocals, code, catches, attributes);
}
Also used : BytecodeArray(com.android.dx.cf.code.BytecodeArray) StdAttributeList(com.android.dx.cf.iface.StdAttributeList) ByteCatchList(com.android.dx.cf.code.ByteCatchList) ConstantPool(com.android.dx.rop.cst.ConstantPool) CstType(com.android.dx.rop.cst.CstType) AttCode(com.android.dx.cf.attrib.AttCode) ByteArray(com.android.dx.util.ByteArray)

Aggregations

AttCode (com.android.dx.cf.attrib.AttCode)1 ByteCatchList (com.android.dx.cf.code.ByteCatchList)1 BytecodeArray (com.android.dx.cf.code.BytecodeArray)1 StdAttributeList (com.android.dx.cf.iface.StdAttributeList)1 ConstantPool (com.android.dx.rop.cst.ConstantPool)1 CstType (com.android.dx.rop.cst.CstType)1 ByteArray (com.android.dx.util.ByteArray)1