edu.rice.cs.cunit.classFile.code
Class InstructionList

java.lang.Object
  extended by edu.rice.cs.cunit.classFile.code.InstructionList

public class InstructionList
extends java.lang.Object

Represents a list of Java instructions.

Author:
Mathias Ricken

Field Summary
protected  int _index
           
(package private)  java.util.LinkedList<AInstruction> _instructionList
           
(package private)  LineNumberTable _lnt
           
 
Constructor Summary
InstructionList(byte[] code)
          Constructor.
InstructionList(byte[] code, int index)
          Constructor.
InstructionList(InstructionList original)
          Copy constructor.
 
Method Summary
 boolean advanceIndex()
          Advance the program index to the next instruction.
 boolean advanceIndex(int count)
          Advance the program index by multiple instructions.
 boolean deleteInstr(CodeAttributeInfo codeAttribute)
          This method deletes the instruction at the program index.
 boolean equals(java.lang.Object o)
          Return true if this instruction list and the other object are equal.
 boolean findInstruction(AInstruction instr)
          Finds the next instruction that matches the specified instruction completely and moves the program counter there.
 boolean findInstruction(AInstruction[] instrs)
          Finds the next instruction that matches one of the specified instructions completely and moves the program counter there.
 boolean findOpcode(byte opcode)
          Finds the next instruction with the specified opcode and moves the program counter there.
 boolean findOpcode(byte[] opcodes)
          Finds the next instruction with one of the specified opcodes and moves the program counter there.
 byte[] getCode()
          Accessor for the bytecode.
 int getIndex()
          Accessor for the program index.
 AInstruction getInstr()
          Return the instruction at the program index.
 int getLength()
          Get the length of the instruction list.
 byte getOpcode()
          Return the opcode at the program index.
 int getPCFromIndex(int index)
          Calculate the PC for an index.
 int hashCode()
          Return hash code.
 void insertBeforeInstr(AInstruction instr, CodeAttributeInfo codeAttribute)
          This method inserts the instruction before the program counter.
 void insertInstr(AInstruction instr, CodeAttributeInfo codeAttribute)
          This method inserts the instruction at the program counter.
protected  void relocateBranches(AInstruction relocInstr, int ip)
          Relocate branches in the instruction.
 boolean rewindIndex()
          Rewind the program index to the previous instruction.
 boolean rewindIndex(int count)
          Rewind the program index by multiple instructions.
 void setCode(byte[] code)
          Mutator for the bytecode.
 void setIndex(int index)
          Mutator for the program index.
 java.lang.String toString()
          Return a human-readable version of the code.
 java.lang.String toString(boolean lineNumbers, boolean PCs, ConstantPool cp)
          Return a human-readable version of the code.
 java.lang.String toString(ConstantPool cp)
          Return a human-readable version of the code.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

_instructionList

java.util.LinkedList<AInstruction> _instructionList

_index

protected int _index

_lnt

LineNumberTable _lnt
Constructor Detail

InstructionList

public InstructionList(byte[] code)
Constructor.

Parameters:
code - bytecode

InstructionList

public InstructionList(InstructionList original)
Copy constructor.

Parameters:
original - original

InstructionList

public InstructionList(byte[] code,
                       int index)
                throws java.lang.IndexOutOfBoundsException
Constructor.

Parameters:
code - bytecode
index - program index.
Throws:
java.lang.IndexOutOfBoundsException
Method Detail

toString

public java.lang.String toString()
Return a human-readable version of the code.

Overrides:
toString in class java.lang.Object
Returns:
mnemonics

toString

public java.lang.String toString(ConstantPool cp)
Return a human-readable version of the code.

Parameters:
cp - constant pool
Returns:
mnemonics

toString

public java.lang.String toString(boolean lineNumbers,
                                 boolean PCs,
                                 ConstantPool cp)
Return a human-readable version of the code.

Parameters:
lineNumbers - print line numbers
PCs - print PC values
cp - constant pool, or null if not verbose
Returns:
mnemonics

getCode

public byte[] getCode()
               throws java.lang.IllegalStateException
Accessor for the bytecode.

Returns:
bytecode
Throws:
java.lang.IllegalStateException

setCode

public void setCode(byte[] code)
Mutator for the bytecode. This also resets the program counter to 0.

Parameters:
code - bytecode

getIndex

public int getIndex()
Accessor for the program index.

Returns:
program index

getPCFromIndex

public int getPCFromIndex(int index)
Calculate the PC for an index.

Parameters:
index - index
Returns:
PC

getLength

public int getLength()
Get the length of the instruction list.

Returns:
length

setIndex

public void setIndex(int index)
              throws java.lang.IndexOutOfBoundsException,
                     java.lang.IllegalArgumentException
Mutator for the program index.

Parameters:
index - new program index
Throws:
java.lang.IndexOutOfBoundsException
java.lang.IllegalArgumentException

advanceIndex

public boolean advanceIndex(int count)
Advance the program index by multiple instructions.

Parameters:
count - number of instructions
Returns:
true while the end of the instruction list has not been reached

advanceIndex

public boolean advanceIndex()
Advance the program index to the next instruction.

Returns:
true while the end of the instruction list has not been reached

rewindIndex

public boolean rewindIndex(int count)
Rewind the program index by multiple instructions.

Parameters:
count - number of instructions
Returns:
true while the beginning of the instruction list has not been reached

rewindIndex

public boolean rewindIndex()
Rewind the program index to the previous instruction.

Returns:
true while the beginning of the instruction list has not been reached

getOpcode

public byte getOpcode()
Return the opcode at the program index.

Returns:
opcode at program index

getInstr

