Package com.android.dx.cf.code
Class BytecodeArray
java.lang.Object
com.android.dx.cf.code.BytecodeArray
Bytecode array, which is part of a standard
Code
attribute.-
Nested Class Summary
Modifier and TypeClassDescriptionstatic class
Base implementation ofBytecodeArray.Visitor
, which has empty method bodies for all methods.static interface
Instruction visitor interface. -
Field Summary
Modifier and TypeFieldDescriptionstatic final BytecodeArray.Visitor
convenient no-op implementation ofBytecodeArray.Visitor
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionint
Gets the total length of this structure in bytes, when included in aCode
attribute.void
forEach
(BytecodeArray.Visitor visitor) Parses each instruction in the array, in order.getBytes()
Gets the underlying byte array.int[]
Finds the offset to each instruction in the bytecode array.int
parseInstruction
(int offset, BytecodeArray.Visitor visitor) Parses the instruction at the indicated offset.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.int
size()
Gets the size of the bytecode array, per se.
-
Field Details
-
EMPTY_VISITOR
convenient no-op implementation ofBytecodeArray.Visitor
-
-
Constructor Details
-
BytecodeArray
Constructs an instance.- Parameters:
bytes
-non-null;
underlying bytespool
-non-null;
constant pool to use when resolving constant pool indices
-
-
Method Details
-
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 aCode
attribute. The returned value includes the array size plus four bytes forcode_length
.- Returns:
>= 4;
the total length, in bytes
-
forEach
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
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 processvisitor
-non-null;
visitor to call back to for each instruction
-
parseInstruction
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
, andlconst_0
qualify for this treatment. aconst_null
becomesldc
of a "known null."- Shorthand local variable accessors become the corresponding
longhand. E.g.
aload_2
becomesaload
. goto_w
andjsr_w
becomegoto
andjsr
(respectively).ldc_w
becomesldc
.tableswitch
becomeslookupswitch
.- Arithmetic, array, and value-returning ops are collapsed
to the
int
variant opcode, with thetype
argument set to indicate the actual type. E.g.,fadd
becomesiadd
, buttype
is passed asType.FLOAT
in that case. Similarly,areturn
becomesireturn
. (However,return
remains unchanged. - Local variable access ops are collapsed to the
int
variant opcode, with thetype
argument set to indicate the actual type. E.g.,aload
becomesiload
, buttype
is passed asType.OBJECT
in that case. - Numeric conversion ops (
i2l
, etc.) are left alone to avoid too much confustion, but theirtype
is the pushed type. E.g.,i2b
gets typeType.INT
, andf2d
gets typeType.DOUBLE
. Other unaltered opcodes also get their pushed type. E.g.,arraylength
gets typeType.INT
.
- Parameters:
offset
->= 0, < bytes.size();
offset to the start of the instructionvisitor
-null-ok;
visitor to call back to- Returns:
- the length of the instruction, in bytes
- The opcodes to push literal constants of primitive types all become
-