/** * 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; }
/** * 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); } }
/** @return complete, i.e., deep copy of this list */ public InstructionList copy() { Map<InstructionHandle, InstructionHandle> map = new HashMap<InstructionHandle, InstructionHandle>(); InstructionList il = new InstructionList(); /* Pass 1: Make copies of all instructions, append them to the new list * and associate old instruction references with the new ones, i.e., * a 1:1 mapping. */ for (InstructionHandle ih = start; ih != null; ih = ih.next) { Instruction i = ih.instruction; Instruction c = i.copy(); // Use clone for shallow copy if (c instanceof BranchInstruction) { map.put(ih, il.append((BranchInstruction) c)); } else { map.put(ih, il.append(c)); } } /* Pass 2: Update branch targets. */ InstructionHandle ih = start; InstructionHandle ch = il.start; while (ih != null) { Instruction i = ih.instruction; Instruction c = ch.instruction; if (i instanceof BranchInstruction) { BranchInstruction bi = (BranchInstruction) i; BranchInstruction bc = (BranchInstruction) c; InstructionHandle itarget = bi.getTarget(); // old target // New target is in hash map bc.setTarget(map.get(itarget)); if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH InstructionHandle[] itargets = ((Select) bi).getTargets(); InstructionHandle[] ctargets = ((Select) bc).getTargets(); for (int j = 0; j < itargets.length; j++) { // Update all targets ctargets[j] = map.get(itargets[j]); } } } ih = ih.next; ch = ch.next; } return il; }
/** * Initialize list with (nonnull) compound instruction. Consumes argument list, i.e., it becomes * empty. * * @param c compound instruction (list) */ public InstructionList(CompoundInstruction c) { append(c.getInstructionList()); }
/** * Create instruction list containing one instruction. * * @param i initial instruction */ public InstructionList(BranchInstruction i) { append(i); }
/** * Create instruction list containing one instruction. * * @param i initial instruction */ public InstructionList(Instruction i) { append(i); }
/** * Append a branch instruction to the end of this list. * * @param i branch instruction to append * @return branch instruction handle of the appended instruction */ public BranchHandle append(BranchInstruction i) { BranchHandle ih = BranchHandle.getBranchHandle(i); append(ih); return ih; }
/** * Append an instruction to the end of this list. * * @param i instruction to append * @return instruction handle of the appended instruction */ public InstructionHandle append(Instruction i) { InstructionHandle ih = InstructionHandle.getInstructionHandle(i); append(ih); return ih; }