public AInstruction getInstr()
Return the instruction at the program index. This includes the code and the operands.

Returns:
instruction at program index

deleteInstr

public boolean deleteInstr(CodeAttributeInfo codeAttribute)
This method deletes the instruction at the program index. It also relocates all jumps. All jumps to places after the deletion point will be changed so that they still point to the same instruction. Jumps to the deletion point or to places before it are not changed. The index will remain unchanged. In case the program counter is past the end of the code block, false will be returned. If codeAttribute is non-null, the PCs in the CodeAttribute will be adjusted.

Parameters:
codeAttribute - CodeAttribute that contains this code block, or null if none
Returns:
true while the end of the code block has not been reached

insertInstr

public void insertInstr(AInstruction instr,
                        CodeAttributeInfo codeAttribute)
This method inserts the instruction at the program counter. The instruction currently at the program counter will be pushed towards the end of the bytecode array. It also relocates all jumps. Jumps to the insertion point or to places before it are not changed. Jumps to all other places will be changed so that they still point to the same instruction. That means that jumps to the instruction previously at the insertion point will now jump to the newly inserted instruction. If codeAttribute is non-null, the PCs in the CodeAttribute will be adjusted. The program counter will remain unchanged. If the inserted instruction itself contains jump targets, these will be relocated as well. Notice, though, that if the instruction contains a jump exactly to the insertion point, this jump will be relocated so that it points to the old instruction (this is the behavior of insertBeforeInstr).

Assume the following code: 1. a 2. b 3. c 4. goto 1 // jump to place before insertion point 5. goto 2 // jump to insertion point 6. goto 3 // junp to place after insertion point The program counter is currently at 2, and the instruction x is inserted using insertInstr. The result is: 1. a 2. x // inserted 3. b 4. c 5. goto 1 // not changed 6. goto 2 // not changed 7. goto 4 // changed

Relocation of branches in the instruction inserted. Type : jump to place before insertion point Action : not changed Example; goto 1 --> goto 1 Type : jump to insertion point Action : changed Example; goto 2 --> goto 3 Type : jump to place after instruction point Action : changed Example; goto 3 --> goto 4

Parameters:
codeAttribute - CodeAttribute that contains this code block, or null if none
instr - instruction to be inserted

relocateBranches

protected void relocateBranches(AInstruction relocInstr,
                                int ip)
Relocate branches in the instruction. If a branch target is to somewhere past the insertion point, it is increased by one.

Parameters:
relocInstr - instruction whose branches should be relocated
ip - insertion point

insertBeforeInstr

public void insertBeforeInstr(AInstruction instr,
                              CodeAttributeInfo codeAttribute)
This method inserts the instruction before the program counter. The instruction currently at the program counter will be pushed towards the end of the bytecode array. It also relocates all jumps. Jumps to places before the insertion point are not changed. Jumps to all other places will be changed so that they still point to the same instruction. That means that jumps to the instruction previously at the insertion point will still jump to the old instruction. If codeAttribute is non-null, the PCs in the CodeAttribute will be adjusted. The program counter will remain unchanged. If the inserted instruction itself contains jump targets, these will be relocated as well.

Assume the following code: 1. a 2. b 3. c 4. goto 1 // jump to place before insertion point 5. goto 2 // jump to insertion point 6. goto 3 // junp to place after insertion point The program counter is currently at 2, and the instruction x is inserted using insertBeforeInstr. The result is: 1. a 2. x // inserted 3. b 4. c 5. goto 1 // not changed 6. goto 3 // changed 7. goto 4 // changed

Relocation of branches in the instruction inserted. Type : jump to place before insertion point Action : not changed Example; goto 1 --> goto 1 Type : jump to insertion point Action : changed Example; goto 2 --> goto 3 Type : jump to place after instruction point Action : changed Example; goto 3 --> goto 4

Parameters:
codeAttribute - CodeAttribute that contains this code block, or null if none
instr - instruction to be inserted

findOpcode

public boolean findOpcode(byte opcode)
Finds the next instruction with the specified opcode and moves the program counter there. If the current instruction matches the opcode, the program counter will not be changed. This means that the caller is responsible for advancing the program counter after a match has been found!

Parameters:
opcode - opcode to find
Returns:
true while the end of the code block has not been reached

findOpcode

public boolean findOpcode(byte[] opcodes)
Finds the next instruction with one of the specified opcodes and moves the program counter there. If the current instruction matches one of the opcodes, the program counter will not be changed. This means that the caller is responsible for advancing the program counter after a match has been found!

Parameters:
opcodes - array of opcodes to find
Returns:
true while the end of the code block has not been reached

findInstruction

public boolean findInstruction(AInstruction instr)
Finds the next instruction that matches the specified instruction completely and moves the program counter there. A complete match requires that both the opcode and all the operands are identical. If the current instruction matches already, the program counter will not be changed. This means that the caller is responsible for advancing the program counter after a match has been found!

Parameters:
instr - instruction to find
Returns:
true while the end of the code block has not been reached

findInstruction

public boolean findInstruction(AInstruction[] instrs)
Finds the next instruction that matches one of the specified instructions completely and moves the program counter there. A complete match requires that both the opcode and all the operands are identical. If the current instruction matches already, the program counter will not be changed. This means that the caller is responsible for advancing the program counter after a match has been found!

Parameters:
instrs - instructions to find
Returns:
true while the end of the code block has not been reached

equals

public boolean equals(java.lang.Object o)
Return true if this instruction list and the other object are equal.

Overrides:
equals in class java.lang.Object
Parameters:
o - other object
Returns:
true if equal

hashCode

public int hashCode()
Return hash code.

Overrides:
hashCode in class java.lang.Object
Returns:
hash code