cvminterfacemethodtable.java

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

JAVA
351
字号
/* * @(#)CVMInterfaceMethodTable.java	1.23 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 runtime;import vm.*;import components.*;import consts.Const;import java.util.Hashtable;/* * This is the CVM-specific subclass of vm.InterfaceMethodTable * It knowns how to write out these data structures for the CVM * This is similar to the CInterfaceMethodTable used for * JDK1.1-based systems. The substantial difference is * the ordering requirement: rather than having two representations * of interfaces, CVM has only one. Those this class implements * directly come first, followed by those inhereted. * Also note that the count of interfaced declared by the class is part of this * structure. This would seem to limit the ability of a child class to share data * with its parent in the case where the parent declares an interface * but the child does not. The CVM recognizes this case though, so this * sharing is allowed. Here's an odd example: * 	class a implements Serializeable {} *	class b extends a {} *		// b shares a's interface table *	class c extends a implements Serializeable {} *		// c cannot share a's interface table *		// though they are identical! */class CVMInterfaceMethodTable extends vm.InterfaceMethodTable {    // names we generate    public static final String vectorName = "CVMinterfaceVector";    int				implementsCount;    boolean			generated;    public    CVMInterfaceMethodTable( ClassClass c, String n, InterfaceVector v[] ){	super( c, n, v );	implementsCount = (c.classInfo.interfaces == null) ?                              0 : c.classInfo.interfaces.length;	generated = false;    }    private static void    sortInterfaceVectors( ClassInfo c, InterfaceVector v[], boolean isInterface ){	/*	 * Each of these interface vectors is correct, BUT order matters	 * We want to make sure that the entries for interfaces declared directly	 * by us come first in the list, AND that they are in the order declared!	 * so do a simple sort of them here.	 */	ClassConstant interfaces[] = c.interfaces;	int implementsCount = interfaces.length;	int l = v.length;	for ( int i = 0; i < implementsCount; i++ ){	    ClassInfo thisInterface = interfaces[i].find();	    for ( int j = i; j < l; j++ ){		if ( v[j].intf == thisInterface ){		    if ( i != j ){			// swap			InterfaceVector t = v[i];			v[i] = v[j];			v[j] = t;		    }		    break;		}	    }	}	if ( isInterface ){	    /*	     * put this class itself next.	     */	    // this will fail badly if this class is not present.	    int j = implementsCount;	    while ( v[j].intf != c ){		j++;	    }	    if ( j != implementsCount ){		// swap		InterfaceVector t = v[implementsCount];		v[implementsCount] = v[j];		v[j] = t;	    }	}    }    private static InterfaceMethodTable    generateTablesForInterface( ClassInfo c ){	//	// 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!	//	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 );	}	sortInterfaceVectors( c, ivec, true );	return new CVMInterfaceMethodTable(	    c.vmClass, "CVM_"+c.getGenericNativeName()+"_intfMethodtable", ivec );    }    /*     * Modified version from vm.InterfaceMethodTable for      * handling the special ordering and sharing needs of CVM.     */    public static InterfaceMethodTable    generateInterfaceTable( ClassClass cc ){	ClassInfo c = cc.classInfo;	if ( c.allInterfaces == null )	    c.findAllInterfaces();	ClassInfo sup = c.superClassInfo;	int ntotal = c.allInterfaces.size();	int nsuper = 0;	int implementsCount = (c.interfaces==null)?0:c.interfaces.length;	if ( (c.access&Const.ACC_INTERFACE) != 0 ){	    return generateTablesForInterface( c );	}	if ( sup != null ){	    if ( sup.vmClass.inf == null ){   		// generate parental information,		// that we might borrow it.		sup.vmClass.inf = generateInterfaceTable( sup.vmClass );	    }	    if ( implementsCount == 0 ){		// CVM allows sharing with parent if we have no		// declared interfaces ourselves.		// 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 );	}	/*	 * Each of these interface vectors is correct, BUT order matters	 * We want to make sure that the entries for interfaces declared directly	 * by us come first in the list, AND that they are in the order declared!	 * so do a simple sort of them here.	 */	sortInterfaceVectors( c, vec, false );	return new CVMInterfaceMethodTable(	    cc, "CVM_"+c.getGenericNativeName()+"_intfMethodtable", vec );    }    static void writeInterfaceTables(ClassClass[] classes, CCodeWriter out, CCodeWriter headerOut) {        int n = classes.length;	// generate the tables. generateInterfaceTable must work	// recursively, of course!	for ( int i = 0; i < n; i++ ){	    ClassClass c = classes[i];	    if ( c.inf == null )		c.inf = generateInterfaceTable(c );	}	//	// print the vectors first.	//	out.println( "STATIC const CVMUint16 " + vectorName + "[] = {");	int offset = 0;	boolean emptyVector = true;	for (int i = 0; i < n; i++) { 	    ClassClass c = classes[i];	    CVMInterfaceMethodTable simt = (CVMInterfaceMethodTable)c.inf;	    if (simt == null || simt.parent != c) 	        continue;	    InterfaceVector iv[] = simt.iv;	    for (int j = 0; j < iv.length; j++) { 	        InterfaceVector vec = iv[j];		if ( vec.generated )		    continue; // done.		vec.generated = true;		vec.offset = offset;		short vector[] = vec.v;		if ( (vector==null) || (vector.length == 0) ){		    continue;		}		int num = vector.length;		emptyVector = false;		out.comment(simt.parent.classInfo.className +                            " " + vec.intf.className);		for (int k = 0, mod = 0; k < num; k++) { 		    if (mod == 0) out.write('\t');		    out.printHexInt( vector[k] );		    out.write(',');		    if (++mod == 8) { 		        out.write('\n'); mod = 0;		    }		}		if ((num % 8) != 0) 		  out.write('\n');		offset += num;	    }	}	if ( emptyVector ){	    out.write('0');// make it non-empty!	}	out.println("};\n");	// end vectors.		//	// now write out the CVMInterfaces structures, which	// roughly correspond to the InterfaceMethodTables.	// But not quite.	//	for (int i = 0; i < n; i++) { 	    ClassClass c = classes[i];	    CVMInterfaceMethodTable simt = (CVMInterfaceMethodTable)c.inf;	    if ( simt != null ){	        simt.write(out, headerOut);	    }	}    }    private static boolean    needVector( InterfaceVector vec ){	if ( vec.v == null || vec.v.length == 0 ) return false; // don't bother.	return true;    }    private static java.util.BitSet	interfaceSizes = new java.util.BitSet();    private static final String		interfaceStructName = "CVMinterface";	    //struct CVMInterfaces {    //    CVMUint16      interfaceCount;    //    CVMUint16      implementsCount;    //    union {    //        CVMUint16* interfaces;    //        struct {    //            CVMClassBlock* interfacecb;    //            CVMUint16*     index;    //        } interfaceTable[1];    //    } intfInfo;    //};     private static String declareInterfaceStruct( int n, CCodeWriter out ){	String interfaceFlavor = "union "+interfaceStructName+n;	if ( ! interfaceSizes.get( n ) ){	    out.println(interfaceFlavor+" {");	    out.println("    struct {");	    out.println("        CVMUint16 interfaceCount; CVMUint16 implementsCount;");	    out.println("        struct { const CVMClassBlock* interfacecb;" +			" union {CVMUint16 * addr; CVMClassTypeID ti;} ext;" +			"} interfaceTable["+n+"];");	    out.println("    } dontAccess;");	    out.println("    CVMInterfaces interfaces;");	    out.println("};");	    interfaceSizes.set( n );	}	return interfaceFlavor;    }    public void    write( CCodeWriter out, CCodeWriter headerOut){        if (this.generated) 	    return;	this.generated = true;	if ( iv.length == 0 ){	    // omit structures of length 0	    return;	}    	String structType = declareInterfaceStruct( iv.length, headerOut );	/* 	 * Added 'extern' keyword, so that the header file does not	 * declare an (unnecessary) global variable for each struct	 * declaration (which would never be used anyway) */	headerOut.println("extern const "+structType+" "+name+";");	out.print("const "+structType+" "+name);	out.print(" = {{\n\t");	out.print( iv.length );	out.print(", ");	out.print( implementsCount );	out.println(", {");	for( int i = 0; i < iv.length; i++ ){	    InterfaceVector entry = iv[i];	    ClassInfo intf = entry.intf;	    String intfName = intf.getGenericNativeName();	    out.print("\t{ ");	    out.print("(CVMClassBlock*)&"+intfName);	    out.print("_Classblock.classclass,");	    if ( needVector( entry ) ){		/*		 * Cast to first type in union (CVMUint16 *).		 */		out.print("{(CVMUint16 *)&"+vectorName+"["+entry.offset+"]}");	    } else {		/*		 * Cast to first type in union (CVMUint16 *).		 */		out.print("{(CVMUint16 *)0}");	    }	    out.println(" },");	}	out.write('}');	out.println("}};");    }}

⌨️ 快捷键说明

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