* Any instruction targeters pointing to handles within the block, keep
* their targets.
*
* @param start
* of moved block
* @param end
* of moved block
* @param target
* of moved block
*/
public void move(final InstructionHandle start, final InstructionHandle end, final InstructionHandle target) {
// Step 1: Check constraints
if ((start == null) || (end == null)) {
throw new ClassGenException("Invalid null handle: From " + start + " to " + end);
}
if ((target == start) || (target == end)) {
throw new ClassGenException("Invalid range: From " + start + " to " + end + " contains target " + target);
}
for (InstructionHandle ih = start; ih != end.getNext(); ih = ih.getNext()) {
if (ih == null) {
throw new ClassGenException("Invalid range: From " + start + " to " + end);
} else if (ih == target) {
throw new ClassGenException("Invalid range: From " + start + " to " + end + " contains target " + target);
}
}
// Step 2: Temporarily remove the given instructions from the list
final InstructionHandle prev = start.getPrev();
InstructionHandle next = end.getNext();
if (prev != null) {
prev.setNext(next);
} else {
this.start = next;
}
if (next != null) {
next.setPrev(prev);
} else {
this.end = prev;
}
start.setPrev(end.setNext(null));
// Step 3: append after target
if (target == null) { // append to start of list
if (this.start != null) {
this.start.setPrev(end);
}
end.setNext(this.start);
this.start = start;
} else {
next = target.getNext();
target.setNext(start);
start.setPrev(target);
end.setNext(next);
if (next != null) {
next.setPrev(end);
} else {
this.end = end;
}
}
}
/**
* Move a single instruction (handle) to a new location.
*
* @param ih
* moved instruction
* @param target
* new location of moved instruction
*/
public void move(final InstructionHandle ih, final InstructionHandle target) {
move(ih, ih, target);
}
/**
* 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.
*
* @param prev
* where to start deleting (predecessor, exclusive)
* @param next
* where to end deleting (successor, exclusive)
*/
private void remove(final InstructionHandle prev, InstructionHandle next) throws TargetLostException {
InstructionHandle first;
InstructionHandle last; // First and last deleted instruction
if ((prev == null) && (next == null)) {
first = start;
last = end;
start = end = null;
} else {
if (prev == null) { // At start of list
first = start;
start = next;
} else {
first = prev.getNext();
prev.setNext(next);
}
if (next == null) { // At end of list
last = end;
end = prev;
} else {
last = next.getPrev();
next.setPrev(prev);
}
}
first.setPrev(null); // Completely separated from rest of list
last.setNext(null);
final List