⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 instructionlist.java

📁 Java Bytecode Editor 是一个 JAVA 的字节码反汇编和修改器。它可以很方便的修改已经编译成 Class 文件的 JAVA 文件。
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
   * @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 + -