public class CodeIterator extends Object implements 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 CodeIterators 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.
CodeAttribute.iterator()| Modifier and Type | Class and Description | 
|---|---|
| static class  | CodeIterator.GapAn inserted gap. | 
| Modifier and Type | Field and Description | 
|---|---|
| protected byte[] | bytecode | 
| protected CodeAttribute | codeAttr | 
| protected int | currentPos | 
| protected int | endPos | 
| protected int | mark | 
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| Modifier | Constructor and Description | 
|---|---|
| protected  | CodeIterator(CodeAttribute ca) | 
| Modifier and Type | Method and Description | 
|---|---|
| int | 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. | 
| CodeAttribute | get()Returns a Code attribute read with this iterator. | 
| int | getCodeLength()Returns  code_lengthofCode_attribute. | 
| int | getMark()Gets the index of the position of the mark set by
  setMark. | 
| 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 by
  next()(not before the instruction returned
 by the last call tonext()). | 
| 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. | 
| void | insert(int pos,
      byte[] code)Inserts the given bytecode sequence
 before the instruction at the given index  pos. | 
| int | insertAt(int pos,
        byte[] code)Inserts the given bytecode sequence
 before the instruction at the given index  pos. | 
| int | insertEx(byte[] code)Inserts the given bytecode sequence exclusively
 before the next instruction that would be returned by
  next()(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 index  pos. | 
| int | insertExAt(int pos,
          byte[] code)Inserts the given bytecode sequence exclusively
 before the instruction at the given index  pos. | 
| int | insertExGap(int length)Inserts an exclusive gap
 before the next instruction that would be returned by
  next()(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
 index  pos. | 
| int | insertGap(int length)Inserts a gap
 before the next instruction that would be returned by
  next()(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
 index  pos. | 
| CodeIterator.Gap | insertGapAt(int pos,
           int length,
           boolean exclusive)Inserts an inclusive or exclusive gap in front of the instruction
 at the given index  pos. | 
| int | lookAhead()Obtains the value that the next call
 to  next()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. | 
| int | signedByteAt(int index)Returns the signed 8bit value at the given index. | 
| int | skipConstructor()Moves to the instruction for
 either  super()orthis(). | 
| int | skipSuperConstructor()Moves to the instruction for  super(). | 
| int | skipThisConstructor()Moves to the instruction for  this(). | 
| int | u16bitAt(int index)Returns the unsigned 16bit value at the given index. | 
| protected void | updateCursors(int pos,
             int length)Is called when a gap is inserted. | 
| 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. | 
protected CodeAttribute codeAttr
protected byte[] bytecode
protected int endPos
protected int currentPos
protected int mark
protected CodeIterator(CodeAttribute ca)
public void begin()
public void move(int 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 to move().
 
Note that the index is into the byte array returned by
 get().getCode().
CodeAttribute.getCode()public void setMark(int index)
getMark()public int getMark()
setMark.setMark(int)public CodeAttribute get()
public int getCodeLength()
code_length of Code_attribute.public int byteAt(int index)
public int signedByteAt(int index)
public void writeByte(int value,
                      int index)
public int u16bitAt(int index)
public int s16bitAt(int index)
public void write16bit(int value,
                       int index)
public int s32bitAt(int index)
public void write32bit(int value,
                       int index)
public void write(byte[] code,
                  int index)
code - may be a zero-length array.public boolean hasNext()
public int next()
         throws BadBytecode
Note that the index is into the byte array returned by
 get().getCode().
BadBytecodeCodeAttribute.getCode(), 
byteAt(int)public int lookAhead()
next() will return.
 This method is side-effects free.
 Successive calls to lookAhead() return the
 same value until next() is called.
public int skipConstructor()
                    throws BadBytecode
super() or this().
 This method skips all the instructions for computing arguments
 to super() or this(), which should be
 placed at the beginning of a constructor body.
 
This method returns the index of INVOKESPECIAL instruction
 executing super() or this().
 A successive call to next() returns the
 index of the next instruction following that INVOKESPECIAL.
 
This method works only for a constructor.
BadBytecodepublic int skipSuperConstructor()
                         throws BadBytecode
super().
 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 to next() returns the
 index of the next instruction following that INVOKESPECIAL.
 
This method works only for a constructor.
this() is found.BadBytecodepublic int skipThisConstructor()
                        throws BadBytecode
this().
 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 to next() returns the
 index of the next instruction following that INVOKESPECIAL.
 
This method works only for a constructor.
super() is found.BadBytecodepublic int insert(byte[] code)
           throws BadBytecode
next() (not before the instruction returned
 by the last call to next()).
 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 or TABLESWITCH.
code - inserted bytecode sequence.BadBytecodepublic void insert(int pos,
                   byte[] code)
            throws BadBytecode
pos.
 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 or TABLESWITCH.
 
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
 to GOTO_W).
pos - the index at which a byte sequence is inserted.code - inserted bytecode sequence.BadBytecodepublic int insertAt(int pos,
                    byte[] code)
             throws BadBytecode
pos.
 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 or TABLESWITCH.
pos - the index at which a byte sequence is inserted.code - inserted bytecode sequence.BadBytecodepublic int insertEx(byte[] code)
             throws BadBytecode
next() (not before the instruction returned
 by tha last call to next()).
 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 or TABLESWITCH.
code - inserted bytecode sequence.BadBytecodepublic void insertEx(int pos,
                     byte[] code)
              throws BadBytecode
pos.
 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 or TABLESWITCH.
 
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
 to GOTO_W).
pos - the index at which a byte sequence is inserted.code - inserted bytecode sequence.BadBytecodepublic int insertExAt(int pos,
                      byte[] code)
               throws BadBytecode
pos.
 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 or TABLESWITCH.
pos - the index at which a byte sequence is inserted.code - inserted bytecode sequence.BadBytecodepublic int insertGap(int length)
              throws BadBytecode
next() (not before the instruction returned
 by the last call to next()).
 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.
length - gap lengthBadBytecodepublic int insertGap(int pos,
                     int length)
              throws BadBytecode
pos.
 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.
pos - the index at which a gap is inserted.length - gap length.length.BadBytecodepublic int insertExGap(int length)
                throws BadBytecode
next() (not before the instruction returned
 by the last call to next()).
 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.
length - gap lengthBadBytecodepublic int insertExGap(int pos,
                       int length)
                throws BadBytecode
pos.
 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.
pos - the index at which a gap is inserted.length - gap length.length.BadBytecodepublic CodeIterator.Gap insertGapAt(int pos, int length, boolean exclusive) throws BadBytecode
pos.
 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
 to GOTO_W).  The index is available from the Gap
 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 to next()).  The next
 instruction returned by next() after the gap is
 inserted is still the same instruction.  It is not NOP
 at the first byte of the inserted gap.
pos - the index at which a gap is inserted.length - gap length.exclusive - true if exclusive, otherwise false.BadBytecodeprotected void updateCursors(int pos,
                             int length)
pos - the position where a gap is inserted.length - the length of the gap.public void insert(ExceptionTable et, int offset)
offset - the value added to the code positions included
                          in the entries.public int append(byte[] code)
code - the bytecode appended.public void appendGap(int gapLength)
gapLength - gap lengthpublic void append(ExceptionTable et, int offset)
offset - the value added to the code positions included
                          in the entries.Copyright © 2016 Shigeru Chiba, www.javassist.org. All Rights Reserved.