class InstructionList {
/**
* Insert an instruction at start of this list.
*
* @param ih instruction to insert
*/
private void insert( InstructionHandle ih ) {
if (isEmpty()) {
start = end = ih;
ih.setNext(ih.setPrev(null));
} else {
start.setPrev(ih);
ih.setNext(start);
ih.setPrev(null);
start = ih;
}
length++;
}
}
class InstructionList {
/**
* 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( 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);
List<InstructionHandle> target_vec = new ArrayList<>();
for (InstructionHandle ih = first; ih != null; ih = ih.getNext()) {
ih.getInstruction().dispose(); // e.g. BranchInstructions release their targets
}
StringBuilder buf = new StringBuilder("{ ");
for (InstructionHandle ih = first; ih != null; ih = next) {
next = ih.getNext();
length--;
if (ih.hasTargeters()) { // Still got targeters?
target_vec.add(ih);
buf.append(ih.toString(true)).append(" ");
ih.setNext(ih.setPrev(null));
} else {
ih.dispose();
}
}
buf.append("}");
if (!target_vec.isEmpty()) {
InstructionHandle[] targeted = new InstructionHandle[target_vec.size()];
target_vec.toArray(targeted);
throw new TargetLostException(targeted, buf.toString());
}
}
}