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

📄 methodgen.java

📁 代码是一个分类器的实现,其中使用了部分weka的源代码。可以将项目导入eclipse运行
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package de.fub.bytecode.generic;import de.fub.bytecode.Constants;import de.fub.bytecode.classfile.*;import java.util.*;/**  * Template class for building up a method. This is done by defining exception * handlers, adding thrown exceptions, local variables and attributes, whereas * the `LocalVariableTable' and `LineNumberTable' attributes will be set * automatically for the code. Use stripAttributes() if you don't like this. * * While generating code it may be necessary to insert NOP operations. You can * use the `removeNOPs' method to get rid off them. * The resulting method object can be obtained via the `getMethod()' method. * * @version $Id: MethodGen.java,v 1.20 2001/10/11 11:59:27 dahm Exp $ * @author  <A HREF="http://www.berlin.de/~markus.dahm/">M. Dahm</A> * @author  <A HREF="http://www.vmeng.com/beard">Patrick C. Beard</A> * @see     InstructionList * @see     Method */public class MethodGen extends FieldGenOrMethodGen {  private String          class_name;  private Type[]          arg_types;  private String[]        arg_names;  private int             max_locals;  private int             max_stack;  private InstructionList il;  private boolean         strip_attributes;  private Vector          variable_vec    = new Vector();  private Vector          line_number_vec = new Vector();  private Vector          exception_vec   = new Vector();  private Vector          throws_vec      = new Vector();  private Vector          code_attrs_vec  = new Vector();  /**   * Declare method. If the method is non-static the constructor   * automatically declares a local variable `$this' in slot 0. The   * actual code is contained in the `il' parameter, which may further   * manipulated by the user. But he must take care not to remove any   * instruction (handles) that are still referenced from this object.   *   * For example one may not add a local variable and later remove the   * instructions it refers to without causing havoc. It is safe   * however if you remove that local variable, too.   *   * @param access_flags access qualifiers   * @param return_type  method type   * @param arg_types argument types   * @param arg_names argument names (if this is null, default names will be provided   * for them)   * @param method_name name of method   * @param class_name class name containing this method (may be null, if you don't care)   * @param il instruction list associated with this method, may be null only for   * abstract or native methods   * @param cp constant pool   */  public MethodGen(int access_flags, Type return_type, Type[] arg_types,		   String[] arg_names, String method_name, String class_name,		   InstructionList il, ConstantPoolGen cp) {    setAccessFlags(access_flags);    setType(return_type);    setArgumentTypes(arg_types);    setArgumentNames(arg_names);    setName(method_name);    setClassName(class_name);    setInstructionList(il);    setConstantPool(cp);    if((access_flags & (Constants.ACC_ABSTRACT | Constants.ACC_NATIVE)) == 0) {      InstructionHandle start = il.getStart();      InstructionHandle end   = il.getEnd();      /* Add local variables, namely the implicit `this' and the arguments       */      if(!isStatic() && (class_name != null)) // Instance method -> `this' is local var 0	addLocalVariable("this", new ObjectType(class_name), start, end);      if(arg_types != null) {	int size = arg_types.length;		if(arg_names != null) { // Names for variables provided?	  if(size != arg_names.length)	    throw new ClassGenException("Mismatch in argument array lengths: " +					size + " vs. " + arg_names.length);	} else { // Give them dummy names	  arg_names = new String[size];	  for(int i=0; i < size; i++)	    arg_names[i] = "arg" + i;	  setArgumentNames(arg_names);	}	for(int i=0; i < size; i++)	  addLocalVariable(arg_names[i], arg_types[i], start, end);      }    }  }  /**   * Instantiate from existing method.   *   * @param m method   * @param class_name class name containing this method   * @param cp constant pool   */  public MethodGen(Method m, String class_name, ConstantPoolGen cp) {    this(m.getAccessFlags(), Type.getReturnType(m.getSignature()),	 Type.getArgumentTypes(m.getSignature()), null /* may be overridden anyway */,	 m.getName(), class_name,	 ((m.getAccessFlags() & (Constants.ACC_ABSTRACT | Constants.ACC_NATIVE)) == 0)?	 new InstructionList(m.getCode().getCode()) : null,	 cp);    Attribute[] attributes = m.getAttributes();    for(int i=0; i < attributes.length; i++) {      Attribute a = attributes[i];      if(a instanceof Code) {	Code c = (Code)a;	setMaxStack(c.getMaxStack());	setMaxLocals(c.getMaxLocals());		CodeException[] ces = c.getExceptionTable();		if(ces != null) {	  for(int j=0; j < ces.length; j++) {            CodeException ce     = ces[j];            int           type   = ce.getCatchType();            ObjectType    c_type = null;	    if(type > 0) {	      String cen = m.getConstantPool().getConstantString(type, Constants.CONSTANT_Class);	      c_type = new ObjectType(cen);	    }	    int end_pc = ce.getEndPC();	    int length = m.getCode().getCode().length;	    	    InstructionHandle end;	    if(length == end_pc) { // May happen, because end_pc is exclusive	      end = il.getEnd();	    } else {	      end = il.findHandle(end_pc);	      end = end.getPrev(); // Make it inclusive	    }	    addExceptionHandler(il.findHandle(ce.getStartPC()), end,				il.findHandle(ce.getHandlerPC()), c_type);	  }	}	Attribute[] c_attributes = c.getAttributes();	for(int j=0; j < c_attributes.length; j++) {	  a = c_attributes[j];	  if(a instanceof LineNumberTable) {	    LineNumber[] ln = ((LineNumberTable)a).getLineNumberTable();	    for(int k=0; k < ln.length; k++) {	      LineNumber l = ln[k];	      addLineNumber(il.findHandle(l.getStartPC()), l.getLineNumber());	    }	  } else if(a instanceof LocalVariableTable) {	    LocalVariable[] lv = ((LocalVariableTable)a).getLocalVariableTable();	    for(int k=0; k < lv.length; k++) {	      LocalVariable     l     = lv[k];	      InstructionHandle start = il.findHandle(l.getStartPC());	      InstructionHandle end   = il.findHandle(l.getStartPC() + l.getLength());	      // Repair malformed handles	      if(start == null)		start = il.getStart();	      if(end == null)		end = il.getEnd();	      addLocalVariable(l.getName(), Type.getType(l.getSignature()),			       l.getIndex(), start, end);	    }	  } else	    addCodeAttribute(a);	}      } else if(a instanceof ExceptionTable) {	String[] names = ((ExceptionTable)a).getExceptionNames();	for(int j=0; j < names.length; j++)	  addException(names[j]);      } else	addAttribute(a);    }  }  /**   * Adds a local variable to this method.   *   * @param name variable name   * @param type variable type   * @param slot the index of the local variable, if type is long or double, the next available   * index is slot+2   * @param start from where the variable is valid   * @param end until where the variable is valid   * @return new local variable object   * @see LocalVariable   */  public LocalVariableGen addLocalVariable(String name, Type type, int slot,					   InstructionHandle start,					   InstructionHandle end) {    byte t   = type.getType();    int  add = type.getSize();        if(slot + add > max_locals)       max_locals = slot + add;    LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end);    int i;    if((i = variable_vec.indexOf(l)) >= 0) // Overwrite if necessary      variable_vec.setElementAt(l, i);    else      variable_vec.addElement(l);    return l;  }  /**   * Adds a local variable to this method and assigns an index automatically.   *   * @param name variable name   * @param type variable type   * @param start from where the variable is valid, if this is null,   * it is valid from the start   * @param end until where the variable is valid, if this is null,   * it is valid to the end   * @return new local variable object   * @see LocalVariable   */  public LocalVariableGen addLocalVariable(String name, Type type,					   InstructionHandle start,					   InstructionHandle end) {    return addLocalVariable(name, type, max_locals, start, end);  }  /**   * Remove a local variable, its slot will not be reused, if you do not use addLocalVariable   * with an explicit index argument.   */  public void removeLocalVariable(LocalVariableGen l) {    variable_vec.removeElement(l);    }  /**   * Remove all local variables.   */  public void removeLocalVariables() {    variable_vec.removeAllElements();  }  /**   * Sort local variables by index   */  private static final void sort(LocalVariableGen[] vars, int l, int r) {    int i = l, j = r;    int m = vars[(l + r) / 2].getIndex();    LocalVariableGen h;    do {      while(vars[i].getIndex() < m) i++;      while(m < vars[j].getIndex()) j--;      if(i <= j) {        h=vars[i]; vars[i]=vars[j]; vars[j]=h; // Swap elements        i++; j--;      }    } while(i <= j);    if(l < j) sort(vars, l, j);    if(i < r) sort(vars, i, r);  }  /*   * If the range of the variable has not been set yet, it will be set to be valid from   * the start to the end of the instruction list.   *    * @return array of declared local variables sorted by index   */  public LocalVariableGen[] getLocalVariables() {    int                size = variable_vec.size();    LocalVariableGen[] lg   = new LocalVariableGen[size];    variable_vec.copyInto(lg);        for(int i=0; i < size; i++) {      if(lg[i].getStart() == null)	lg[i].setStart(il.getStart());      if(lg[i].getEnd() == null)	lg[i].setEnd(il.getEnd());    }    if(size > 1)      sort(lg, 0, size - 1);    return lg;  }  /**   * @return `LocalVariableTable' attribute of all the local variables of this method.   */  public LocalVariableTable getLocalVariableTable(ConstantPoolGen cp) {    LocalVariableGen[] lg   = getLocalVariables();    int                size = lg.length;    LocalVariable[]    lv   = new LocalVariable[size];    for(int i=0; i < size; i++)      lv[i] = lg[i].getLocalVariable(cp);    return new LocalVariableTable(cp.addUtf8("LocalVariableTable"),				  2 + lv.length * 10, lv, cp.getConstantPool());  }  /**   * Give an instruction a line number corresponding to the source code line.   *   * @param ih instruction to tag   * @return new line number object   * @see LineNumber   */  public LineNumberGen addLineNumber(InstructionHandle ih, int src_line) {    LineNumberGen l = new LineNumberGen(ih, src_line);    line_number_vec.addElement(l);    return l;  }  /**   * Remove a line number.   */  public void removeLineNumber(LineNumberGen l) {    line_number_vec.removeElement(l);    }  /**   * Remove all line numbers.   */  public void removeLineNumbers() {    line_number_vec.removeAllElements();  }  /*   * @return array of line numbers   */  public LineNumberGen[] getLineNumbers() {    LineNumberGen[] lg = new LineNumberGen[line_number_vec.size()];    line_number_vec.copyInto(lg);    return lg;  }  /**   * @return `LineNumberTable' attribute of all the local variables of this method.   */  public LineNumberTable getLineNumberTable(ConstantPoolGen cp) {    int          size = line_number_vec.size();     LineNumber[] ln   = new LineNumber[size];    try {      for(int i=0; i < size; i++)	ln[i] = ((LineNumberGen)line_number_vec.elementAt(i)).getLineNumber();    } catch(ArrayIndexOutOfBoundsException e) {} // Never occurs    return new LineNumberTable(cp.addUtf8("LineNumberTable"),			       2 + ln.length * 4, ln, cp.getConstantPool());  }  /**   * Add an exception handler, i.e., specify region where a handler is active and an   * instruction where the actual handling is done.   *   * @param start_pc Start of region (inclusive)   * @param end_pc End of region (inclusive)   * @param handler_pc Where handling is done   * @param catch_type fully qualified class name of handled exception or null if any   * exception is handled   * @return new exception handler object   */  public CodeExceptionGen addExceptionHandler(InstructionHandle start_pc,					      InstructionHandle end_pc,					      InstructionHandle handler_pc,					      ObjectType catch_type) {    if((start_pc == null) || (end_pc == null) || (handler_pc == null))      throw new ClassGenException("Exception handler target is null instruction");        CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc,					      handler_pc, catch_type);    exception_vec.addElement(c);    return c;  }  /**   * @deprecated Use above method   */  public CodeExceptionGen addExceptionHandler(InstructionHandle start_pc,					      InstructionHandle end_pc,					      InstructionHandle handler_pc,					      String catch_type) {    return addExceptionHandler(start_pc, end_pc, handler_pc, catch_type == null?			       null : new ObjectType(catch_type));  }  /**   * Remove an exception handler.   */  public void removeExceptionHandler(CodeExceptionGen c) {    exception_vec.removeElement(c);    }  /**   * Remove all line numbers.   */  public void removeExceptionHandlers() {    exception_vec.removeAllElements();  }  /*   * @return array of declared exception handlers   */  public CodeExceptionGen[] getExceptionHandlers() {    CodeExceptionGen[] cg   = new CodeExceptionGen[exception_vec.size()];    exception_vec.copyInto(cg);    return cg;  }  /**   * @return code exceptions for `Code' attribute   */  private CodeException[] getCodeExceptions() {    int             size  = exception_vec.size();     CodeException[] c_exc = new CodeException[size];    try {      for(int i=0; i < size; i++) {	CodeExceptionGen c = (CodeExceptionGen)exception_vec.elementAt(i);	c_exc[i] = c.getCodeException(cp);      }    } catch(ArrayIndexOutOfBoundsException e) {}        return c_exc;  }  /**   * Add an exception possibly thrown by this method.   *   * @param class_name (fully qualified) name of exception   */  public void addException(String class_name) {    throws_vec.addElement(class_name);  }  /**   * Remove an exception.   */  public void removeException(String c) {    throws_vec.removeElement(c);    }  /**   * Remove all exceptions.   */  public void removeExceptions() {    throws_vec.removeAllElements();    }

⌨️ 快捷键说明

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