interfacemethodtable.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 214 行

JAVA
214
字号
/* * @(#)InterfaceMethodTable.java	1.19 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */package vm;import java.util.Hashtable;import java.util.Enumeration;import components.ClassInfo;import components.MethodInfo;import components.MethodConstant;import util.*;import consts.Const;/* * This class will build * the imethodtable, used by JDK1.1 for a quicker implementation * of invokeinterface_quick. *  * This class should be subclassed in a target-machine-specific way * to provide writing out the data structure we build here.  * See also InterfaceMethodFactory for the mechanism used to call back * into that target-specific body of code. *  * Each ClassInfo is already decorated with a vector of * all the interfaces it implements.  * Each ClassInfo's allInterfaces vector has its parent's vector as prefix. * So: * A) a class which implements the same number of interfaces as its parent *    necessarily implements the same set of interfaces, and can use its *    parent's table, by reference. * B) for those classes for which a table must indeed be built, *    Only the interface elements associated with the present *    ClassInfo need to have a method index table built. */public abstractclass InterfaceMethodTable {    public ClassClass	   parent;    public String	   name;    public InterfaceVector iv[];    protected InterfaceMethodTable( ClassClass c, String n, InterfaceVector v[] ){	parent = c;	name = n;	iv = v;    }    private static MethodInfo findSlot( MethodInfo mit[], MethodInfo m ){	if ( mit != null ){	    MethodInfo v;	    int nt = mit.length;	    int ID = m.getID();	    for( int i = 0; i < nt; i++ ){		if ((v = mit[i]).getID() == ID )		    return v;	    }	}	return null;    }    /*     * Iterate through the methods of an interface.     * For the non-static members (i.e. the non-<clinit> )     * assign a zero-based index, and use the methodTableIndex field     * to keep it in.     */    public void     indexInterfaceMethods( ClassInfo c ){	if ( (c.access&Const.ACC_INTERFACE) == 0 ){	    System.err.println(Localizer.getString("javacodecompact.not_an_interface", c.className));	    return; // this is bad	}	int j = 0;	MethodInfo m[] = c.methods;	if ( m == null ) return; // no methods here.	int n = m.length;	for( int i =0; i < n; i++ ){	    MethodInfo t = m[i];	    if ( (t.access&Const.ACC_STATIC) != 0 )		continue; // don't number statics.	    if ( (t.access&Const.ACC_ABSTRACT) == 0 ){		System.err.println(Localizer.getString("javacodecompact.concrete_method_in_interface", c.className, t));		// but keep going anyway...	    }	    t.methodTableIndex = j++;	}    }    private static InterfaceMethodTable    generateTablesForInterface( ClassInfo c, String imtName, InterfaceMethodFactory imf ){	//	// We generate a thing like an imethodtable for interfaces, too.	// But its different enough that I'm treating it separately, here.	//	// Cannot share our imethotable with our superclass,	// as it must at least include ourselves!	//	// struct imethodtable { 	//     int icount;	//     struct { 	// 	ClassClass *classdescriptor;	// 	unsigned long *offsets = 0;	//     } itable[1];	// }	ClassClass me = c.vmClass;	int ntotal = c.allInterfaces.size();	InterfaceVector ivec[] = new InterfaceVector[ ntotal+1 ];	// first the entry for ourselves.	ivec[ 0 ] = new InterfaceVector( me, c, null );	// now all the others (if any)	for( int i = 0; i< ntotal; i++){	    ClassInfo intf = (ClassInfo)c.allInterfaces.elementAt( i );	    ivec[ i+1 ] = new InterfaceVector( me, intf, null );	}	return imf.newInterfaceMethodTable( me, imtName, ivec );    }    public static InterfaceVector    generateInterfaceVector( ClassInfo thisClass, ClassInfo intf ){	MethodInfo mtab[] = intf.methodtable;	int nmethods = mtab.length;	short ivec[] = new short[ nmethods ];	for( int j = 0; j < nmethods; j++ ){	    MethodInfo target = mtab[j];	    if ( (target.access&Const.ACC_STATIC) != 0 ){		// should never happen.		System.err.println(Localizer.getString(                    "javacodecompact.static_method_in_interface",                    intf.className, target));		continue;	    }	    MethodInfo v = findSlot( thisClass.methodtable, target );	    if ( v == null ){		System.err.println(Localizer.getString(                    "javacodecompact.interface_unimplemented",                    thisClass.className, intf.className, target));		ivec[ j ] = 0;	    } else {		ivec[ j ] = (short)v.methodTableIndex;	    }	}	return new InterfaceVector( thisClass.vmClass, intf, ivec );    }    public static InterfaceMethodTable    generateInterfaceTable( ClassClass cc, InterfaceMethodFactory imf ){	ClassInfo c = cc.classInfo;	if (c.allInterfaces == null) {	    c.findAllInterfaces();        }	String imtName = c.getGenericNativeName() + "_intfMethodtable";	ClassInfo sup = c.superClassInfo;	int ntotal = c.allInterfaces.size();	int nsuper = 0;	if ( (c.access&Const.ACC_INTERFACE) != 0 ){	    return generateTablesForInterface( c, imtName, imf );	}	if ( sup != null ){	    if ( sup.vmClass.inf == null ){   		// generate parental information,		// that we might borrow it.		sup.vmClass.inf = generateInterfaceTable( sup.vmClass, imf );	    }	    nsuper = sup.allInterfaces.size();	    if ( nsuper == ntotal ){		// use other class's tables entirely.		// we have nothing further to add.		return sup.vmClass.inf;	    }	}	//	// generate the offset tables, or symbolic references	// to them.	InterfaceVector vec[] = new InterfaceVector[ ntotal ];	if ( nsuper != 0 ){	    // borrow some from superclass. They are the same.	    System.arraycopy( sup.vmClass.inf.iv, 0, vec, 0, nsuper );	}	// compute the rest of the thing ourselves.	for( int i = nsuper; i < ntotal; i++ ){	    ClassInfo intf = (ClassInfo)c.allInterfaces.elementAt( i );	    vec[ i ] = generateInterfaceVector( c, intf );	}	return imf.newInterfaceMethodTable( cc, imtName, vec );    }}

⌨️ 快捷键说明

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