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 + -
显示快捷键?