cvmwriter.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,949 行 · 第 1/5 页

JAVA
1,949
字号
	    boolean isAbstract= (access&CVM_METHOD_ACC_ABSTRACT) != 0;	    //	    // Item #2	    //	    String invoker = isAbstract ? "CVM_INVOKE_ABSTRACT_METHOD"			  : isNative ? (				isClassCNI(c.classInfo.className) ?				    "CVM_INVOKE_CNI_METHOD" : (				synchro ? "CVM_INVOKE_JNI_SYNC_METHOD"					: "CVM_INVOKE_JNI_METHOD" ))			  : (				synchro ? "CVM_INVOKE_JAVA_SYNC_METHOD"					: "CVM_INVOKE_JAVA_METHOD" );	    //	    // note the offset in the exception array,	    // and add to that array as necessary.	    //	    int exceptions;	    if ((meth.method.exceptionsThrown != null) &&                (meth.method.exceptionsThrown.length != 0)) {		ClassConstant thrown[] = meth.method.exceptionsThrown;		int net = thrown.length;	        exceptions = currCheckedException;		checkedExceptionVector[currCheckedException++] = net;		for ( int j = 0; j < net; j++ ){		    checkedExceptionVector[currCheckedException++] =                        thrown[j].index;		}	    } else {		// Note we have changed this from ((unsigned short)		// -1) to 0 to be consistent with the documentation in		// classes.h. A checkedExceptionsOffset of 0 indicates		// no checked exceptions for the method. Also see the		// allocation of the checkedExceptionVector above.		exceptions = 0;	    }	    //	    // Item #3	    //	    int argssize   = meth.method.argsSize;	    int tableIndex = meth.methodOffset();	    	    //	    // Remember these items	    // We won't know whether a class is compressible	    // until after all the triples for all methods have been seen	    //	    methStats.record(argssize, invoker, access);	    // 	    // Also see whether the method table index and	    // checkedExceptionsOffset are encodable in one byte each.	    //	    if (tableIndex >= 256) {		c.setCompressible(false);	    }	    if (exceptions >= 256) {		c.setCompressible(false);	    }	}    }    void writeMethods(CVMClass c) {	boolean isCompressible = c.isCompressible();	String cbname_comma = "&" + cbName(c) + ",";	CVMMethodInfo m[] = c.methods;	int nCheckedExceptions = 0;	int currCheckedException = 0;	int checkedExceptionVector[];	boolean writableMethods = mutableMBs;	if ( (m == null) || (m.length == 0 )){	    methodArrayName = "0";	    checkedExceptionName = "0";	    methodTableSize = 0;	    return;	}	int nmethod =  m.length;	String thisTableName = c.getNativeName()+"_methods";	String thisExceptionName = null;	for ( int i = 0; i < nmethod; i++ ){	    CVMMethodInfo meth = m[i];	    MethodInfo    mi   = meth.method;	    if ( mi.exceptionsThrown != null ){		int n = mi.exceptionsThrown.length;		if ( n != 0 )		    nCheckedExceptions += n+1; // "1" is for the count word.	    }	    if ( mi.code != null ){		writeCode( meth );	    }	    if ( meth.codeHasJsr() ){		writableMethods = true;	    }	}	//	// if any methods declare that they throw any exceptions,	// we need to construct the exception vector.	if ( nCheckedExceptions == 0 ){	    checkedExceptionName = "0";	    checkedExceptionVector = null;	} else {	    thisExceptionName = c.getNativeName()+"_throws";	    checkedExceptionName = thisExceptionName;	    // Ensure that item 0 in this array is always unused.	    // See classes.h.	    nCheckedExceptions++;	    checkedExceptionVector = new int[ nCheckedExceptions ];	    checkedExceptionVector[0] = 0;	    currCheckedException = 1;	}	boolean emittedNativeHeader = false;	//	// Look to see whether we can compact this	//	for ( int i = 0; i < nmethod; i++ ){	    CVMMethodInfo meth = m[i];	    int access = meth.CVMflags();	    if (!emittedNativeHeader &&		((access&CVM_METHOD_ACC_NATIVE)!=0)) {		String subdir;		subdir = isClassCNI(c.classInfo.className) ? "cni/" : "jni/";		headerOut.println("#include \"generated/" + subdir +		    Util.convertToClassName(c.classInfo.className)+".h\"");		emittedNativeHeader = true;	    }	    boolean synchro = (access&CVM_METHOD_ACC_SYNCHRONIZED)!=0;	    boolean isNative  = (access&CVM_METHOD_ACC_NATIVE)!=0;	    boolean isAbstract= (access&CVM_METHOD_ACC_ABSTRACT) != 0;	    String invoker = isAbstract ? "CVM_INVOKE_ABSTRACT_METHOD"			  : isNative ? (				isClassCNI(c.classInfo.className) ?				    "CVM_INVOKE_CNI_METHOD" : (				synchro ? "CVM_INVOKE_JNI_SYNC_METHOD"					: "CVM_INVOKE_JNI_METHOD" ))			  : (				synchro ? "CVM_INVOKE_JAVA_SYNC_METHOD"					: "CVM_INVOKE_JAVA_METHOD" );	    int argssize   = meth.method.argsSize;	    	    CVMMethodStats.Entry entry =		methStats.lookup(argssize, invoker, access);	    //	    // Cannot encode in one byte, therefore cannot compress	    //	    if (entry.getIdx() >= 256) {		c.setCompressible(false);	    }	    meth.statsEntry = entry;	}	//	// Update the compressibility of class c	//	isCompressible = isCompressible && c.isCompressible();	//	// isCompressible cannot be true if the mb's are to be read-only	//	isCompressible = isCompressible && writableMethods;		// if any method has a JSR, then its method block, and thus	// all of them, must be writable, so we can replace its code, bundled	// with its JavaMethodDescriptor.	declareMethodArray( c, writableMethods, isCompressible );	String cbDeclaration;		if (isCompressible) {	    cbDeclaration = "CVM_INIT_METHODARRAY_CB_WITH_COMPRESSED_MBS";	} else {	    cbDeclaration = "CVM_INIT_METHODARRAY_CB_WITH_UNCOMPRESSED_MBS";	}		classOut.print(" = {\n\t" + cbDeclaration + "(&" + classBlockName +                       "),\n\t{\n");	for ( int i = 0; i < nmethod; i++ ){	    CVMMethodInfo meth = m[i];	    if (meth.method.hasCheckinits) {		nMethodsWithCheckinitInvokes++;	    }	    int mbIndex = i % cbRepeat;	    int typeid = meth.sigType.entryNo;	    int nameid = CVMMemberNameEntry.lookupEnter(                             getUTF(meth.method.name));	    String nameAndType = "RAW_TYPEID(0x" +                                 Integer.toHexString(nameid) + ", 0x" +                                 Integer.toHexString(typeid) + ")";	    int access = meth.CVMflags();	    boolean synchro = (access&CVM_METHOD_ACC_SYNCHRONIZED)!=0;	    boolean isNative  = (access&CVM_METHOD_ACC_NATIVE)!=0;	    boolean isAbstract= (access&CVM_METHOD_ACC_ABSTRACT) != 0;	    String invoker = meth.statsEntry.getInvoker();	    /* By default let interpreter do invocation in all	       except native methods. Compilation might change	       invoker function */	    String jitInvoker = isNative ? (				    isClassCNI(c.classInfo.className) ?				        "CVMCCMinvokeCNIMethod" :				        "CVMCCMinvokeJNIMethod" )		                : "CVMCCMletInterpreterDoInvoke";	    	    //	    // note the offset in the exception array,	    // and add to that array as necessary.	    int exceptions;	    if ((meth.method.exceptionsThrown != null) &&                (meth.method.exceptionsThrown.length != 0)) {		ClassConstant thrown[] = meth.method.exceptionsThrown;		int net = thrown.length;	        exceptions = currCheckedException;		checkedExceptionVector[currCheckedException++] = net;		for ( int j = 0; j < net; j++ ){		    checkedExceptionVector[currCheckedException++] =                        thrown[j].index;		}	    } else {		// Note we have changed this from ((unsigned short)		// -1) to 0 to be consistent with the documentation in		// classes.h. A checkedExceptionsOffset of 0 indicates		// no checked exceptions for the method. Also see the		// allocation of the checkedExceptionVector above.		exceptions = 0;	    }	    int argssize   = meth.method.argsSize;	    int tableIndex = meth.methodOffset();	    	    /* 	     * method offsets are always mod 'cbRepeat' and we have to	     * emit a cb entry before each block of 'cbRepeat'	     * methods. 	     */	    if ((mbIndex == 0) && (i != 0) && 		!isCompressible && !writableMethods) {		// Output the repeated cb only if we are emitting read-only		// method blocks.		classOut.print( "\t},\n");		classOut.print( "\t&"+classBlockName+",\n\t{\n" );	    }	    if (isCompressible) {		// The C compiler checks that the values here are		// really compressed within the proper sizes. We get		// warnings if we exceed the maximum width for a given		// data field.		//		// entryIdx encapsulates argssize, invoker, and access flags		int entryIdx = meth.statsEntry.getIdx();		classOut.print("\tCVM_INIT_METHODBLOCK_IMMUTABLE_COMPRESSED(" +                               cbname_comma + nameAndType + "," + tableIndex +                               "," + entryIdx + "," + mbIndex + "," +                               exceptions + ",");	    } else if (writableMethods) {		classOut.print("\tCVM_INIT_METHODBLOCK_IMMUTABLE(" +                               cbname_comma + nameAndType + "," + tableIndex +                               "," + argssize + "," + invoker + "," + access +                               "," + mbIndex + "," + exceptions + ",");	    } else {		classOut.print("\tCVM_INIT_METHODBLOCK(" + cbname_comma +                               jitInvoker + "," + nameAndType + "," +                               tableIndex + "," + argssize + "," +                               invoker + "," + access + "," + mbIndex +                               "," + exceptions + ",");	    }	    	    if ( isAbstract ){		classOut.print("(CVMJavaMethodDescriptor*)"+i+"),\n");	    } else if ( isNative ){		if (isClassCNI(c.classInfo.className)) {		    String jniName = meth.method.getNativeName(true);		    String eniName = "CNI" + jniName.substring(5);		    classOut.print("(CVMJavaMethodDescriptor*)&" + eniName +                                   "),\n");		} else {		    classOut.print("(CVMJavaMethodDescriptor*)&" +			meth.method.getNativeName(true)+"),\n");		}	    } else {		classOut.print("&(" + meth.getNativeName() + ".u.jmd)),\n");	    }	}	classOut.print("}};\n");        this.nmethods += nmethod;	if (writableMethods) {	    nClassesWithWritableMethodBlocks += 1;	    nWritableMethodBlocks += nmethod;	}	//	// now, if there are any exception-catch clauses	// that need to be represented, print out the table.	if (nCheckedExceptions != 0) {	    classOut.println("STATIC const CVMUint16 " + thisExceptionName +                             "[] = {");	    int j = 0;	    for (int i = 0; i < nCheckedExceptions; i++) {		if (j >= 8) {		    classOut.print("\n    ");		    j = 0;		} else {		    j += 1;		}		classOut.print( checkedExceptionVector[i]+", ");	    }	    classOut.println("\n};");	}    }    /*     * Write out the InnerClassInfo structure. This structure will contain     * information about all referenced inner classes.     */    private void    writeInnerClasses(CVMClass c) { 	//Write information about each inner class contained in this class.	int innerClassCount = c.classInfo.innerClassAttr.getInnerClassCount();	InnerClassAttribute ica = c.classInfo.innerClassAttr;	classOut.println("    " + innerClassCount + ", {");	for (int j=0; j < innerClassCount; j++) {	    // write out the indexes and access flags of this inner class.	    classOut.print("        {");	    classOut.print(ica.getInnerInfoIndex(j));	    classOut.write(',');	    classOut.print(ica.getOuterInfoIndex(j));	    classOut.write(',');	    /* innerNameIndex not supported because utf8 cp entries	     * are not kept around.	    classOut.print(ica.getInnerNameIndex(j));	    */	    classOut.print('0');	    classOut.write(',');	    classOut.print(ica.getAccessFlags(j));	    classOut.print("},\n");	}	classOut.println("    }");	ninnerclasses += innerClassCount;    }    void mungeAllIDsAndWriteExternals(ClassClass classes[]) {     }    private static int CVMDataAccessFlags( int access ){	int a = 0;	if ( (access&ACC_PUBLIC) != 0 ) a |= CVM_FIELD_ACC_PUBLIC;	if ( (access&ACC_PRIVATE) != 0 ) a |= CVM_FIELD_ACC_PRIVATE;	if ( (access&ACC_PROTECTED) != 0 ) a |= CVM_FIELD_ACC_PROTECTED;	if ( (access&ACC_STATIC) != 0 ) a |= CVM_FIELD_ACC_STATIC;	if ( (access&ACC_FINAL) != 0 ) a |= CVM_FIELD_ACC_FINAL;	if ( (access&ACC_VOLATILE) != 0 ) a |= CVM_FIELD_ACC_VOLATILE;	if ( (access&ACC_TRANSIENT) != 0 ) a |= CVM_FIELD_ACC_TRANSIENT;	return a;    }    private void declareFieldArray( CVMClass c ){	// Note: Should deal with > 255 fields.	// Today is not that day. Just do the simple case.	FieldInfo m[] = c.classInfo.fields;	int nfields = m.length;	String thisTableName = c.getNativeName()+"_fields";	String fieldArrayFlavor = "struct CVMFieldArray"+nfields;	if ( !fieldArraySizes.get( nfields ) ){	    // need to declare a structure containing a classblock pointer	    // plus "nfields" CVMFieldBlock structures	    int i;	    headerOut.print(fieldArrayFlavor+" {");	    if (nfields > cbRepeat)		headerOut.println();	    int numFieldArrays = (nfields-1) / cbRepeat + 1;	    for (i = 1; i <= numFieldArrays; i++) {		int nfields2; // # fields in this field array		if (i == numFieldArrays) {		    nfields2 = (nfields-1) % cbRepeat + 1;		} else {		    nfields2 = cbRepeat;		}		headerOut.print(" CVMClassBlock const *cb" + i + ";" + 				" CVMFieldBlock fb" + i + 				"[" + nfields2 + "];");		if (nfields > cbRepeat) {		    headerOut.println();		}	    }	    headerOut.println(" };");	    fieldArraySizes.set( nfields );

⌨️ 快捷键说明

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