📄 kvmwriter.java
字号:
/* * KVMWriter.java 1.35 01/05/08 SMI * * Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved. * * This software is the confidential and proprietary information of Sun * Microsystems, Inc. ("Confidential Information"). You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Sun. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. * Use is subject to license terms. */package runtime;import vm.Const;import vm.EVMConst;import components.*;import vm.*;import jcc.Util;import util.*;import java.util.Vector;import java.util.Enumeration;import java.util.Hashtable;import java.io.OutputStream;/* * The CoreImageWriter for the Embedded VM */public class KVMWriter implements CoreImageWriter, Const, EVMConst { KVMStringTable stringTable = new KVMStringTable(); KVMNameTable nameTable; KVMClassTable classTable; KVMStackMap stackMapUtil; /* INSTANCE DATA */ protected String outputFileName; protected Exception failureMode = null; // only interesting on failure protected OutputStream xxx; CCodeWriter out; protected vm.VMClassFactory classMaker = new vm.EVMClassFactory(); //CConstants sc; boolean formatError = false; boolean verbose = false; boolean classDebug = false; boolean buildingRelocationTable = false; boolean relocatableROM = false; boolean compactUTFTable = false; protected static final String staticStoreName = "KVM_staticData"; protected static final String masterStaticStoreName = "KVM_masterStaticData"; // In ROMjava.c we need to make several "forward static" declarations, // where the forward declaration has no initializer and the later // declaration has an initializer. Some compilers allow you to specify // simply "static" in both places. Other compiler treat this as a // redefinition error and require the "forward" declaration to be // "external". So, we will emit the identifier // "FORWARD_STATIC_DECLARATION", and each specific compiler will // have to define this to be what is appropriate for that compiler. protected ClassnameFilterList nativeTypes; protected boolean classLoading = true; // by default. /* for statistics only */ int ncodebytes; int ncatchframes; int nmethods; int nfields; int nconstants; int njavastrings; public static final int ACC_ARRAY_CLASS = 0x1000; public static final int ACC_ROM_CLASS = 0x2000; public static final int ACC_ROM_NON_INIT_CLASS = 0x4000; public static final int ACC_POINTER = Const.ACC_REFERENCE; public static final int ACC_DOUBLE = Const.ACC_DOUBLEWORD; MethodInfo runCustomCodeMethod; MethodConstant runCustomCodeConstant; public KVMWriter( ){ nameTable = new KVMNameTable(); classTable = new KVMClassTable(nameTable); nameTable.classTable = classTable; stackMapUtil = new KVMStackMap(this, nameTable); } public void init( boolean classDebug, ClassnameFilterList nativeTypes, boolean verbose, int maxSegmentSize ){ this.verbose = verbose; this.classDebug = classDebug; this.nativeTypes = nativeTypes; } public boolean setAttribute( String attribute ){ if (attribute.equals("compactUTFTable")) { compactUTFTable = true; return true; } return false; } public boolean open( String filename ){ if ( out != null ) { close(); } outputFileName = filename; if ( filename == null){ xxx = System.out; out = new CCodeWriter( xxx ); } else { try { xxx = new java.io.FileOutputStream( filename ); out = new CCodeWriter( xxx ); } catch ( java.io.IOException e ){ failureMode = e; return false; } } return true; } public void close(){ if (out != null) { out.close(); outputFileName = null; out = null; } } public boolean writeClasses( ConstantPool consts ) { return writeClasses(consts, null); } public void printError( java.io.PrintStream o ){ if ( failureMode != null ){ failureMode.printStackTrace( o ); } else { if ( out != null && out.checkError() ) o.println(outputFileName+": Output write error"); } } public boolean writeClasses( ConstantPool consts, ConstantPool sharedconsts ){ ClassClass classes[] = ClassClass.getClassVector( classMaker ); ClassClass.setTypes(); if (verbose) { System.out.println(Localizer.getString("cwriter.writing_classes")); } try { initialPass(classes); runCustomCodeConstant = new MethodConstant(new ClassConstant( new UnicodeConstant("java/lang/Class")), new NameAndTypeConstant( new UnicodeConstant("runCustomCode"), new UnicodeConstant("()V"))); runCustomCodeMethod = runCustomCodeConstant.find(); if (!buildingRelocationTable) { // write out some constant pool stuff here, writeProlog(); // Print out declarations for each of the classes writeAllClassDeclarations(classes); out.println("\014"); // Print out the string table if (relocatableROM) { out.println("void *StringSectionHeader = &StringSectionHeader;"); } njavastrings = stringTable.writeStrings(this, "InternStringTable"); if (relocatableROM) { out.println("void *StringSectionTrailer = &StringSectionTrailer;"); } /* Write out the static store */ out.println("\014"); writeStaticStore(classes); /* Write out the UTF table */ out.println("\014"); if (relocatableROM) { out.println("void *UTFSectionHeader = &UTFSectionHeader;"); } nameTable.setCompactEntries(compactUTFTable); nameTable.writeTable(out, "UTFStringTable"); if (relocatableROM) { out.println("void *UTFSectionTrailer = &UTFSectionTrailer;"); } /* Write out class definitions */ out.println("\014"); writeAllClassDefinitions(classes); out.println("\014"); writeEpilog(); } else { writeRelocationFile(classes); } } catch (DataFormatException e) { out.flush(); System.out.println(e); e.printStackTrace(System.out); formatError = true; } catch (RuntimeException e) { out.flush(); System.out.println(e); e.printStackTrace(System.out); formatError = true; } return (!formatError) && (! out.checkError()); } protected void initialPass(ClassClass classes[]) { for (int i = 0; i < classes.length; i++) { EVMClass cc = (EVMClass) classes[i]; if (cc.isPrimitiveClass()) { /* Do nothing */ } else if (cc.isArrayClass()) { /* Make sure this is in the table */ classTable.addArrayClass(cc.ci.className); } else { /* Make sure this is in the table */ classTable.getClassKey(cc.ci.className); EVMMethodInfo m[] = cc.methods; FieldInfo f[] = cc.ci.fields; ConstantObject cpool[] = cc.ci.constants; ClassConstant intfs[] = cc.ci.interfaces; int methodCount = m.length; int fieldCount = f.length; int constantCount = cpool.length; int intfCount = intfs.length; for (int index = 0; index < methodCount; index++) { EVMMethodInfo meth = m[index]; MethodInfo mi = meth.method; classTable.getNameAndTypeKey(mi); stackMapUtil.initialPass(meth); } for (int index = 0; index < fieldCount; index++) { classTable.getNameAndTypeKey(f[index]); if (f[index].isStaticMember() && f[index].value instanceof StringConstant) { stringTable.intern( (StringConstant) f[index].value); } } for (int index = 1; index < constantCount;) { ConstantObject obj = cpool[index]; if (obj instanceof StringConstant){ stringTable.intern( (StringConstant) obj); } index += obj.nSlots; } } } for (int i = 0; i < publicNameTypes.length; i++) { String triple[] = publicNameTypes[i]; String globalName = triple[0]; String methodName = triple[1]; String methodType = triple[2]; classTable.getNameAndTypeKey(methodName, methodType); } for (int i = 0; i < mayNotBeRenamed.length; i++) { classTable.getNameKey(mayNotBeRenamed[i], false); } stringTable.stringHashTable.closed = true; classTable.closed = true; nameTable.closed = true; stackMapUtil.showStatistics(); } protected void writeAllClassDeclarations(ClassClass classes[]) throws DataFormatException { out.println("struct AllClassblocks_Struct {"); Vector names = new Vector(); for (Enumeration e = classTable.enumerate(); e.hasMoreElements(); ) { String name = ((KVMClassName)e.nextElement()).toString(); ClassInfo ci = ClassInfo.lookupClass(name); if (ci == null) { if (name.charAt(0) == '[') { /* Let's create an array class for this thing */ ci = new ArrayClassInfo(false, name); new EVMClass(ci); } else { String myName = Util.convertToClassName(name); out.println("\tstruct instanceClassStruct " + myName + ";"); continue; } } EVMClass cc = (EVMClass)ci.vmClass; String myName = cc.getNativeName(); names.addElement(myName); if (cc.isPrimitiveClass()) { // We ignore these } else if (cc.isArrayClass()) { out.println("\tstruct arrayClassStruct " + myName + ";"); } else { out.println("\tstruct instanceClassStruct " + myName + ";"); } } out.println("};"); out.println(); out.println("FORWARD_STATIC_DECLARATION"); out.println("struct AllClassblocks_Struct AllClassblocks;"); out.println(); } /* * 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. */ void writeStaticStore (ClassClass classes[]) { int nclass = classes.length; int nStaticWords = 1; // 1 header word assumed int nRef = 0; /* * Count all statics. * Count refs, and count number of words. */ for (int cno = 0; cno < nclass; cno++ ){ EVMClass c = (EVMClass)(classes[cno]); c.orderStatics(); nRef += c.nStaticRef; nStaticWords += c.nStaticWords; FieldInfo f[] = c.statics; } /* * Assign offsets and at the same time * write any initial values. */ int refOff = 1; int scalarOff = refOff + nRef; final ConstantObject staticInitialValue[] = new ConstantObject[nStaticWords]; for ( int cno = 0; cno < nclass; cno++ ){ EVMClass c = (EVMClass)(classes[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]; char toptype = fld.type.string.charAt(0); if ( (toptype == 'L') || (toptype=='[')){ fld.instanceOffset = refOff; staticInitialValue[refOff] = fld.value; refOff += 1; } else { fld.instanceOffset = scalarOff; staticInitialValue[scalarOff] = fld.value; scalarOff += fld.nSlots; } } } ConstantObject zero = new SingleValueConstant(0); staticInitialValue[0] = new SingleValueConstant(nRef); ArrayPrinter ap = new ArrayPrinter() { DoubleValueConstant previous; public void print(int index) { ConstantObject value = staticInitialValue[index]; if (value != null) { out.print("ROM_STATIC_"); if (value.nSlots == 1) { writeConstant(value, false); } else { DoubleValueConstant dval = (DoubleValueConstant) value;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -