コード例 #1
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());
   }
 }
コード例 #2
0
  /**
   * Replace instruction ih in list il with the instructions in new_il. If new_il is null, do
   * nothing
   */
  protected static void replace_instructions(
      InstructionList il, InstructionHandle ih, InstructionList new_il) {

    if ((new_il == null) || new_il.isEmpty()) return;

    // If there is only one new instruction, just replace it in the handle
    if (new_il.getLength() == 1) {
      ih.setInstruction(new_il.getEnd().getInstruction());
      return;
    }

    // Get the start and end instruction of the new instructions
    InstructionHandle new_end = new_il.getEnd();
    InstructionHandle new_start = il.insert(ih, new_il);

    // Move all of the branches from the old instruction to the new start
    il.redirectBranches(ih, new_start);

    // Move other targets to the new instuctions.
    if (ih.hasTargeters()) {
      for (InstructionTargeter it : ih.getTargeters()) {
        if (it instanceof LineNumberGen) {
          it.updateTarget(ih, new_start);
        } else if (it instanceof LocalVariableGen) {
          it.updateTarget(ih, new_end);
        } else if (it instanceof CodeExceptionGen) {
          CodeExceptionGen exc = (CodeExceptionGen) it;
          if (exc.getStartPC() == ih) exc.updateTarget(ih, new_start);
          else if (exc.getEndPC() == ih) exc.updateTarget(ih, new_end);
          else if (exc.getHandlerPC() == ih) exc.setHandlerPC(new_start);
          else System.out.printf("Malformed CodeException: %s%n", exc);
        } else {
          System.out.printf("unexpected target %s%n", it);
        }
      }
    }

    // Remove the old handle.  There should be no targeters left to it.
    try {
      il.delete(ih);
    } catch (Exception e) {
      throw new Error("Can't delete instruction", e);
    }
  }