FileDocCategorySizeDatePackage
ArrayData.javaAPI DocAndroid 5.1 API6129Thu Mar 12 22:18:28 GMT 2015com.android.dexgen.dex.code

ArrayData

public final class ArrayData extends VariableSizeInsn
Pseudo-instruction which holds fill array data.

Fields Summary
private final CodeAddress
user
{@code non-null;} address representing the instruction that uses this instance
private final ArrayList
values
{@code non-null;} initial values to be filled into an array
private final Constant
arrayType
non-null: type of constant that initializes the array
private final int
elemWidth
Width of the init value element
private final int
initLength
Length of the init list
Constructors Summary
public ArrayData(com.android.dexgen.rop.code.SourcePosition position, CodeAddress user, ArrayList values, Constant arrayType)
Constructs an instance. The output address of this instance is initially unknown ({@code -1}).

param
position {@code non-null;} source position
param
user {@code non-null;} address representing the instruction that uses this instance
param
values {@code non-null;} initial values to be filled into an array

        super(position, RegisterSpecList.EMPTY);

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

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

        int sz = values.size();

        if (sz <= 0) {
            throw new IllegalArgumentException("Illegal number of init values");
        }

        this.arrayType = arrayType;

        if (arrayType == CstType.BYTE_ARRAY ||
                arrayType == CstType.BOOLEAN_ARRAY) {
            elemWidth = 1;
        } else if (arrayType == CstType.SHORT_ARRAY ||
                arrayType == CstType.CHAR_ARRAY) {
            elemWidth = 2;
        } else if (arrayType == CstType.INT_ARRAY ||
                arrayType == CstType.FLOAT_ARRAY) {
            elemWidth = 4;
        } else if (arrayType == CstType.LONG_ARRAY ||
                arrayType == CstType.DOUBLE_ARRAY) {
            elemWidth = 8;
        } else {
            throw new IllegalArgumentException("Unexpected constant type");
        }
        this.user = user;
        this.values = values;
        initLength = values.size();
    
Methods Summary
protected java.lang.StringargString()
{@inheritDoc}

        StringBuffer sb = new StringBuffer(100);

        int sz = values.size();
        for (int i = 0; i < sz; i++) {
            sb.append("\n    ");
            sb.append(i);
            sb.append(": ");
            sb.append(values.get(i).toHuman());
        }

        return sb.toString();
    
public intcodeSize()
{@inheritDoc}

        int sz = initLength;
        // Note: the unit here is 16-bit
        return 4 + ((sz * elemWidth) + 1) / 2;
    
protected java.lang.StringlistingString0(boolean noteIndices)
{@inheritDoc}

        int baseAddress = user.getAddress();
        StringBuffer sb = new StringBuffer(100);
        int sz = values.size();

        sb.append("array-data // for fill-array-data @ ");
        sb.append(Hex.u2(baseAddress));

        for (int i = 0; i < sz; i++) {
            sb.append("\n  ");
            sb.append(i);
            sb.append(": ");
            sb.append(values.get(i).toHuman());
        }

        return sb.toString();
    
public DalvInsnwithRegisters(com.android.dexgen.rop.code.RegisterSpecList registers)
{@inheritDoc}

        return new ArrayData(getPosition(), user, values, arrayType);
    
public voidwriteTo(com.android.dexgen.util.AnnotatedOutput out)
{@inheritDoc}

        int sz = values.size();

        out.writeShort(0x300 | DalvOps.NOP);
        out.writeShort(elemWidth);
        out.writeInt(initLength);


        // For speed reasons, replicate the for loop in each case
        switch (elemWidth) {
            case 1: {
                for (int i = 0; i < sz; i++) {
                    Constant cst = values.get(i);
                    out.writeByte((byte) ((CstLiteral32) cst).getIntBits());
                }
                break;
            }
            case 2: {
                for (int i = 0; i < sz; i++) {
                    Constant cst = values.get(i);
                    out.writeShort((short) ((CstLiteral32) cst).getIntBits());
                }
                break;
            }
            case 4: {
                for (int i = 0; i < sz; i++) {
                    Constant cst = values.get(i);
                    out.writeInt(((CstLiteral32) cst).getIntBits());
                }
                break;
            }
            case 8: {
                for (int i = 0; i < sz; i++) {
                    Constant cst = values.get(i);
                    out.writeLong(((CstLiteral64) cst).getLongBits());
                }
                break;
            }
            default:
                break;
        }

        // Pad one byte to make the size of data table multiples of 16-bits
        if (elemWidth == 1 && (sz % 2 != 0)) {
            out.writeByte(0x00);
        }