cvmwriter.java

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

JAVA
1,949
字号
	    classOut.println("    \"" + c.classInfo.sourceFileAttr.sourceName +                             "\", ");	} else {	    classOut.println("    0, ");	}	/* write out the methodTablePtr. */	classOut.println("    " + methodTableName + ",");	/* write out the ClassLoader and ProtectionDomain */	int id = c.classInfo.loader.getID();	if (id != 0) {	    int clIDOff = 1; // first cl ID (boot == 0)	    int off = clRefOff + (id - clIDOff) * 2;	    classOut.println("    (CVMClassLoaderICell *)" +		"STATIC_STORE_ADDRESS(" + off + "), " +		"(CVMObjectICell *)" +		"STATIC_STORE_ADDRESS(" + (off + 1) + "),");	} else {	    classOut.println("    0, 0,");	}	/* write out the InnerClassesInfo */	if (c.classInfo.innerClassAttr != null) {	    classOut.println("    &" + c.getNativeName() +			     "_Classblock.innerClassesCount),");	    writeInnerClasses(c);	} else {	    classOut.println("    0)");	}	// TODO :: BEGIN        // This is for adding class version number and signature later.        // This code needs to be further reviewed and tested before enabling        // it.        if (false) { // disabled for now.	    classOut.println("    /* major_version */ " +                             c.classInfo.majorVersion + ",");	    classOut.println("    /* minor_version */ " +                             c.classInfo.minorVersion + ",");	    classOut.print  ("    /* CB genSig     */ ");	    //if (c.ci.signatureAttr != null) {	    //  classOut.print("\""+c.ci.signatureAttr.signature+"\""); // FIXME	    //} else {	        classOut.print(0);	    //}	    classOut.println(",");	    classOut.println("    /* FB genSig *   */ " +			     0 + ",");	    classOut.println("    /* MB getSig *   */ " +			     0 +"), ");	    if (c.classInfo.innerClassAttr != null) {		writeInnerClasses(c);	    }        }        // TODO :: END	classOut.println("};");    }    void writeMethodTable(CVMClass c) {	MethodInfo vtbl[] = c.classInfo.methodtable;	int        vtblSize;	/*	 * Note: If this is a primitive class, the	 * typecode is stored in the methodTableCount field.	 * Since these things cannot be instantiated, they need	 * no virtual methods.	 */	if ( c.isPrimitiveClass() ){	    return;	} else {	    // vtbl == null may occur for array classes! 	    vtblSize = (vtbl==null)?0:vtbl.length;	}	if (vtblSize > 0) {	    /* write out the methodtable. */	    String methodTableName = c.getNativeName()+"_mt"+"["+vtblSize+"]";	    if (c.classInfo.superClass == null) { // is it java/lang/Object		// java/lang/Object needs an extern methodTable declaration.		/* Added another const (for the pointer, which is also		 * const here, not just the data) 		 */		declare("const CVMMethodBlock* const " + methodTableName,                        classOut);	    } else {		/* Added another const (for the pointer, which is also const                   here, not just the data)		 */		classOut.print("STATIC const CVMMethodBlock* const " +                               methodTableName);	    }	    classOut.println(" = {");	    for (int i = 0; i < vtblSize; i++) {		classOut.println("    (CVMMethodBlock*)"+				  methodBlockAddress(vtbl[i]) + ",");	    }	    classOut.println("};\n");	}    }	    /* (These two belong directly in the CCodeWriter) */    private void    writeIntegerValue( int v, CCodeWriter out ){	 // little things make gcc happy.	 if (v==0x80000000)	    out.print( "(CVMInt32)0x80000000" );	else	     out.print( v );    }    private void    writeLongValue( String tag, int highval, int lowval, CCodeWriter out ){	out.print( tag );	out.write( '(' );	writeIntegerValue( highval, out );	out.print( ", " );	writeIntegerValue( lowval, out );	out.write( ')' );    }    /*      * Added prefix argument to differ between writing entries to the     * constant pool (where prefix="CP_") and the rest (where prefix     * is empty). Additionally we use the INTEGER/LONG/... macros now     * everywhere in this function to indicate, what type we are writing     * (may be hard to spot otherwise).     */    private void    writeConstant( ConstantObject value, CCodeWriter out, String prefix ){	switch ( value.tag ){	case Const.CONSTANT_INTEGER:	case Const.CONSTANT_FLOAT:	    /* 	     * add INTEGER macro like the one for LONG and DOUBLE	     * to have the possibility to change the representation	     * platform dependent	     */	    /* 	     * Add prefix to macro to get correct version.	     */            if (value.tag == Const.CONSTANT_INTEGER) {                if (verbose) out.print("/* int */ ");            } else {                if (verbose) out.print("/* flt */ ");            }	    out.print( prefix + "INTEGER(" );	    writeIntegerValue(((SingleValueConstant)value).value, out);	    out.print( ")" );	    break;	case Const.CONSTANT_UTF8:	    if (verbose) out.print("/* utf */ ");	    out.print("(CVMInt32)");	    out.write('"');	    out.print( Util.unicodeToUTF(((UnicodeConstant)value).string ));	    out.write('"');	    // also, not sharing here at all.	    break;	case Const.CONSTANT_STRING:	    /* 	     * Moved global variables to CVMROMGlobals	     */	    /* CVM_BIGTYPEID: RS, 10/08/02:	     * Use ADDR() macro to print out address.	     */	    if (verbose) out.print("/* str */ ");	    out.print(prefix  + "ADDR(&CVMROMGlobals."+stringArrayName+"[");	    if ( ((StringConstant)value).unicodeIndex == -1 ) {		// Uninitialized, very bad		throw new InternalError("Uninitialized string constant "+					value);	    } else {		out.print( ((StringConstant)value).unicodeIndex );	    }	    	    out.print("])");	    break;	case Const.CONSTANT_LONG:{	    DoubleValueConstant dval = (DoubleValueConstant) value;	    /*	     * Add prefix to macro to get correct version.	     */	    if (verbose) out.print("/* lng */ ");	    writeLongValue( "LONG",  dval.highVal, dval.lowVal, out );	    }	    break;	case Const.CONSTANT_DOUBLE:{	    DoubleValueConstant dval = (DoubleValueConstant) value;	    /*	     * Add prefix to macro to get correct version.	     */	    if (verbose) out.print("/* dbl */ ");	    writeLongValue( "DOUBLE",  dval.highVal, dval.lowVal, out );	    }	    break;	case Const.CONSTANT_CLASS:	    if (value.isResolved()) {		/* 		 * Use ADDR() macro to print out address.		 */		if (verbose) out.print("/* cls */ ");		out.print(prefix + "ADDR(&" +                    cbName((CVMClass)(((ClassConstant)value).find().vmClass)) +                    ")");	    } else {		int classid = CVMDataType.lookupClassname(		    getUTF(((ClassConstant)value).name) );		/*		 * Use TYPEID() macro to create typeid from type part.		 */		if (verbose) out.print("/* cID */ ");		out.print(prefix + "TYPEID(0, 0x" +                          Integer.toHexString(classid) + ")");	    }	    break;	case Const.CONSTANT_METHOD:	case Const.CONSTANT_INTERFACEMETHOD:	    if ( value.isResolved() ){		/*		 * Use ADDR() macro to print out address.		 */		if (value.tag == Const.CONSTANT_METHOD) {		    if (verbose) out.print("/* mb  */ ");		} else {		    if (verbose) out.print("/* imb */ ");		}		out.print(prefix + "ADDR(");		out.print(methodBlockAddress(((MethodConstant)value).find()) +                          ")");	    } else {		FMIrefConstant ref = (FMIrefConstant)value;		/* 		 * Use MEMBER_REF() macro to create entry for parts.		 * This is a pair of 16-bit indices into the cp.		 * They reference a Class constant and a NameAndType		 * constant.		 * It is not a typeId.		 */		if (value.tag == Const.CONSTANT_METHOD) {		    if (verbose) out.print("/* mID */ ");		} else {		    if (verbose) out.print("/* iID */ ");		}		out.print(prefix + 		    "MEMBER_REF(0x"+Integer.toHexString(ref.clas.getIndex()) +		    ", 0x"+Integer.toHexString(ref.sig.getIndex())+")");	    }	    break;	case Const.CONSTANT_FIELD:	    if ( value.isResolved() ){		FieldInfo ftarget = ((FieldConstant)value).find();		ClassInfo ctarget = ftarget.parent;		// ROMized code always use checkinit version of opcodes		// to access fields including static fields.		/*		 * Add prefix to macro to get correct version.		 */		if (verbose) out.print("/* fb  */ ");		out.print(prefix + "ADDR(" + fieldBlockAddress(ftarget) + ")");	    } else {		FMIrefConstant ref = (FMIrefConstant)value;		/* 		 * Use MEMBER_REF() macro to create entry for parts.		 * This is a pair of 16-bit indices into the cp.		 * They reference a Class constant and a NameAndType		 * constant.		 * It is not a typeId.		 */		if (verbose) out.print("/* fID */ ");		out.print(prefix + 		    "MEMBER_REF(0x"+Integer.toHexString(ref.clas.getIndex()) + 		    ", 0x"+Integer.toHexString(ref.sig.getIndex())+")");	    }	    break;	case CONSTANT_NAMEANDTYPE:	    NameAndTypeConstant ntcon = (NameAndTypeConstant)value;	    int nameid = CVMMemberNameEntry.lookupEnter(getUTF(ntcon.name));	    String sigString = getUTF(ntcon.type);	    int typeid = (sigString.charAt(0)==SIGC_METHOD)	       ? (CVMMethodType.parseSignature(sigString).entryNo)	       : (CVMDataType.parseSignature(sigString));	    /* 	     * Use TYPEID() macro to create typeid from parts.	     */	    if (verbose) out.print("/* n&t */ ");            out.print("TYPEID(0x" + Integer.toHexString(nameid) + ", 0x" +                      Integer.toHexString(typeid) +")");	    break;	}    }    private int clRefOff;    /*     * Merge the static store for all classes into one area.     * Sort static cells, refs first, and assign offsets.     * Write the resulting master data glob and arrange for     * it to be copied to writable at startup.     */    private int writeStaticStore( ClassClass cvec[] ){	int nclass = cvec.length;	int nStaticWords = 1; // 1 header word assumed	int nRef    = 0;	/* The number of necessary slots for clinitEE + 1.	 * Index of a class that doesn't have <clinit> is always 0.	 * The 0th entry is reserved for it. */	int maxClinitIdx = 1;	int maxClIdx = 0;	/*	 * Count all statics.	 * Count refs, and count number of words.	 */	for ( int cno = 0; cno < nclass; cno++ ){	    CVMClass c = (CVMClass)(cvec[cno]);	    c.orderStatics();	    nRef += c.nStaticRef;	    nStaticWords += c.nStaticWords;	    /* Count the number of necessary slots for clinitEE. */	    if (c.hasStaticInitializer) {		maxClinitIdx++;	    }	}	int ncl = components.ClassTable.getNumClassLoaders();	nRef += ncl * 2;	nStaticWords += ncl * 2;	/*	 * Assign offsets and at the same time	 * record any initial values.	 * write it later.	 */	int refOff = 1;	int scalarOff = refOff+nRef;	ConstantObject staticInitialValue[] = new ConstantObject[nStaticWords];	short          staticInitialSize[]  = new short[nStaticWords];	clRefOff = refOff;	for ( int i = 0; i < ncl; ++i) {	    staticInitialValue[refOff] = null;	    staticInitialSize[refOff] = 1;	    ++refOff;	    staticInitialValue[refOff] = null;	    staticInitialSize[refOff] = 1;	    ++refOff;	}	for ( int cno = 0; cno < nclass; cno++ ){	    CVMClass c = (CVMClass)(cvec[cno]);	    FieldInfo f[] = c.statics;	    if ((f == null) || (f.length == 0)) continue; // this class has none	    int     nFields = f.length;	    for ( int i = 0; i < nFields; i++ ){		FieldInfo fld = f[i];		short     nslots = (short)(fld.nSlots);		char toptype =  fld.type.string.charAt(0);		if ( (toptype == 'L') || (toptype=='[')){		    fld.instanceOffset = refOff;		    staticInitialValue[refOff] = fld.value;		    staticInitialSize[refOff] = 1;		    refOff += 1;		} else {		    fld.instanceOffset = scalarOff;		    staticInitialValue[scalarOff] = fld.value;		    staticInitialSize[scalarOff] = nslots;		    scalarOff += nslots;		}	    }	}	/*	 * Allocate writable space for the static store.	 * Start writing the static storage header.	 * Remember that the first word is the number of refs.	 * And many of those refs get initialized to zero.	 * A static final String constant gets initialized with a pointer.	 * 	 * The buffer holds static field slots for the ROMized classes and 	 * cliniEE (that includes runtime flags) slots for ROMized classes.	 * The slot allocation looks like this:	 *	 * 

⌨️ 快捷键说明

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