cvmwriter.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,949 行 · 第 1/5 页
JAVA
1,949 行
} declare( "const "+fieldArrayFlavor+" "+thisTableName, classOut); fieldTableName = "&"+thisTableName; fieldTableSize = nfields; } void writeFields(CVMClass c) { // Note: Should deal with > 255 fields. // Today is not that day. Just do the simple case. FieldInfo m[] = c.classInfo.fields; if ( (m == null) || (m.length== 0)){ fieldTableName = "0"; fieldTableSize = 0; return; } int nfields = m.length; declareFieldArray( c ); classOut.print( " = {\n"); for ( int i = 0; i < nfields; i++ ){ int fbIndex = i % cbRepeat; FieldInfo f = m[i]; int typeid = CVMDataType.parseSignature(getUTF(f.type)); int nameid = CVMMemberNameEntry.lookupEnter(getUTF(f.name)); String nameAndType = "RAW_TYPEID(0x" + Integer.toHexString(nameid) + ", 0x" + Integer.toHexString(typeid) + ")"; //System.out.println( nameAndType+" => "+Integer.toHexString(typeid) ); int access = CVMDataAccessFlags(f.access); int offset = f.instanceOffset; /* field offsets are always mod cbRepeat and we have to emit a cb * entry before each block of cbRepeat fields. */ if (fbIndex == 0) { if (i != 0) { classOut.print( "\t},\n"); } classOut.print( "\t&"+classBlockName+",\n\t{\n" ); } // static members use simple byte offset // instance members include size of header info if (f.isStaticMember()) { classOut.print("\tCVM_INIT_FIELDBLOCK(" + nameAndType + "," + access + "," + fbIndex + ", CVM_STATIC_OFFSET(" + offset + ")),\n"); } else { classOut.print("\tCVM_INIT_FIELDBLOCK(" + nameAndType + "," + access + "," + fbIndex + ", CVM_FIELD_OFFSET(" + offset + ")),\n"); } } classOut.println("}};"); this.nfields += nfields; } private String methodBlockAddress( MethodInfo mi ){ CVMMethodInfo em = (CVMMethodInfo)(mi.vmMethodInfo); CVMClass ec = (CVMClass)(mi.parent.vmClass); int n = mi.index; /* * Moved globals to CVMROMGlobals. For classes without * writeable methods, there is (still) a constant global * variable <class>_methods - nothing has changed. For * classes with writeable methods, the <class>_methods * variable lives in the CVMROMGlobals structure. The ability * to determine whether a class has writable methods has been * added to CVMClass. */ if (mutableMBs || ec.hasWritableMethods()) { // had better not be an interface. return "&CVMROMGlobals." + ec.getNativeName() + "_methods.mb" + (n/cbRepeat+1) + "[" + n%cbRepeat + "]"; } // had better not be an interface. return "&" + ec.getNativeName() + "_methods.mb" + (n/cbRepeat+1) + "[" + n%cbRepeat + "]"; } private static String fieldBlockAddress( FieldInfo f ){ // pretty disgusting. // if this is frequent enough, find a better way! ClassInfo c = f.parent; FieldInfo cf[] = c.fields; int n = f.index; //for ( n = 0; cf[n] != f; n++ ) // TRY THIS. // ; // assume we found it. String parentName = ((CVMClass)(c.vmClass)).getNativeName(); return "&"+parentName+"_fields.fb"+(n/cbRepeat+1)+"["+n%cbRepeat+"]"; } private static final int unresolvedCVMConstantMap[] = { CVM_CONSTANT_Invalid, CVM_CONSTANT_Utf8, CVM_CONSTANT_Invalid, CVM_CONSTANT_Integer|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_Float|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_Long|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_Double|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_ClassTypeID, CVM_CONSTANT_StringObj|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_Fieldref, CVM_CONSTANT_Methodref, CVM_CONSTANT_InterfaceMethodref, CVM_CONSTANT_NameAndType }; private static final int resolvedCVMConstantMap[] = { CVM_CONSTANT_Invalid, CVM_CONSTANT_Utf8, CVM_CONSTANT_Invalid, CVM_CONSTANT_Integer|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_Float|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_Long|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_Double|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_ClassBlock|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_StringObj|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_FieldBlock|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_MethodBlock|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_MethodBlock|CVM_CONSTANT_POOL_ENTRY_RESOLVED, CVM_CONSTANT_NameAndType }; private static int CVMconstantTag( ConstantObject c){ int t; if ( c.isResolved() ){ t = resolvedCVMConstantMap[ c.tag ]; if (t == CVM_CONSTANT_NameAndType){ String sig = ((NameAndTypeConstant)c).type.string; t = (sig.charAt(0) == SIGC_METHOD) ? CVM_CONSTANT_MethodTypeID : CVM_CONSTANT_FieldTypeID; } } else { t = unresolvedCVMConstantMap[ c.tag ]; if (t == CVM_CONSTANT_NameAndType){ String sig = ((NameAndTypeConstant)c).type.string; t = (sig.charAt(0) == SIGC_METHOD) ? CVM_CONSTANT_MethodTypeID : CVM_CONSTANT_FieldTypeID; } } return t; } // return address of this type table. private String writeTypeTable( ConstantObject constants[], String name ){ int clen = constants.length; String ttname = name+"_tt"; auxOut.print("CVMUint8 "+ttname+"[] = { 0,"); int j = 99; for ( int i = 1; i < clen; i+=constants[i].nSlots ){ if ( j >= 10 ){ auxOut.print("\n "); j = 1; } else { j += 1; } auxOut.print(CVMconstantTag(constants[i])+","); if (constants[i].nSlots == 2){ auxOut.print(" 0,"); // 2nd word of 2-word constant j += 1; } } auxOut.println("\n};"); headerOut.println("extern CVMUint8 "+ttname+"["+clen+"];"); return "&"+ttname; } // return address of this array Info. private String writeArrayInfo( ArrayClassInfo info, String name ){ String arrayInfoName = name+"_ai"; classOut.println("STATIC const union {"); classOut.println("\tCVMArrayInfo ai;"); classOut.println("\tCVMConstantPool constantpool;"); classOut.println("} "+arrayInfoName+" = {{"); classOut.println("\t"+info.depth+", "+info.baseType+","); classOut.println("\t(CVMClassBlock*)&"+ cbName((CVMClass)info.baseClass.find().vmClass)+","); classOut.println("\t(CVMClassBlock*)&"+ cbName((CVMClass)info.subarrayClass.find().vmClass)); classOut.println("}};"); return "&"+arrayInfoName+".ai"; } // return address of this constant pool. private String writeConstants(ConstantPool cp, String name, boolean export) { ConstantObject constants[] = cp.getConstants(); int clen = constants.length; if ( (clen == 0) || (clen == 1 ) ){ return "0"; } // Check if we need a type table. When we write the class, we // check for unquickened bytecodes. If we find any, we mark // the constant pool as needing a type table. The check for // unresolved entries should be redundant, because unreferenced // entries should have been removed, and referenced entries // should have an unquickened reference. boolean doTypeTable = cp.needsTypeTable() || ClassClass.isPartiallyResolved(cp); if ( doTypeTable && !classLoading ){ // in future, do something more useful here. System.err.println(Localizer.getString("cwriter.no_class_loading")); // write the type table out anyway, in case // there is someone to look at it at runtime! } String typeTableName; if ( doTypeTable ){ typeTableName = "CP_ADDR(" + writeTypeTable( constants, name ) + ")"; }else{ typeTableName = "CP_ADDR(0)"; } String constantPoolName = name+"_cp"; classOut.print( doTypeTable ? "" : "const "); classOut.println("CVMAddr "+constantPoolName+"["+(clen)+"] = {"); classOut.println(" (CVMAddr)"+typeTableName+","); if (export) { // Export in the global header for multiple components of // romjava files to find headerOut.print("extern "); headerOut.print( doTypeTable ? "" : "const "); headerOut.println("CVMAddr "+ constantPoolName+"["+(clen)+"];"); } for ( int i = 1; i < clen; i+=constants[i].nSlots ){ classOut.print(" "); writeConstant( constants[i], classOut, "CP_" ); classOut.println(","); } classOut.println("};"); nconstants += clen; return constantPoolName; } private void declareClassblock( CVMClass c, int innerClassCount ){ String myName = c.getNativeName(); String classblockFlavor = "struct CVMClassBlock"+innerClassCount; if (!classblockSizes.get(innerClassCount)) { // need to declare a classblock-like struct with innerClassCount // elements in its CVMInnerClassInfo array if ( innerClassCount < 1 ){ headerOut.println(classblockFlavor + " { CVMClassBlock classclass; };"); } else { headerOut.println(classblockFlavor + " { CVMClassBlock classclass; " + "CVMUint32 innerClassesCount; " + "CVMInnerClassInfo innerClasses[ " + innerClassCount + "]; };"); } classblockSizes.set(innerClassCount); } declare( "const "+classblockFlavor+" "+myName+"_Classblock", classOut); } // helper for classBitMap private static int GCbits( FieldInfo slottable[], int first, int last ) { int mapval = 0; for ( int i = first; i < last; i++ ){ switch ( slottable[i].type.string.charAt(0) ){ case 'L': case '[': // this is a reference. mapval |= 1<<(i-first); } } return mapval; } // // compute the GC bit map for a class. // if it is big, then write it out as well. In any case, // return a string to use to initialize the gcMap field in the CVMClassBlock // private String classBitMap( CVMClass c ){ if ( c.isArrayClass() ){ // either an array of primitive or an array of objects. ArrayClassInfo ac = (ArrayClassInfo)(c.classInfo); if ( (ac.depth==1) && (ac.baseType!=T_CLASS) ) return "0"; // contains no references else return "1"; // contains nothing but references. } ClassInfo ci = c.classInfo; FieldInfo ft[] = ci.slottable; if ( (ft==null) || (ft.length==0) ) return "0"; int nslots; if ( (nslots=ft.length) <= 30 ){ // easy case. Small object. Map can be represented in a word. return "0x"+Integer.toHexString(GCbits(ft,0,nslots)<<2); } else { // hard case. String myName = c.getNativeName()+"_gcBits"; int nWords = (nslots+31)/32; classOut.print( "STATIC const struct { " + "CVMUint16 maplen; CVMUint32 map["+nWords+"]; } "); classOut.print( myName ); classOut.print( " = { "); classOut.print( nWords ); classOut.print( ",\n {" ); for ( int i = 0; i < nslots; i+= 32 ){ classOut.print("0x"+Integer.toHexString(GCbits(ft, i, Math.min( i+32, nslots)))); classOut.print(", "); } classOut.println("} };"); return "(CVMAddr)(((char*)&"+myName+")+ CVM_GCMAP_LONGGCMAP_FLAG)"; } } private void writeClassinfo( int classno, CVMClass c, int clinitIdx, int nStaticWords ){ if (c.hasStaticInitializer) { nClinits++; } String superName = (c.classInfo.superClassInfo == null) ? ("0") : ("&" + cbName((CVMClass) c.classInfo.superClassInfo.vmClass)); String myStaticName = (c.nStaticWords == 0) ? ("0") : ("(CVMJavaVal32*)STATIC_STORE_ADDRESS(0)"); int innerClassCount = (c.classInfo.innerClassAttr == null) ? (0) : (c.classInfo.innerClassAttr.getInnerClassCount()); String runtimeFlags = (c.hasStaticInitializer) ? ("CVM_ROMCLASS_WCI_INIT") : ("CVM_ROMCLASS_INIT"); MethodInfo vtbl[] = c.classInfo.methodtable; String methodTableName; int methodTableCount; String gcBits; /* * 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() ){ methodTableCount = c.typecode(); methodTableName = "0"; } else { // vtbl == null may occur for array classes! methodTableCount = (vtbl==null)?0:vtbl.length; if (methodTableCount > 0) { methodTableName = c.getNativeName()+"_mt"; } else if (c.isArrayClass()) { methodTableCount = c.classInfo.superClassInfo.methodtable.length; methodTableName = "java_lang_Object_mt"; } else { /* must be an interface */ methodTableName = "0"; } } // classBitMap may do output, so it needs // to be called before declareClassblock! gcBits = classBitMap( c ); declareClassblock( c, innerClassCount ); int classid = c.getClassId(); //System.out.println( c.ci.className+" => "+Integer.toHexString(classid) ); classOut.println(" = {\n CVM_INIT_CLASSBLOCK( "+gcBits+", " + "RAW_TYPEID(0, 0x" + Integer.toHexString(classid) + "), \"" + c.classInfo.className + "\","); classOut.println(" "+superName+","); classOut.println(" "+constantPoolName+", "); classOut.println(" "+interfaceTableName+","); classOut.println(" "+methodArrayName+","); classOut.println(" "+fieldTableName+", "+myStaticName+","); classOut.println(" "+constantPoolSize+", "+methodTableSize+", "+ fieldTableSize+", "+methodTableCount+", "+ c.CVMflags()+", "+runtimeFlags+", "+ nStaticWords+" + "+clinitIdx+ ", OBJ_SIZE("+c.instanceSize()+"), "); classOut.println(" (CVMClassICell*)(&CVM_classICell["+classno+"]), "); /* The slots for clinitEE is appended to 'staticStoreName'. */ /* * Moved global variables to CVMROMGlobals */ classOut.println(" (CVMExecEnv**)&CVMROMGlobals."+staticStoreName+ "["+nStaticWords+" + "+clinitIdx+"],"); classOut.println(" "+checkedExceptionName+", "); if (classDebug && c.classInfo.sourceFileAttr != null) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?