📄 instructionlist.java
字号:
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; Vector target_vec = new Vector(); 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.addElement(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.copyInto(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; } public boolean contains(Instruction i) { return findInstruction1(i) != null; } public void setPositions() { setPositions(false); } /** * Give all instructions their position number (offset in byte stream), i.e., * make the list ready to be dumped. * * @param check Perform sanity checks, e.g. if all targeted instructions really belong * to this list */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -