Class BytecodeArray

java.lang.Object
com.android.dx.cf.code.BytecodeArray

public final class BytecodeArray extends Object
Bytecode array, which is part of a standard Code attribute.
  • Field Details

  • Constructor Details

    • BytecodeArray

      public BytecodeArray(ByteArray bytes, ConstantPool pool)
      Constructs an instance.
      Parameters:
      bytes - non-null; underlying bytes
      pool - non-null; constant pool to use when resolving constant pool indices
  • Method Details

    • getBytes

      public ByteArray getBytes()
      Gets the underlying byte array.
      Returns:
      non-null; the byte array
    • size

      public int size()
      Gets the size of the bytecode array, per se.
      Returns:
      >= 0; the length of the bytecode array
    • byteLength

      public int byteLength()
      Gets the total length of this structure in bytes, when included in a Code attribute. The returned value includes the array size plus four bytes for code_length.
      Returns:
      >= 4; the total length, in bytes
    • forEach

      public void forEach(BytecodeArray.Visitor visitor)
      Parses each instruction in the array, in order.
      Parameters:
      visitor - null-ok; visitor to call back to for each instruction
    • getInstructionOffsets

      public int[] getInstructionOffsets()
      Finds the offset to each instruction in the bytecode array. The result is a bit set with the offset of each opcode-per-se flipped on.
      Returns:
      non-null; appropriately constructed bit set
      See Also:
    • processWorkSet

      public void processWorkSet(int[] workSet, BytecodeArray.Visitor visitor)
      Processes the given "work set" by repeatedly finding the lowest bit in the set, clearing it, and parsing and visiting the instruction at the indicated offset (that is, the bit index), repeating until the work set is empty. It is expected that the visitor will regularly set new bits in the work set during the process.
      Parameters:
      workSet - non-null; the work set to process
      visitor - non-null; visitor to call back to for each instruction
    • parseInstruction

      public int parseInstruction(int offset, BytecodeArray.Visitor visitor)
      Parses the instruction at the indicated offset. Indicate the result by calling the visitor if supplied and by returning the number of bytes consumed by the instruction.

      In order to simplify further processing, the opcodes passed to the visitor are canonicalized, altering the opcode to a more universal one and making formerly implicit arguments explicit. In particular:

      • The opcodes to push literal constants of primitive types all become ldc. E.g., fconst_0, sipush, and lconst_0 qualify for this treatment.
      • aconst_null becomes ldc of a "known null."
      • Shorthand local variable accessors become the corresponding longhand. E.g. aload_2 becomes aload.
      • goto_w and jsr_w become goto and jsr (respectively).
      • ldc_w becomes ldc.
      • tableswitch becomes lookupswitch.
      • Arithmetic, array, and value-returning ops are collapsed to the int variant opcode, with the type argument set to indicate the actual type. E.g., fadd becomes iadd, but type is passed as Type.FLOAT in that case. Similarly, areturn becomes ireturn. (However, return remains unchanged.
      • Local variable access ops are collapsed to the int variant opcode, with the type argument set to indicate the actual type. E.g., aload becomes iload, but type is passed as Type.OBJECT in that case.
      • Numeric conversion ops (i2l, etc.) are left alone to avoid too much confustion, but their type is the pushed type. E.g., i2b gets type Type.INT, and f2d gets type Type.DOUBLE. Other unaltered opcodes also get their pushed type. E.g., arraylength gets type Type.INT.
      Parameters:
      offset - >= 0, < bytes.size(); offset to the start of the instruction
      visitor - null-ok; visitor to call back to
      Returns:
      the length of the instruction, in bytes