예제 #1
0
 /**
  * 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++;
 }
예제 #2
0
 /**
  * Append an instruction to the end of this list.
  *
  * @param ih instruction to append
  */
 private void append(InstructionHandle ih) {
   if (isEmpty()) {
     start = end = ih;
     ih.next = ih.prev = null;
   } else {
     end.next = ih;
     ih.prev = end;
     ih.next = null;
     end = ih;
   }
   length++; // Update length
 }
예제 #3
0
 /**
  * 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) {
       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
   InstructionHandle prev = start.prev, next = end.next;
   if (prev != null) {
     prev.next = next;
   } else {
     this.start = next;
   }
   if (next != null) {
     next.prev = prev;
   } else {
     this.end = prev;
   }
   start.prev = end.next = null;
   // Step 3: append after target
   if (target == null) { // append to start of list
     if (this.start != null) {
       this.start.prev = end;
     }
     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;
     } else {
       this.end = end;
     }
   }
 }
예제 #4
0
 /**
  * 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)) {
     first = start;
     last = end;
     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;
   List<InstructionHandle> target_vec = new ArrayList<InstructionHandle>();
   for (InstructionHandle ih = first; ih != null; ih = ih.next) {
     ih.getInstruction().dispose(); // e.g. BranchInstructions release their targets
   }
   StringBuilder buf = new StringBuilder("{ ");
   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());
   }
 }
예제 #5
0
 /**
  * Insert another list before Instruction handle ih contained in this list. Consumes argument
  * list, i.e., it becomes empty.
  *
  * @param ih 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()) {
     return ih;
   }
   InstructionHandle prev = ih.prev, ret = il.start;
   ih.prev = il.end;
   il.end.next = ih;
   il.start.prev = prev;
   if (prev != null) {
     prev.next = il.start;
   } else {
     start = il.start; // Update start ...
   }
   length += il.length; // Update length
   il.clear();
   return ret;
 }
예제 #6
0
 /**
  * Append another list after instruction (handle) ih contained in this list. Consumes argument
  * list, i.e., it becomes empty.
  *
  * @param ih where to append the instruction list
  * @param il Instruction list to append to this one
  * @return instruction handle pointing to the <B>first</B> appended instruction
  */
 public InstructionHandle append(InstructionHandle ih, InstructionList il) {
   if (il == null) {
     throw new ClassGenException("Appending null InstructionList");
   }
   if (il.isEmpty()) {
     return ih;
   }
   InstructionHandle next = ih.next, ret = il.start;
   ih.next = il.start;
   il.start.prev = ih;
   il.end.next = next;
   if (next != null) {
     next.prev = il.end;
   } else {
     end = il.end; // Update end ...
   }
   length += il.length; // Update length
   il.clear();
   return ret;
 }