📄 instructionlist.java
字号:
* @return instruction handle pointing to the <B>first</B> appended instruction
*/
public BranchHandle append(InstructionHandle ih, BranchInstruction i) {
BranchHandle bh = BranchHandle.getBranchHandle(i);
InstructionList il = new InstructionList();
il.append(bh);
append(ih, il);
return bh;
}
/**
* Insert another list before Instruction handle ih contained in this list.
* Consumes argument list, i.e., it becomes empty.
*
* @param i where to append the instruction list
* @param il Instruction list to insert
* @return instruction handle of the first inserted instruction
*/
public InstructionHandle insert(InstructionHandle ih, InstructionList il) {
if(il == null)
throw new ClassGenException("Inserting null InstructionList");
if(il.isEmpty()) // Nothing to do
return ih;
InstructionHandle prev = ih.prev, ret = il.start;
ih.prev = il.end;
il.end.next = ih;
il.start.prev = prev;
if(prev != null) // ih == start ?
prev.next = il.start;
else
start = il.start; // Update start ...
length += il.length; // Update length
il.clear();
return ret;
}
/**
* Insert another list.
*
* @param il list to insert before start of this list
* @return instruction handle of the first inserted instruction
*/
public InstructionHandle insert(InstructionList il) {
if(isEmpty()) {
append(il); // Code is identical for this case
return start;
}
else
return insert(start, il);
}
/**
* Insert an instruction at start of this list.
*
* @param ih instruction to insert
*/
private void insert(InstructionHandle ih) {
if(isEmpty()) {
start = end = ih;
ih.next = ih.prev = null;
} else {
start.prev = ih;
ih.next = start;
ih.prev = null;
start = ih;
}
length++;
}
/**
* Insert another list before Instruction i contained in this list.
* Consumes argument list, i.e., it becomes empty.
*
* @param i where to append the instruction list
* @param il Instruction list to insert
* @return instruction handle pointing to the first inserted instruction,
* i.e., il.getStart()
*/
public InstructionHandle insert(Instruction i, InstructionList il) {
InstructionHandle ih;
if((ih = findInstruction1(i)) == null)
throw new ClassGenException("Instruction " + i +
" is not contained in this list.");
return insert(ih, il);
}
/**
* Insert an instruction at start of this list.
*
* @param i instruction to insert
* @return instruction handle of the inserted instruction
*/
public InstructionHandle insert(Instruction i) {
InstructionHandle ih = InstructionHandle.getInstructionHandle(i);
insert(ih);
return ih;
}
/**
* Insert a branch instruction at start of this list.
*
* @param i branch instruction to insert
* @return branch instruction handle of the appended instruction
*/
public BranchHandle insert(BranchInstruction i) {
BranchHandle ih = BranchHandle.getBranchHandle(i);
insert(ih);
return ih;
}
/**
* Insert a single instruction j before another instruction i, which
* must be in this list of course!
*
* @param i Instruction in list
* @param j Instruction to insert before i in list
* @return instruction handle of the first inserted instruction
*/
public InstructionHandle insert(Instruction i, Instruction j) {
return insert(i, new InstructionList(j));
}
/**
* Insert a compound instruction before instruction i.
*
* @param i Instruction in list
* @param c The composite instruction (containing an InstructionList)
* @return instruction handle of the first inserted instruction
*/
public InstructionHandle insert(Instruction i, CompoundInstruction c) {
return insert(i, c.getInstructionList());
}
/**
* Insert a compound instruction.
*
* @param c The composite instruction (containing an InstructionList)
* @return instruction handle of the first inserted instruction
*/
public InstructionHandle insert(CompoundInstruction c) {
return insert(c.getInstructionList());
}
/**
* Insert an instruction before instruction (handle) ih contained in this list.
*
* @param ih where to insert to the instruction list
* @param i Instruction to insert
* @return instruction handle of the first inserted instruction
*/
public InstructionHandle insert(InstructionHandle ih, Instruction i) {
return insert(ih, new InstructionList(i));
}
/**
* Insert a compound instruction.
*
* @param ih where to insert the instruction list
* @param c The composite instruction (containing an InstructionList)
* @return instruction handle of the first inserted instruction
*/
public InstructionHandle insert(InstructionHandle ih, CompoundInstruction c) {
return insert(ih, c.getInstructionList());
}
/**
* Insert an instruction before instruction (handle) ih contained in this list.
*
* @param ih where to insert to the instruction list
* @param i Instruction to insert
* @return instruction handle of the first inserted instruction
*/
public BranchHandle insert(InstructionHandle ih, BranchInstruction i) {
BranchHandle bh = BranchHandle.getBranchHandle(i);
InstructionList il = new InstructionList();
il.append(bh);
insert(ih, il);
return bh;
}
/**
* 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.<br>
* 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(InstructionHandle start, InstructionHandle end, 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.next; ih = ih.next) {
if(ih == null) // At end of list, end not found yet
throw new ClassGenException("Invalid range: From " + start + " to " + end);
else if(ih == target) // target may be null
throw new ClassGenException("Invalid range: From " + start + " to " + end +
" contains target " + target);
}
// Step 2: Temporarily remove the given instructions from the list
InstructionHandle prev = start.prev, next = end.next;
if(prev != null)
prev.next = next;
else // start == this.start!
this.start = next;
if(next != null)
next.prev = prev;
else // end == this.end!
this.end = prev;
start.prev = end.next = null;
// Step 3: append after target
if(target == null) { // append to start of list
end.next = this.start;
this.start = start;
} else {
next = target.next;
target.next = start;
start.prev = target;
end.next = next;
if(next != null)
next.prev = end;
}
}
/**
* Move a single instruction (handle) to a new location.
*
* @param ih moved instruction
* @param target new location of moved instruction
*/
public void move(InstructionHandle ih, 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(InstructionHandle prev, InstructionHandle next)
throws TargetLostException
{
InstructionHandle first, last; // First and last deleted instruction
if((prev == null) && (next == null)) { // singleton list
first = last = start;
start = end = null;
} else {
if(prev == null) { // At start of list
first = start;
start = next;
} else {
first = prev.next;
prev.next = next;
}
if(next == null) { // At end of list
last = end;
end = prev;
} else {
last = next.prev;
next.prev = prev;
}
}
first.prev = null; // Completely separated from rest of list
last.next = null;
ArrayList<InstructionHandle> target_vec = new ArrayList<InstructionHandle>();
for(InstructionHandle ih=first; ih != null; ih = ih.next)
ih.getInstruction().dispose(); // e.g. BranchInstructions release their targets
StringBuffer buf = new StringBuffer("{ ");
for(InstructionHandle ih=first; ih != null; ih = next) {
next = ih.next;
length--;
if(ih.hasTargeters()) { // Still got targeters?
target_vec.add(ih);
buf.append(ih.toString(true) + " ");
ih.next = ih.prev = 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());
}
}
/**
* Remove instruction from this list. The corresponding Instruction
* handles must not be reused!
*
* @param ih instruction (handle) to remove
*/
public void delete(InstructionHandle ih) throws TargetLostException {
remove(ih.prev, ih.next);
}
/**
* Remove instruction from this list. The corresponding Instruction
* handles must not be reused!
*
* @param i instruction to remove
*/
public void delete(Instruction i) throws TargetLostException {
InstructionHandle ih;
if((ih = findInstruction1(i)) == null)
throw new ClassGenException("Instruction " + i +
" is not contained in this list.");
delete(ih);
}
/**
* 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!
*
* @param from where to start deleting (inclusive)
* @param to where to end deleting (inclusive)
*/
public void delete(InstructionHandle from, InstructionHandle to)
throws TargetLostException
{
remove(from.prev, to.next);
}
/**
* 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!
*
* @param from where to start deleting (inclusive)
* @param to where to end deleting (inclusive)
*/
public void delete(Instruction from, Instruction to) throws TargetLostException {
InstructionHandle from_ih, to_ih;
if((from_ih = findInstruction1(from)) == null)
throw new ClassGenException("Instruction " + from +
" is not contained in this list.");
if((to_ih = findInstruction2(to)) == null)
throw new ClassGenException("Instruction " + to +
" is not contained in this list.");
delete(from_ih, to_ih);
}
/**
* Search for given Instruction reference, start at beginning of list.
*
* @param i instruction to search for
* @return instruction found on success, null otherwise
*/
private InstructionHandle findInstruction1(Instruction i) {
for(InstructionHandle ih=start; ih != null; ih = ih.next)
if(ih.instruction == i)
return ih;
return null;
}
/**
* Search for given Instruction reference, start at end of list
*
* @param i instruction to search for
* @return instruction found on success, null otherwise
*/
private InstructionHandle findInstruction2(Instruction i) {
for(InstructionHandle ih=end; ih != null; ih = ih.prev)
if(ih.instruction == i)
return ih;
return null;
}
public boolean contains(InstructionHandle i) {
if(i == null)
return false;
for(InstructionHandle ih=start; ih != null; ih = ih.next)
if(ih == i)
return true;
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -