Class CodeIterator
- All Implemented Interfaces:
Opcode
To directly read or edit a bytecode sequence, call byteAt(int)
, s16bitAt(int)
,
writeByte(int, int)
, write16bit(int, int)
, and other methods.
For example, if method
refers to a CtMethod
object,
the following code substitutes the NOP
instruction for the first
instruction of the method:
CodeAttribute ca = method.getMethodInfo().getCodeAttribute(); CodeIterator ci = ca.iterator(); ci.writeByte(Opcode.NOP, 0);
To visit every instruction, call next()
on a CodeIterator
.
It returns the index of the first byte of the next instruction.
If there are multiple CodeIterator
s referring to the
same Code_attribute
, then inserting a gap by one
CodeIterator
will break the other
CodeIterator
.
This iterator does not provide remove()
.
If a piece of code in a Code_attribute
is unnecessary,
it should be overwritten with NOP
.
- See Also:
-
Nested Class Summary
-
Field Summary
Fields inherited from interface javassist.bytecode.Opcode
AALOAD, AASTORE, ACONST_NULL, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARETURN, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, ATHROW, BALOAD, BASTORE, BIPUSH, CALOAD, CASTORE, CHECKCAST, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DNEG, DREM, DRETURN, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FNEG, FREM, FRETURN, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, GOTO, GOTO_W, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INEG, INSTANCEOF, INVOKEDYNAMIC, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, JSR, JSR_W, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDC_W, LDC2_W, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LNEG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, NEW, NEWARRAY, NOP, POP, POP2, PUTFIELD, PUTSTATIC, RET, RETURN, SALOAD, SASTORE, SIPUSH, STACK_GROW, SWAP, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, TABLESWITCH, WIDE
-
Method Summary
Modifier and TypeMethodDescriptionint
append
(byte[] code) Appends the given bytecode sequence at the end.void
append
(ExceptionTable et, int offset) Copies and appends the entries in the given exception table at the end of the exception table in the code attribute edited by this object.void
appendGap
(int gapLength) Appends a gap at the end of the bytecode sequence.void
begin()
Moves to the first instruction.int
byteAt
(int index) Returns the unsigned 8bit value at the given index.get()
Returns a Code attribute read with this iterator.int
Returnscode_length
ofCode_attribute
.int
getMark()
Gets the index of the position of the mark set bysetMark
.int
getMark2()
Gets the index of the position of the mark set bysetMark2
.boolean
hasNext()
Returns true if there is more instructions.int
insert
(byte[] code) Inserts the given bytecode sequence before the next instruction that would be returned bynext()
(not before the instruction returned by the last call tonext()
).void
insert
(int pos, byte[] code) Inserts the given bytecode sequence before the instruction at the given indexpos
.void
insert
(ExceptionTable et, int offset) Copies and inserts the entries in the given exception table at the beginning of the exception table in the code attribute edited by this object.int
insertAt
(int pos, byte[] code) Inserts the given bytecode sequence before the instruction at the given indexpos
.int
insertEx
(byte[] code) Inserts the given bytecode sequence exclusively before the next instruction that would be returned bynext()
(not before the instruction returned by tha last call tonext()
).void
insertEx
(int pos, byte[] code) Inserts the given bytecode sequence exclusively before the instruction at the given indexpos
.int
insertExAt
(int pos, byte[] code) Inserts the given bytecode sequence exclusively before the instruction at the given indexpos
.int
insertExGap
(int length) Inserts an exclusive gap before the next instruction that would be returned bynext()
(not before the instruction returned by the last call tonext()
).int
insertExGap
(int pos, int length) Inserts an exclusive gap in front of the instruction at the given indexpos
.int
insertGap
(int length) Inserts a gap before the next instruction that would be returned bynext()
(not before the instruction returned by the last call tonext()
).int
insertGap
(int pos, int length) Inserts a gap in front of the instruction at the given indexpos
.insertGapAt
(int pos, int length, boolean exclusive) Inserts an inclusive or exclusive gap in front of the instruction at the given indexpos
.int
Obtains the value that the next call tonext()
will return.void
move
(int index) Moves to the given index.int
next()
Returns the index of the next instruction (not the operand following the current opcode).int
s16bitAt
(int index) Returns the signed 16bit value at the given index.int
s32bitAt
(int index) Returns the signed 32bit value at the given index.void
setMark
(int index) Sets a mark to the bytecode at the given index.void
setMark2
(int index) Sets a mark to the bytecode at the given index.int
signedByteAt
(int index) Returns the signed 8bit value at the given index.int
Moves to the instruction for eithersuper()
orthis()
.int
Moves to the instruction forsuper()
.int
Moves to the instruction forthis()
.int
u16bitAt
(int index) Returns the unsigned 16bit value at the given index.void
write
(byte[] code, int index) Writes a byte array at the index.void
write16bit
(int value, int index) Writes a 16 bit integer at the index.void
write32bit
(int value, int index) Writes a 32bit integer at the index.void
writeByte
(int value, int index) Writes an 8bit value at the given index.
-
Method Details
-
begin
public void begin()Moves to the first instruction. -
move
public void move(int index) Moves to the given index.The index of the next instruction is set to the given index. The successive call to
next()
returns the index that has been given tomove()
.Note that the index is into the byte array returned by
get().getCode()
.- See Also:
-
setMark
public void setMark(int index) Sets a mark to the bytecode at the given index. The mark can be used to track the position of that bytecode when code blocks are inserted. If a code block is inclusively inserted at the position of the bytecode, the mark is set to the inserted code block.- Since:
- 3.11
- See Also:
-
setMark2
public void setMark2(int index) Sets a mark to the bytecode at the given index. The mark can be used to track the position of that bytecode when code blocks are inserted. If a code block is inclusively inserted at the position of the bytecode, the mark is set to the inserted code block.- Since:
- 3.26
- See Also:
-
getMark
public int getMark()Gets the index of the position of the mark set bysetMark
.- Returns:
- the index of the position.
- Since:
- 3.11
- See Also:
-
getMark2
public int getMark2()Gets the index of the position of the mark set bysetMark2
.- Returns:
- the index of the position.
- Since:
- 3.26
- See Also:
-
get
Returns a Code attribute read with this iterator. -
getCodeLength
public int getCodeLength()Returnscode_length
ofCode_attribute
. -
byteAt
public int byteAt(int index) Returns the unsigned 8bit value at the given index. -
signedByteAt
public int signedByteAt(int index) Returns the signed 8bit value at the given index. -
writeByte
public void writeByte(int value, int index) Writes an 8bit value at the given index. -
u16bitAt
public int u16bitAt(int index) Returns the unsigned 16bit value at the given index. -
s16bitAt
public int s16bitAt(int index) Returns the signed 16bit value at the given index. -
write16bit
public void write16bit(int value, int index) Writes a 16 bit integer at the index. -
s32bitAt
public int s32bitAt(int index) Returns the signed 32bit value at the given index. -
write32bit
public void write32bit(int value, int index) Writes a 32bit integer at the index. -
write
public void write(byte[] code, int index) Writes a byte array at the index.- Parameters:
code
- may be a zero-length array.
-
hasNext
public boolean hasNext()Returns true if there is more instructions. -
next
Returns the index of the next instruction (not the operand following the current opcode).Note that the index is into the byte array returned by
get().getCode()
.- Throws:
BadBytecode
- See Also:
-
lookAhead
public int lookAhead()Obtains the value that the next call tonext()
will return.This method is side-effects free. Successive calls to
lookAhead()
return the same value untilnext()
is called. -
skipConstructor
Moves to the instruction for eithersuper()
orthis()
.This method skips all the instructions for computing arguments to
super()
orthis()
, which should be placed at the beginning of a constructor body.This method returns the index of INVOKESPECIAL instruction executing
super()
orthis()
. A successive call tonext()
returns the index of the next instruction following that INVOKESPECIAL.This method works only for a constructor.
- Returns:
- the index of the INVOKESPECIAL instruction, or -1 if a constructor invocation is not found.
- Throws:
BadBytecode
-
skipSuperConstructor
Moves to the instruction forsuper()
.This method skips all the instructions for computing arguments to
super()
, which should be placed at the beginning of a constructor body.This method returns the index of INVOKESPECIAL instruction executing
super()
. A successive call tonext()
returns the index of the next instruction following that INVOKESPECIAL.This method works only for a constructor.
- Returns:
- the index of the INVOKESPECIAL instruction, or -1
if a super constructor invocation is not found
but
this()
is found. - Throws:
BadBytecode
-
skipThisConstructor
Moves to the instruction forthis()
.This method skips all the instructions for computing arguments to
this()
, which should be placed at the beginning of a constructor body.This method returns the index of INVOKESPECIAL instruction executing
this()
. A successive call tonext()
returns the index of the next instruction following that INVOKESPECIAL.This method works only for a constructor.
- Returns:
- the index of the INVOKESPECIAL instruction, or -1
if a explicit constructor invocation is not found
but
super()
is found. - Throws:
BadBytecode
-
insert
Inserts the given bytecode sequence before the next instruction that would be returned bynext()
(not before the instruction returned by the last call tonext()
). Branch offsets and the exception table are also updated.If the next instruction is at the beginning of a block statement, then the bytecode is inserted within that block.
An extra gap may be inserted at the end of the inserted bytecode sequence for adjusting alignment if the code attribute includes
LOOKUPSWITCH
orTABLESWITCH
.- Parameters:
code
- inserted bytecode sequence.- Returns:
- the index indicating the first byte of the inserted byte sequence.
- Throws:
BadBytecode
-
insert
Inserts the given bytecode sequence before the instruction at the given indexpos
. Branch offsets and the exception table are also updated.If the instruction at the given index is at the beginning of a block statement, then the bytecode is inserted within that block.
An extra gap may be inserted at the end of the inserted bytecode sequence for adjusting alignment if the code attribute includes
LOOKUPSWITCH
orTABLESWITCH
.The index at which the byte sequence is actually inserted might be different from pos since some other bytes might be inserted at other positions (e.g. to change
GOTO
toGOTO_W
).- Parameters:
pos
- the index at which a byte sequence is inserted.code
- inserted bytecode sequence.- Throws:
BadBytecode
-
insertAt
Inserts the given bytecode sequence before the instruction at the given indexpos
. Branch offsets and the exception table are also updated.If the instruction at the given index is at the beginning of a block statement, then the bytecode is inserted within that block.
An extra gap may be inserted at the end of the inserted bytecode sequence for adjusting alignment if the code attribute includes
LOOKUPSWITCH
orTABLESWITCH
.- Parameters:
pos
- the index at which a byte sequence is inserted.code
- inserted bytecode sequence.- Returns:
- the index indicating the first byte of the inserted byte sequence, which might be different from pos.
- Throws:
BadBytecode
- Since:
- 3.11
-
insertEx
Inserts the given bytecode sequence exclusively before the next instruction that would be returned bynext()
(not before the instruction returned by tha last call tonext()
). Branch offsets and the exception table are also updated.If the next instruction is at the beginning of a block statement, then the bytecode is excluded from that block.
An extra gap may be inserted at the end of the inserted bytecode sequence for adjusting alignment if the code attribute includes
LOOKUPSWITCH
orTABLESWITCH
.- Parameters:
code
- inserted bytecode sequence.- Returns:
- the index indicating the first byte of the inserted byte sequence.
- Throws:
BadBytecode
-
insertEx
Inserts the given bytecode sequence exclusively before the instruction at the given indexpos
. Branch offsets and the exception table are also updated.If the instruction at the given index is at the beginning of a block statement, then the bytecode is excluded from that block.
An extra gap may be inserted at the end of the inserted bytecode sequence for adjusting alignment if the code attribute includes
LOOKUPSWITCH
orTABLESWITCH
.The index at which the byte sequence is actually inserted might be different from pos since some other bytes might be inserted at other positions (e.g. to change
GOTO
toGOTO_W
).- Parameters:
pos
- the index at which a byte sequence is inserted.code
- inserted bytecode sequence.- Throws:
BadBytecode
-
insertExAt
Inserts the given bytecode sequence exclusively before the instruction at the given indexpos
. Branch offsets and the exception table are also updated.If the instruction at the given index is at the beginning of a block statement, then the bytecode is excluded from that block.
An extra gap may be inserted at the end of the inserted bytecode sequence for adjusting alignment if the code attribute includes
LOOKUPSWITCH
orTABLESWITCH
.- Parameters:
pos
- the index at which a byte sequence is inserted.code
- inserted bytecode sequence.- Returns:
- the index indicating the first byte of the inserted byte sequence, which might be different from pos.
- Throws:
BadBytecode
- Since:
- 3.11
-
insertGap
Inserts a gap before the next instruction that would be returned bynext()
(not before the instruction returned by the last call tonext()
). Branch offsets and the exception table are also updated. The inserted gap is filled with NOP. The gap length may be extended to a multiple of 4.If the next instruction is at the beginning of a block statement, then the gap is inserted within that block.
- Parameters:
length
- gap length- Returns:
- the index indicating the first byte of the inserted gap.
- Throws:
BadBytecode
-
insertGap
Inserts a gap in front of the instruction at the given indexpos
. Branch offsets and the exception table are also updated. The inserted gap is filled with NOP. The gap length may be extended to a multiple of 4.If the instruction at the given index is at the beginning of a block statement, then the gap is inserted within that block.
- Parameters:
pos
- the index at which a gap is inserted.length
- gap length.- Returns:
- the length of the inserted gap.
It might be bigger than
length
. - Throws:
BadBytecode
-
insertExGap
Inserts an exclusive gap before the next instruction that would be returned bynext()
(not before the instruction returned by the last call tonext()
). Branch offsets and the exception table are also updated. The inserted gap is filled with NOP. The gap length may be extended to a multiple of 4.If the next instruction is at the beginning of a block statement, then the gap is excluded from that block.
- Parameters:
length
- gap length- Returns:
- the index indicating the first byte of the inserted gap.
- Throws:
BadBytecode
-
insertExGap
Inserts an exclusive gap in front of the instruction at the given indexpos
. Branch offsets and the exception table are also updated. The inserted gap is filled with NOP. The gap length may be extended to a multiple of 4.If the instruction at the given index is at the beginning of a block statement, then the gap is excluded from that block.
- Parameters:
pos
- the index at which a gap is inserted.length
- gap length.- Returns:
- the length of the inserted gap.
It might be bigger than
length
. - Throws:
BadBytecode
-
insertGapAt
Inserts an inclusive or exclusive gap in front of the instruction at the given indexpos
. Branch offsets and the exception table in the method body are also updated. The inserted gap is filled with NOP. The gap length may be extended to a multiple of 4.Suppose that the instruction at the given index is at the beginning of a block statement. If the gap is inclusive, then it is included within that block. If the gap is exclusive, then it is excluded from that block.
The index at which the gap is actually inserted might be different from pos since some other bytes might be inserted at other positions (e.g. to change
GOTO
toGOTO_W
). The index is available from theGap
object returned by this method.Suppose that the gap is inserted at the position of the next instruction that would be returned by
next()
(not the last instruction returned by the last call tonext()
). The next instruction returned bynext()
after the gap is inserted is still the same instruction. It is notNOP
at the first byte of the inserted gap.- Parameters:
pos
- the index at which a gap is inserted.length
- gap length.exclusive
- true if exclusive, otherwise false.- Returns:
- the position and the length of the inserted gap.
- Throws:
BadBytecode
- Since:
- 3.11
-
insert
Copies and inserts the entries in the given exception table at the beginning of the exception table in the code attribute edited by this object.- Parameters:
offset
- the value added to the code positions included in the entries.
-
append
public int append(byte[] code) Appends the given bytecode sequence at the end.- Parameters:
code
- the bytecode appended.- Returns:
- the position of the first byte of the appended bytecode.
-
appendGap
public void appendGap(int gapLength) Appends a gap at the end of the bytecode sequence.- Parameters:
gapLength
- gap length
-
append
Copies and appends the entries in the given exception table at the end of the exception table in the code attribute edited by this object.- Parameters:
offset
- the value added to the code positions included in the entries.
-