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

📄 instructionlist.java

📁 代码是一个分类器的实现,其中使用了部分weka的源代码。可以将项目导入eclipse运行
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
  public void setPositions(boolean check) {    int max_additional_bytes = 0, additional_bytes = 0;    int index = 0, count = 0;    int[] pos = new int[length];    /* Pass 0: Sanity checks     */    if(check) {      for(InstructionHandle ih=start; ih != null; ih = ih.next) {	Instruction i = ih.instruction;	if(i instanceof BranchInstruction) { // target instruction within list?	  Instruction inst = ((BranchInstruction)i).getTarget().instruction;	  if(!contains(inst))	    throw new ClassGenException("Branch target of " +					Constants.OPCODE_NAMES[i.opcode] + ":" +					inst + " not in instruction list");	  if(i instanceof Select) {	    InstructionHandle[] targets = ((Select)i).getTargets();	    	    for(int j=0; j < targets.length; j++) {	      inst = targets[j].instruction;	      if(!contains(inst))		throw new ClassGenException("Branch target of " +					    Constants.OPCODE_NAMES[i.opcode] + ":" +					    inst + " not in instruction list");	    }	  }	  if(!(ih instanceof BranchHandle))	    throw new ClassGenException("Branch instruction " +					Constants.OPCODE_NAMES[i.opcode] + ":" +					inst + " not contained in BranchHandle.");	}      }    }    /* Pass 1: Set position numbers and sum up the maximum number of bytes an     * instruction may be shifted.     */    for(InstructionHandle ih=start; ih != null; ih = ih.next) {      Instruction i = ih.instruction;      ih.setPosition(index);      pos[count++] = index;      /* Get an estimate about how many additional bytes may be added, because       * BranchInstructions may have variable length depending on the target       * offset (short vs. int) or alignment issues (TABLESWITCH and       * LOOKUPSWITCH).       */      switch(i.getOpcode()) {      case Constants.JSR: case Constants.GOTO:	max_additional_bytes += 2;	break;      case Constants.TABLESWITCH: case Constants.LOOKUPSWITCH:	max_additional_bytes += 3;	break;      }      index += i.getLength();    }        /* Pass 2: Expand the variable-length (Branch)Instructions depending on     * the target offset (short or int) and ensure that branch targets are     * within this list.     */    for(InstructionHandle ih=start; ih != null; ih = ih.next)      additional_bytes += ih.updatePosition(additional_bytes, max_additional_bytes);    /* Pass 3: Update position numbers (which may have changed due to the     * preceding expansions), like pass 1.     */    index=count=0;    for(InstructionHandle ih=start; ih != null; ih = ih.next) {      Instruction i = ih.instruction;      ih.setPosition(index);      pos[count++] = index;      index += i.getLength();    }    byte_positions = new int[count]; // Trim to proper size    System.arraycopy(pos, 0, byte_positions, 0, count);  }  /**   * When everything is finished, use this method to convert the instruction   * list into an array of bytes.   *   * @return the byte code ready to be dumped   */  public byte[] getByteCode() {    // Update position indices of instructions    setPositions();    ByteArrayOutputStream b   = new ByteArrayOutputStream();    DataOutputStream      out = new DataOutputStream(b);    try {      for(InstructionHandle ih=start; ih != null; ih = ih.next) {	Instruction i = ih.instruction;	i.dump(out); // Traverse list      }    } catch(IOException e) {       System.err.println(e);      return null;    }    return b.toByteArray();  }  /**   * @return an array of instructions without target information for branch instructions.   */  public Instruction[] getInstructions() {    ByteSequence  bytes        = new ByteSequence(getByteCode());    Vector        instructions = new Vector();    try {      while(bytes.available() > 0) {	instructions.addElement(Instruction.readInstruction(bytes));      }    } catch(IOException e) { throw new ClassGenException(e.toString()); }    Instruction[] result = new Instruction[instructions.size()];    instructions.copyInto(result);    return result;  }  public String toString() {    return toString(true);  }  /**   * @param verbose toggle output format   * @return String containing all instructions in this list.   */   public String toString(boolean verbose) {    StringBuffer buf = new StringBuffer();    for(InstructionHandle ih=start; ih != null; ih = ih.next) {      buf.append(ih.toString(verbose) + "\n");    }    return buf.toString();  }  /**   * @return Enumeration that lists all instructions (handles)   */  public Enumeration elements() {    return new Enumeration() {      private InstructionHandle ih = start;      public Object nextElement() {	InstructionHandle i = ih;	ih = ih.next;	return i;      }      public boolean hasMoreElements() { return ih != null; }    };  }  /**   * @return array containing all instructions (handles)   */  public InstructionHandle[] getInstructionHandles() {    InstructionHandle[] ihs = new InstructionHandle[length];    InstructionHandle   ih  = start;    for(int i=0; i < length; i++) {      ihs[i] = ih;      ih = ih.next;    }    return ihs;  }  /**   * Get positions (offsets) of all instructions in the list. This relies on that   * the list has been freshly created from an byte code array, or that setPositions()   * has been called. Otherwise this may be inaccurate.   *   * @return array containing all instruction's offset in byte code   */  public int[] getInstructionPositions() { return byte_positions; }  /**   * @return complete, i.e., deep copy of this list   */  public InstructionList copy() {    Hashtable       map = new Hashtable();    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((InstructionHandle)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] = (InstructionHandle)map.get(itargets[j]);	  }	}      }      ih = ih.next;      ch = ch.next;    }    return il;  }  /** Replace all references to the old constant pool with references to the new   *  constant pool   */  public void replaceConstantPool(ConstantPoolGen old_cp, ConstantPoolGen new_cp) {    for(InstructionHandle ih=start; ih != null; ih = ih.next) {      Instruction i = ih.instruction;      if(i instanceof CPInstruction) {	CPInstruction ci = (CPInstruction)i;	Constant      c  = old_cp.getConstant(ci.getIndex());	ci.setIndex(new_cp.addConstant(c, old_cp));      }    }      }  private void clear() {    start = end = null;    length = 0;  }  /**   * Delete contents of list. Provides besser memory utilization,   * because the system then may reuse the instruction handles. This   * method is typically called right after   * <href="MethodGen.html#getMethod()">MethodGen.getMethod()</a>.   */  public void dispose() {    // Traverse in reverse order, because ih.next is overwritten    for(InstructionHandle ih=end; ih != null; ih = ih.prev)      /* Causes BranchInstructions to release target and targeters, because it       * calls dispose() on the contained instruction.       */      ih.dispose();    clear();  }  /**   * @return start of list   */  public InstructionHandle getStart() { return start; }  /**   * @return end of list   */  public InstructionHandle getEnd()   { return end; }  /**   * @return length of list (Number of instructions, not bytes)   */  public int getLength() { return length; }  /**   * @return length of list (Number of instructions, not bytes)   */  public int size() { return length; }  /**   * Redirect all references from old_target to new_target, i.e., update targets    * of branch instructions.   *   * @param old_target the old target instruction handle   * @param new_target the new target instruction handle   */  public void redirectBranches(InstructionHandle old_target, 			       InstructionHandle new_target) {    for(InstructionHandle ih = start; ih != null; ih = ih.next) {      Instruction i  = ih.getInstruction();      if(i instanceof BranchInstruction) {	BranchInstruction b      = (BranchInstruction)i;	InstructionHandle target = b.getTarget();	if(target == old_target)	  b.setTarget(new_target);	if(b instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH	  InstructionHandle[] targets = ((Select)b).getTargets();	  	  for(int j=0; j < targets.length; j++) // Update targets	    if(targets[j] == old_target)	      ((Select)b).setTarget(j, new_target);	}      }    }  }  /**   * Redirect all references of local variables from old_target to new_target.   *   * @@param lg array of local variables   * @@param old_target the old target instruction handle   * @@param new_target the new target instruction handle   * @@see MethodGen   */  public void redirectLocalVariables(LocalVariableGen[] lg,				     InstructionHandle old_target, 				     InstructionHandle new_target) {    for(int i=0; i < lg.length; i++) {      InstructionHandle start = lg[i].getStart();      InstructionHandle end   = lg[i].getEnd();            if(start == old_target)	lg[i].setStart(new_target);      if(end == old_target)	lg[i].setEnd(new_target);    }  }  /**   * Redirect all references of exception handlers from old_target to new_target.   *   * @@param exceptions array of exception handlers   * @@param old_target the old target instruction handle   * @@param new_target the new target instruction handle   * @@see MethodGen   */  public void redirectExceptionHandlers(CodeExceptionGen[] exceptions,					InstructionHandle old_target, 					InstructionHandle new_target) {    for(int i=0; i < exceptions.length; i++) {      if(exceptions[i].getStartPC() == old_target)	exceptions[i].setStartPC(new_target);      if(exceptions[i].getEndPC() == old_target)	exceptions[i].setEndPC(new_target);      if(exceptions[i].getHandlerPC() == old_target)	exceptions[i].setHandlerPC(new_target);    }  }  private Vector observers;  /** Add observer for this object.   */  public void addObserver(InstructionListObserver o) {    if(observers == null)      observers = new Vector();    observers.addElement(o);  }  /** Remove observer for this object.   */  public void removeObserver(InstructionListObserver o) {    if(observers != null)      observers.removeElement(o);  }  /** Call notify() method on all observers. This method is not called   * automatically whenever the state has changed, but has to be   * called by the user after he has finished editing the object.   */  public void update() {    if(observers != null)      for(Enumeration e = observers.elements(); e.hasMoreElements(); )	((InstructionListObserver)e.nextElement()).notify(this);  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -