Package org.apache.bcel.generic
Class InstructionList
- java.lang.Object
-
- org.apache.bcel.generic.InstructionList
-
- All Implemented Interfaces:
java.lang.Iterable<InstructionHandle>
public class InstructionList extends java.lang.Object implements java.lang.Iterable<InstructionHandle>
This class is a container for a list of Instruction objects. Instructions can be appended, inserted, moved, deleted, and so on. Instructions are being wrapped into InstructionHandles objects that are returned upon append/insert operations. They give the user (read only) access to the list structure, such that it can be traversed and manipulated in a controlled way.A list is finally dumped to a byte code array with getByteCode.
- See Also:
Instruction,InstructionHandle,BranchHandle
-
-
Field Summary
Fields Modifier and Type Field Description private int[]bytePositionsprivate InstructionHandleendprivate intlengthprivate java.util.List<InstructionListObserver>observersprivate InstructionHandlestart
-
Constructor Summary
Constructors Constructor Description InstructionList()Create (empty) instruction list.InstructionList(byte[] code)Initialize instruction list from byte array.InstructionList(BranchInstruction i)Create instruction list containing one instruction.InstructionList(CompoundInstruction c)Initialize list with (nonnull) compound instruction.InstructionList(Instruction i)Create instruction list containing one instruction.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidaddObserver(InstructionListObserver o)Add observer for this object.BranchHandleappend(BranchInstruction i)Append a branch instruction to the end of this list.InstructionHandleappend(CompoundInstruction c)Append a compound instruction.InstructionHandleappend(Instruction i)Append an instruction to the end of this list.private voidappend(InstructionHandle ih)Append an instruction to the end of this list.BranchHandleappend(InstructionHandle ih, BranchInstruction i)Append an instruction after instruction (handle) ih contained in this list.InstructionHandleappend(InstructionHandle ih, CompoundInstruction c)Append a compound instruction.InstructionHandleappend(InstructionHandle ih, Instruction i)Append an instruction after instruction (handle) ih contained in this list.InstructionHandleappend(InstructionHandle ih, InstructionList il)Append another list after instruction (handle) ih contained in this list.InstructionHandleappend(InstructionList il)Append another list to this one.InstructionHandleappend(Instruction i, CompoundInstruction c)Append a compound instruction, after instruction i.InstructionHandleappend(Instruction i, Instruction j)Append a single instruction j after another instruction i, which must be in this list of course!InstructionHandleappend(Instruction i, InstructionList il)Append another list after instruction i contained in this list.private voidclear()booleancontains(Instruction i)Checks if the list contains the given instruction.booleancontains(InstructionHandle i)Checks if the list contains the given instruction handle.InstructionListcopy()Creates a complete deep copy of this list.voiddelete(Instruction i)Remove instruction from this list.voiddelete(InstructionHandle ih)Remove instruction from this list.voiddelete(InstructionHandle from, InstructionHandle to)Remove instructions from instruction 'from' to instruction 'to' contained in this list.voiddelete(Instruction from, Instruction to)Remove instructions from instruction 'from' to instruction 'to' contained in this list.voiddispose()Delete contents of list.InstructionHandlefindHandle(int pos)Gets instruction handle for instruction at byte code position pos.static InstructionHandlefindHandle(InstructionHandle[] ihs, int[] pos, int count, int target)Find the target instruction (handle) that corresponds to the given target position (byte code offset).private InstructionHandlefindInstruction1(Instruction i)Search for given Instruction reference, start at beginning of list.private InstructionHandlefindInstruction2(Instruction i)Search for given Instruction reference, start at end of listbyte[]getByteCode()When everything is finished, use this method to convert the instruction list into an array of bytes.InstructionHandlegetEnd()Gets the end of list.InstructionHandle[]getInstructionHandles()Gets array containing all instructions.int[]getInstructionPositions()Gets positions (offsets) of all instructions in the list.Instruction[]getInstructions()Gets an array of instructions without target information for branch instructions.intgetLength()Gets the length of list.InstructionHandlegetStart()Gets the start of list.BranchHandleinsert(BranchInstruction i)Insert a branch instruction at start of this list.InstructionHandleinsert(CompoundInstruction c)Insert a compound instruction.InstructionHandleinsert(Instruction i)Insert an instruction at start of this list.private voidinsert(InstructionHandle ih)Insert an instruction at start of this list.BranchHandleinsert(InstructionHandle ih, BranchInstruction i)Insert an instruction before instruction (handle) ih contained in this list.InstructionHandleinsert(InstructionHandle ih, CompoundInstruction c)Insert a compound instruction.InstructionHandleinsert(InstructionHandle ih, Instruction i)Insert an instruction before instruction (handle) ih contained in this list.InstructionHandleinsert(InstructionHandle ih, InstructionList il)Insert another list before Instruction handle ih contained in this list.InstructionHandleinsert(InstructionList il)Insert another list.InstructionHandleinsert(Instruction i, CompoundInstruction c)Insert a compound instruction before instruction i.InstructionHandleinsert(Instruction i, Instruction j)Insert a single instruction j before another instruction i, which must be in this list of course!InstructionHandleinsert(Instruction i, InstructionList il)Insert another list before Instruction i contained in this list.booleanisEmpty()Tests for empty list.java.util.Iterator<InstructionHandle>iterator()voidmove(InstructionHandle ih, InstructionHandle target)Move a single instruction (handle) to a new location.voidmove(InstructionHandle start, InstructionHandle end, InstructionHandle target)Take all instructions (handles) from "start" to "end" and append them after the new location "target".voidredirectBranches(InstructionHandle oldTarget, InstructionHandle newTarget)Redirect all references from oldTarget to newTarget, that is, update targets of branch instructions.voidredirectExceptionHandlers(CodeExceptionGen[] exceptions, InstructionHandle oldTarget, InstructionHandle newTarget)Redirect all references of exception handlers from oldTarget to newTarget.voidredirectLocalVariables(LocalVariableGen[] lg, InstructionHandle oldTarget, InstructionHandle newTarget)Redirect all references of local variables from oldTarget to newTarget.private voidremove(InstructionHandle prev, InstructionHandle next)Remove from instruction 'prev' to instruction 'next' both contained in this list.voidremoveObserver(InstructionListObserver o)Remove observer for this object.voidreplaceConstantPool(ConstantPoolGen oldCp, ConstantPoolGen newCp)Replace all references to the old constant pool with references to the new constant pool.voidsetPositions()Sets positions with no sanity checks.voidsetPositions(boolean check)Give all instructions their position number (offset in byte stream), that is, make the list ready to be dumped.intsize()Gets the length of list.java.lang.StringtoString()java.lang.StringtoString(boolean verbose)Gets string containing all instructions in this list.voidupdate()Call notify() method on all observers.
-
-
-
Field Detail
-
start
private InstructionHandle start
-
end
private InstructionHandle end
-
length
private int length
-
bytePositions
private int[] bytePositions
-
observers
private java.util.List<InstructionListObserver> observers
-
-
Constructor Detail
-
InstructionList
public InstructionList()
Create (empty) instruction list.
-
InstructionList
public InstructionList(BranchInstruction i)
Create instruction list containing one instruction.- Parameters:
i- initial instruction.
-
InstructionList
public InstructionList(byte[] code)
Initialize instruction list from byte array.- Parameters:
code- byte array containing the instructions.
-
InstructionList
public InstructionList(CompoundInstruction c)
Initialize list with (nonnull) compound instruction. Consumes argument list, that is, it becomes empty.- Parameters:
c- compound instruction (list).
-
InstructionList
public InstructionList(Instruction i)
Create instruction list containing one instruction.- Parameters:
i- initial instruction.
-
-
Method Detail
-
findHandle
public static InstructionHandle findHandle(InstructionHandle[] ihs, int[] pos, int count, int target)
Find the target instruction (handle) that corresponds to the given target position (byte code offset).- Parameters:
ihs- array of instruction handles, for example il.getInstructionHandles().pos- array of positions corresponding to ihs, for example il.getInstructionPositions().count- length of arrays.target- target position to search for.- Returns:
- target position's instruction handle if available.
-
addObserver
public void addObserver(InstructionListObserver o)
Add observer for this object.- Parameters:
o- the observer to add.
-
append
public BranchHandle append(BranchInstruction i)
Append a branch instruction to the end of this list.- Parameters:
i- branch instruction to append.- Returns:
- branch instruction handle of the appended instruction.
-
append
public InstructionHandle append(CompoundInstruction c)
Append a compound instruction.- Parameters:
c- The composite instruction (containing an InstructionList).- Returns:
- instruction handle of the first appended instruction.
-
append
public InstructionHandle append(Instruction i)
Append an instruction to the end of this list.- Parameters:
i- instruction to append.- Returns:
- instruction handle of the appended instruction.
-
append
public InstructionHandle append(Instruction i, CompoundInstruction c)
Append a compound instruction, after instruction i.- Parameters:
i- Instruction in list.c- The composite instruction (containing an InstructionList).- Returns:
- instruction handle of the first appended instruction.
-
append
public InstructionHandle append(Instruction i, Instruction j)
Append a single instruction j after another instruction i, which must be in this list of course!- Parameters:
i- Instruction in list.j- Instruction to append after i in list.- Returns:
- instruction handle of the first appended instruction.
-
append
public InstructionHandle append(Instruction i, InstructionList il)
Append another list after instruction i contained in this list. Consumes argument list, that is, it becomes empty.- Parameters:
i- where to append the instruction list.il- Instruction list to append to this one.- Returns:
- instruction handle pointing to the first appended instruction.
-
append
private void append(InstructionHandle ih)
Append an instruction to the end of this list.- Parameters:
ih- instruction to append.
-
append
public BranchHandle append(InstructionHandle ih, BranchInstruction i)
Append an instruction after instruction (handle) ih contained in this list.- Parameters:
ih- where to append the instruction list.i- Instruction to append.- Returns:
- instruction handle pointing to the first appended instruction.
-
append
public InstructionHandle append(InstructionHandle ih, CompoundInstruction c)
Append a compound instruction.- Parameters:
ih- where to append the instruction list.c- The composite instruction (containing an InstructionList).- Returns:
- instruction handle of the first appended instruction.
-
append
public InstructionHandle append(InstructionHandle ih, Instruction i)
Append an instruction after instruction (handle) ih contained in this list.- Parameters:
ih- where to append the instruction list.i- Instruction to append.- Returns:
- instruction handle pointing to the first appended instruction.
-
append
public InstructionHandle append(InstructionHandle ih, InstructionList il)
Append another list after instruction (handle) ih contained in this list. Consumes argument list, that is, it becomes empty.- Parameters:
ih- where to append the instruction list.il- Instruction list to append to this one.- Returns:
- instruction handle pointing to the first appended instruction.
-
append
public InstructionHandle append(InstructionList il)
Append another list to this one. Consumes argument list, that is, it becomes empty.- Parameters:
il- list to append to end of this list.- Returns:
- instruction handle of the first appended instruction.
-
clear
private void clear()
-
contains
public boolean contains(Instruction i)
Checks if the list contains the given instruction.- Parameters:
i- the instruction to check.- Returns:
- true if the list contains the instruction.
-
contains
public boolean contains(InstructionHandle i)
Checks if the list contains the given instruction handle.- Parameters:
i- the instruction handle to check.- Returns:
- true if the list contains the instruction handle.
-
copy
public InstructionList copy()
Creates a complete deep copy of this list.- Returns:
- complete, that is, deep copy of this list.
-
delete
public void delete(Instruction i) throws TargetLostException
Remove instruction from this list. The corresponding Instruction handles must not be reused!- Parameters:
i- instruction to remove.- Throws:
TargetLostException- if target is lost.
-
delete
public void delete(Instruction from, Instruction to) throws TargetLostException
Remove instructions from instruction 'from' to instruction 'to' contained in this list. The user must ensure that 'from' is an instruction before 'to', or risk havoc. The corresponding Instruction handles must not be reused!- Parameters:
from- where to start deleting (inclusive).to- where to end deleting (inclusive).- Throws:
TargetLostException- if target is lost.
-
delete
public void delete(InstructionHandle ih) throws TargetLostException
Remove instruction from this list. The corresponding Instruction handles must not be reused!- Parameters:
ih- instruction (handle) to remove.- Throws:
TargetLostException- if target is lost.
-
delete
public void delete(InstructionHandle from, InstructionHandle to) throws TargetLostException
Remove instructions from instruction 'from' to instruction 'to' contained in this list. The user must ensure that 'from' is an instruction before 'to', or risk havoc. The corresponding Instruction handles must not be reused!- Parameters:
from- where to start deleting (inclusive).to- where to end deleting (inclusive).- Throws:
TargetLostException- if target is lost.
-
dispose
public void dispose()
Delete contents of list. Provides better memory utilization, because the system then may reuse the instruction handles. This method is typically called right afterMethodGen.getMethod().
-
findHandle
public InstructionHandle findHandle(int pos)
Gets instruction handle for instruction at byte code position pos. This only works properly, if the list is freshly initialized from a byte array or setPositions() has been called before this method.- Parameters:
pos- byte code position to search for.- Returns:
- target position's instruction handle if available.
-
findInstruction1
private InstructionHandle findInstruction1(Instruction i)
Search for given Instruction reference, start at beginning of list.- Parameters:
i- instruction to search for.- Returns:
- instruction found on success, null otherwise.
-
findInstruction2
private InstructionHandle findInstruction2(Instruction i)
Search for given Instruction reference, start at end of list- Parameters:
i- instruction to search for.- Returns:
- instruction found on success, null otherwise.
-
getByteCode
public byte[] getByteCode()
When everything is finished, use this method to convert the instruction list into an array of bytes.- Returns:
- the byte code ready to be dumped.
-
getEnd
public InstructionHandle getEnd()
Gets the end of list.- Returns:
- end of list.
-
getInstructionHandles
public InstructionHandle[] getInstructionHandles()
Gets array containing all instructions.- Returns:
- array containing all instructions (handles).
-
getInstructionPositions
public int[] getInstructionPositions()
Gets positions (offsets) of all instructions in the list. This relies on that the list has been freshly created from an byte code array, or that setPositions() has been called. Otherwise this may be inaccurate.- Returns:
- array containing all instruction's offset in byte code.
-
getInstructions
public Instruction[] getInstructions()
Gets an array of instructions without target information for branch instructions.- Returns:
- an array of instructions without target information for branch instructions.
-
getLength
public int getLength()
Gets the length of list.- Returns:
- length of list (Number of instructions, not bytes).
-
getStart
public InstructionHandle getStart()
Gets the start of list.- Returns:
- start of list.
-
insert
public BranchHandle insert(BranchInstruction i)
Insert a branch instruction at start of this list.- Parameters:
i- branch instruction to insert.- Returns:
- branch instruction handle of the appended instruction.
-
insert
public InstructionHandle insert(CompoundInstruction c)
Insert a compound instruction.- Parameters:
c- The composite instruction (containing an InstructionList).- Returns:
- instruction handle of the first inserted instruction.
-
insert
public InstructionHandle insert(Instruction i)
Insert an instruction at start of this list.- Parameters:
i- instruction to insert.- Returns:
- instruction handle of the inserted instruction.
-
insert
public InstructionHandle insert(Instruction i, CompoundInstruction c)
Insert a compound instruction before instruction i.- Parameters:
i- Instruction in list.c- The composite instruction (containing an InstructionList).- Returns:
- instruction handle of the first inserted instruction.
-
insert
public InstructionHandle insert(Instruction i, Instruction j)
Insert a single instruction j before another instruction i, which must be in this list of course!- Parameters:
i- Instruction in list.j- Instruction to insert before i in list.- Returns:
- instruction handle of the first inserted instruction.
-
insert
public InstructionHandle insert(Instruction i, InstructionList il)
Insert another list before Instruction i contained in this list. Consumes argument list, that is, it becomes empty.- Parameters:
i- where to append the instruction list.il- Instruction list to insert.- Returns:
- instruction handle pointing to the first inserted instruction, that is, il.getStart().
-
insert
private void insert(InstructionHandle ih)
Insert an instruction at start of this list.- Parameters:
ih- instruction to insert.
-
insert
public BranchHandle insert(InstructionHandle ih, BranchInstruction i)
Insert an instruction before instruction (handle) ih contained in this list.- Parameters:
ih- where to insert to the instruction list.i- Instruction to insert.- Returns:
- instruction handle of the first inserted instruction.
-
insert
public InstructionHandle insert(InstructionHandle ih, CompoundInstruction c)
Insert a compound instruction.- Parameters:
ih- where to insert the instruction list.c- The composite instruction (containing an InstructionList).- Returns:
- instruction handle of the first inserted instruction.
-
insert
public InstructionHandle insert(InstructionHandle ih, Instruction i)
Insert an instruction before instruction (handle) ih contained in this list.- Parameters:
ih- where to insert to the instruction list.i- Instruction to insert.- Returns:
- instruction handle of the first inserted instruction.
-
insert
public InstructionHandle insert(InstructionHandle ih, InstructionList il)
Insert another list before Instruction handle ih contained in this list. Consumes argument list, that is, it becomes empty.- Parameters:
ih- where to append the instruction list.il- Instruction list to insert.- Returns:
- instruction handle of the first inserted instruction.
-
insert
public InstructionHandle insert(InstructionList il)
Insert another list.- Parameters:
il- list to insert before start of this list.- Returns:
- instruction handle of the first inserted instruction.
-
isEmpty
public boolean isEmpty()
Tests for empty list.
-
iterator
public java.util.Iterator<InstructionHandle> iterator()
- Specified by:
iteratorin interfacejava.lang.Iterable<InstructionHandle>- Returns:
- iterator that lists all instructions (handles).
-
move
public void move(InstructionHandle ih, InstructionHandle target)
Move a single instruction (handle) to a new location.- Parameters:
ih- moved instruction.target- new location of moved instruction.
-
move
public void move(InstructionHandle start, InstructionHandle end, InstructionHandle target)
Take all instructions (handles) from "start" to "end" and append them after the new location "target". Of course, "end" must be after "start" and target must not be located withing this range. If you want to move something to the start of the list use null as value for target.Any instruction targeters pointing to handles within the block, keep their targets.
- Parameters:
start- of moved block.end- of moved block.target- of moved block.
-
redirectBranches
public void redirectBranches(InstructionHandle oldTarget, InstructionHandle newTarget)
Redirect all references from oldTarget to newTarget, that is, update targets of branch instructions.- Parameters:
oldTarget- the old target instruction handle.newTarget- the new target instruction handle.
-
redirectExceptionHandlers
public void redirectExceptionHandlers(CodeExceptionGen[] exceptions, InstructionHandle oldTarget, InstructionHandle newTarget)
Redirect all references of exception handlers from oldTarget to newTarget.- Parameters:
exceptions- array of exception handlers.oldTarget- the old target instruction handle.newTarget- the new target instruction handle.- See Also:
MethodGen
-
redirectLocalVariables
public void redirectLocalVariables(LocalVariableGen[] lg, InstructionHandle oldTarget, InstructionHandle newTarget)
Redirect all references of local variables from oldTarget to newTarget.- Parameters:
lg- array of local variables.oldTarget- the old target instruction handle.newTarget- the new target instruction handle.- See Also:
MethodGen
-
remove
private void remove(InstructionHandle prev, InstructionHandle next) throws TargetLostException
Remove from instruction 'prev' to instruction 'next' both contained in this list. Throws TargetLostException when one of the removed instruction handles is still being targeted.- Parameters:
prev- where to start deleting (predecessor, exclusive).next- where to end deleting (successor, exclusive).- Throws:
TargetLostException
-
removeObserver
public void removeObserver(InstructionListObserver o)
Remove observer for this object.- Parameters:
o- the observer to remove.
-
replaceConstantPool
public void replaceConstantPool(ConstantPoolGen oldCp, ConstantPoolGen newCp)
Replace all references to the old constant pool with references to the new constant pool.- Parameters:
oldCp- the old constant pool.newCp- the new constant pool.
-
setPositions
public void setPositions()
Sets positions with no sanity checks.
-
setPositions
public void setPositions(boolean check)
Give all instructions their position number (offset in byte stream), that is, make the list ready to be dumped.- Parameters:
check- Perform sanity checks, for example if all targeted instructions really belong to this list.
-
size
public int size()
Gets the length of list.- Returns:
- length of list (Number of instructions, not bytes).
-
toString
public java.lang.String toString()
- Overrides:
toStringin classjava.lang.Object
-
toString
public java.lang.String toString(boolean verbose)
Gets string containing all instructions in this list.- Parameters:
verbose- toggle output format.- Returns:
- String containing all instructions in this list.
-
update
public void update()
Call notify() method on all observers. This method is not called automatically whenever the state has changed, but has to be called by the user after he has finished editing the object.
-
-