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

📄 methodinfo.java

📁 已经移植好的java虚拟机
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*  *	MethodInfo.java	1.33	01/04/27 SMI * * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. * * This software is the confidential and proprietary information of Sun * Microsystems, Inc. ("Confidential Information").  You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Sun. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. * Use is subject to license terms. */package components;import java.io.DataInput;import java.io.DataOutput;import java.io.IOException;import java.io.PrintWriter;import java.io.StringWriter;import java.util.Hashtable;import vm.Const;import vm.EVMConst;import jcc.Util;import util.DataFormatException;// Class for representing every method in a classpublicclass MethodInfo extends ClassMemberInfo implements Const{    public int	argsSize;    public int	stack;    public int	locals;    public int	methodTableIndex = -1;    public byte	code[];    private Attribute		 methodAttributes[];    public CodeAttribute	 codeAttribute;    public Attribute	    	 codeAttributes[];    public ExceptionEntry	 exceptionTable[];    public ClassConstant	 exceptionsThrown[];    private boolean		 checkedDebugTables = false;    private LineNumberTableEntry lineNumberTable[];    private LocalVariableTableEntry localVariableTable[];    public  StackMapFrame        stackMapTable[];    public  vm.VMMethodInfo      vmMethodInfo;    /* An array of the methods called by invokevirtual_quick and     * invokevirtualobject_quick.  (After quickening, before inlining).      */    public MethodInfo[] targetMethods;    /**     * The following are arrays of indexes into the     * code array of references to the constant pool:     * ldcInstructions lists the instructions with a one-byte index.     * wideConstantRefInstructions lists the instructions with a two-byte index.     * In each case, the index is that of the opcode: the actual reference     * begins with the following byte.     * Entries of value -1 are ignored.     */    public int		ldcInstructions[];    public int		wideConstantRefInstructions[];    public MethodInfo( int name, int sig, int access, ClassInfo p ) {	super( name, sig, access, p );    }    public void    initializeClassDebugTables() {	int nattr = (codeAttributes == null) ? 0 : codeAttributes.length;	// parse code attributes	for (int i = 0; i < nattr; i++) {	    Attribute a = codeAttributes[i];	    if (a.name.string.equals("LineNumberTable")) {		lineNumberTable = ((LineNumberTableAttribute)a).data;	    }	    if (a.name.string.equals("LocalVariableTable")) {		localVariableTable = ((LocalVariableTableAttribute)a).data;	    }	    if (a.name.string.equals("StackMap")) {		stackMapTable = ((StackMapAttribute)a).data;	    }	}    }    public LineNumberTableEntry []    getLineNumberTable(){	if ( !checkedDebugTables ){	    initializeClassDebugTables();	    checkedDebugTables = true;	}	return lineNumberTable;    }    public LocalVariableTableEntry []    getLocalVariableTable(){	if ( !checkedDebugTables ){	    initializeClassDebugTables();	    checkedDebugTables = true;	}	return localVariableTable;    }    public boolean     hasLineNumberTable(){	if ( !checkedDebugTables ){	    initializeClassDebugTables();	    checkedDebugTables = true;	}	return (lineNumberTable != null) && (lineNumberTable.length != 0);    }    public boolean     hasLocalVariableTable(){	if ( !checkedDebugTables ){	    initializeClassDebugTables();	    checkedDebugTables = true;	}	return (localVariableTable != null) && (localVariableTable.length != 0);    }    public boolean    throwsExceptions(){	return exceptionsThrown != null;    }    public ClassConstant[]    getExceptionsThrown(){	return exceptionsThrown;    }    public int    nExceptionsThrown(){	return ( exceptionsThrown == null ) ? 0 : exceptionsThrown.length;    }    private String nativeName;    public String getNativeName(boolean isJNI) {         if (nativeName == null) { 	    nativeName = isJNI ? getJNIName() : getOldNativeName();	}	return nativeName;    }    private String getJNIName() {         ClassInfo ci = parent;        String classname = ci.className;	String methodname = this.name.string;	int nmethods = ci.methods.length;	String typeName = null;	// by default, don't need type	for (int j = 0; j < nmethods; j ++ ){	    MethodInfo m = ci.methods[j];	    if ((m != this) && ( (m.access&Const.ACC_NATIVE) != 0 )) {	        if (m.name.equals(this.name)) {		    // Two native methods with the same name.  Need type name		    typeName = this.type.string;		    break;		}	    }	} 	return Util.convertToJNIName(classname, methodname, typeName);    }    private String getOldNativeName() {         ClassInfo ci = parent;	String methodname = this.name.string;	StringBuffer sbuf = new StringBuffer(/*NOI18N*/"Java_")	                          .append(ci.getGenericNativeName())	                          .append('_');	if (methodname.indexOf('_') == -1) {	    // optimization.  Most methods don't have an _ in them	    sbuf.append(methodname);	} else { 	    for (int i = 0; i < methodname.length(); i++) { 	      if (methodname.charAt(i) == '_') {		  sbuf.append(/*NOI18N*/"_0005f");	      } else {		  sbuf.append(methodname.charAt(i));	      }	    }	}	sbuf.append("_stub");	return sbuf.toString();    }    /*     * A methods attributes are Code and Exceptions.     */    private static Hashtable methodAttributeTypes = new Hashtable();    static {	methodAttributeTypes.put( "Code", CodeAttributeFactory.instance );	methodAttributeTypes.put( "Exceptions", ExceptionsAttributeFactory.instance );    }    // Read in method attributes from classfile    void    readAttributes( DataInput in, ConstantObject locals[], ConstantObject globals[], boolean readCode ) throws IOException {	methodAttributes = Attribute.readAttributes( in, locals, globals, methodAttributeTypes, false );	// oops, we read the code.	// we'll fix this someday.	//	// parse special attributes	//	if ( methodAttributes != null ){	    for ( int i = 0; i < methodAttributes.length; i ++ ){		Attribute a = methodAttributes[i];		if (a.name.string.equals("Code") ) {		    CodeAttribute ca = (CodeAttribute)a;		    this.locals = ca.locals;		    this.stack  = ca.stack;		    this.code   = ca.code;		    this.exceptionTable = ca.exceptionTable;		    this.codeAttributes = ca.codeAttributes;		    this.codeAttribute = ca;		} else if (a.name.string.equals("Exceptions") ) {		    this.exceptionsThrown = ((ExceptionsAttribute)a).data;		}	    }	}    }    public static MethodInfo    readMethod( DataInput in, ClassInfo p, boolean readCode ) throws IOException {	int access = in.readUnsignedShort();	int name   = in.readUnsignedShort();	int sig    = in.readUnsignedShort();	MethodInfo m = new MethodInfo( name, sig, access, p );	// the bad thing is, we really cannot go far	// without resolving. So we resolve here.	m.resolve( p.symbols );	m.argsSize = Util.argsSize(m.type.string);	if ((m.access & ACC_STATIC) == 0) {	    m.argsSize++;	}	m.readAttributes( in, p.constants, p.symbols, readCode );	return m;    }    public void externalize( ConstantPool p ){	super.externalize( p );	Attribute.externalizeAttributes( methodAttributes, p );	Attribute.externalizeAttributes( codeAttributes, p );    }    public void write( DataOutput o ) throws IOException{	o.writeShort( access );	o.writeShort( name.index );	o.writeShort( type.index );	Attribute.writeAttributes( methodAttributes, o, false );    }    private static int getInt(byte[] code, int w) { 	return	(  (int)code[w]   << 24 ) |		(( (int)code[w+1] &0xff ) << 16 ) |		(( (int)code[w+2] &0xff ) << 8 ) |		 ( (int)code[w+3] &0xff );    }    public int getInt( int w ){	return	getInt(code, w);    }    public int getUnsignedShort( int w ){	return	(( (int)code[w] &0xff ) << 8 ) | ( (int)code[w+1] &0xff );    }    public int getShort( int w ){	return	(( (int)code[w]) << 8 ) | ( (int)code[w+1] &0xff );    }    //    // Private Utility functions    private void putInt(byte array[], int offset, int val) {        array[offset] =   (byte) ((val >> 24) & 0xFF);        array[offset+1] = (byte) ((val >> 16) & 0xFF);        array[offset+2] = (byte) ((val >> 8) & 0xFF);        array[offset+3] = (byte) (val & 0xFF);    }    private void putShort( int w, short v ){	code[w]   = (byte)(v>>>8);	code[w+1] = (byte)v;    }    public void findConstantReferences() throws DataFormatException {	if ( code == null ) return; // no code, no references.	int 	ldc[]  = new int[ code.length / 2 ];	int 	wide[] = new int[ code.length / 3 ];	int	nldc   = 0;	int	nwide  = 0;	int	ncode  = code.length;	int	opcode;	for( int i = 0; i < ncode; /*nothing*/){	    switch (opcode = (int)code[i]&0xff) {	    case opc_tableswitch:		i = (i + 4) & ~3;		int low = getInt( i+4);		int high = getInt( i+8);		i += (high - low + 1) * 4 + 12;		break;	    case opc_lookupswitch:		i = (i + 4) & ~3;		int pairs = getInt(i+4);		i += pairs * 8 + 8;		break;	    case opc_wide:		switch ((int)code[i+1]&0xff) {		case opc_aload:		case opc_iload:		case opc_fload:		case opc_lload:		case opc_dload:		case opc_istore:		case opc_astore:		case opc_fstore:		case opc_lstore:		case opc_dstore:		case opc_ret:		    i += 4;		    break;		case opc_iinc:		    i += 6;		    break;		default:		    throw new DataFormatException( parent.className + "." +			name.string + ": unknown wide " +

⌨️ 快捷键说明

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