📄 cfile.java
字号:
// CFile.java -- general procs for writing .c files, excluding method codepackage toba.translator;import toba.classfile.*;import java.io.*;import java.util.*;class CFile {static private Hashtable declared; // set of class structs declaredstatic private StringBuffer strpool; // string character poolstatic private int strnums[]; // indices of used stringsstatic private int strlens[]; // lengths of those stringstatic private int strcount; // number of used stringsstatic private int nsupers; // number of superclasses incl selfstatic private int ninters; // number of interfaces implementedstatic private int nothers; // number of "other" classes referenced// write(d, c) -- write header info for class c on stream d.static void write(PrintWriter d, ClassData c){ declared = new Hashtable(); // clear list of classes // include general definitions, present class, ancestors, their interfaces d.println(); d.println("#include \"toba.h\""); for (ClassData t = c; t != null; t = t.superclass) { include(d, t.name); for (int i = 0; i < t.interfaces.length; i++) include(d, t.interfaces[i].name); } // always include these two classes (needed by generated code): include(d, "java.lang.String"); include(d, "java.lang.Class"); // include declarations for other referenced classes for (int i = 1; i < c.constants.length; i++) { Constant k = c.constants[i]; if (k != null && k.tag == Constant.CLASS) { ClassRef cr = (ClassRef)k.value; String s = Names.baseclass(cr.name); if (s != null) include(d, s); } } declared = new Hashtable(); // reset list of classes supers(d, c); // generate superclass list inters(d, c); // generate interfaces list others(d, c); // generate others list d.println(); d.println("extern const Char ch_" + c.cname + "[];"); // declare string pool d.println("extern const void *st_" + c.cname + "[];"); // declare string ptrs for (int i = 0; i < c.methods.length; i++) { Field m = c.methods[i]; /* This is really static, but we have to declare it extern * to get by the Irix C compiler which won't allow forward * decls of arrays of unknown size. We can't create a Method * structure now, because the variable use flags will be * wrong unless we've done some of the later setup. */ d.println("extern Class xt_" + m.cname + "[];");// declare exceptn lists } hashgen(d, c); // generate hash table clname(d, c); // generate class name string cltables(d, c); // generate variable static tables clstruct(d, c); // generate class structure gfloats(d, c.constants); // generate floating constants // initialize bookkeeping for string pool strnums = new int[c.constants.length]; // init constant index array strlens = new int[c.constants.length]; // init string lengths array strpool = new StringBuffer(c.name); // init pool with class name strlens[0] = c.name.length(); // record it as first entry strcount = 1; // and count it // generate method code for (int i = 0; i < c.methods.length; i++) { Method m = new Method(c, c.methods[i]); MethGen.minfo(d, m); // always gen exception list if ((m.fl.access & ClassData.ACC_ABSTRACT) == 0) { // generate body code if not native if ((m.fl.access & ClassData.ACC_NATIVE) == 0) { try { MethGen.mgen(d, m); } catch (Error e) { Trans.abort("method " + m.fl.name + ": " + e.getMessage()); } } // if synchronized, generate wrapper function if ((m.fl.access & ClassData.ACC_SYNCHRONIZED) != 0) MethGen.syncwrap(d, m); } } // dump string pool strdump(d, c);}// include(d, name) -- generate #include for a class, if not already generatedstatic private void include(PrintWriter d, String name){ name = Names.classfile(name); if (!declared.containsKey(name)) { d.println("#include \"" + name + ".h\""); declared.put(name, ""); }}// supers(d, c) -- write list of superclasses.static private void supers(PrintWriter d, ClassData c){ nsupers = 0; d.println(); d.println("static const Class supers[] = {"); for (; c != null; c = c.superclass) { d.println(" &cl_" + c.cname + ".C,"); declared.put(c.cname, ""); nsupers++; } d.println("};");}// inters(d, c) -- write list of interfaces implemented.static private void inters(PrintWriter d, ClassData c){ ninters = 0; d.println(); d.println("static const Class inters[] = {"); for (; c != null; c = c.superclass) { for (int j = 0; j < c.interfaces.length; j++) { String s = Names.hashclass(c.interfaces[j].name); d.println(" &cl_" + s + ".C,"); declared.put(s, ""); ninters++; } } if (ninters == 0) d.println(" 0"); d.println("};");}// others(d, c) -- write list of other classes referenced.static private void others(PrintWriter d, ClassData c){ nothers = 0; d.println(); d.println("static const Class others[] = {"); for (int i = 1; i < c.constants.length; i++) { Constant k = c.constants[i]; if (k != null && k.tag == Constant.CLASS) { ClassRef cr = (ClassRef)k.value; String s = Names.baseclass(cr.name); if (s != null) { s = Names.hashclass(s); if (! declared.containsKey(s)) { d.println(" &cl_" + s + ".C,"); nothers++; } } } } if (nothers == 0) d.println(" 0"); d.println("};");}// hashgen(d, c) -- generate hash table for finding interface methodsstatic private int hcols;static private final int HColMax = 75;static private void hashgen(PrintWriter d, ClassData c){ IHash h = new IHash(c); d.println(); d.println("#define HASHMASK 0x" + Integer.toHexString(h.mask)); for (int i = 0; i < h.hlist.length; i++) { Field m = h.hlist[i]; if (m != null) { d.println("/* " + Integer.toHexString(i) + ". " + Integer.toHexString(m.hashcode) + " (" + Integer.toHexString(m.hashcode & h.mask) + ") " + m.name + " */"); } } d.print("static const struct ihash htable[" + h.hlist.length + "] = {"); hcols = HColMax; for (int i = 0; i < h.hlist.length; i++) { Field m = h.hlist[i]; if (m == null) hashprint(d, " 0, 0,"); else hashprint(d, " " + m.hashcode + ", &cl_" + c.cname + ".M." + m.cname + ","); } d.println("\n};");}static private void hashprint(PrintWriter d, String s){ if (hcols + s.length() > HColMax) { d.print("\n "); hcols = 3; } d.print(s); hcols += s.length();}/** Emit the name and signature unicode char arrays for a given set of * fields, tagging each definition with something that indicates whether * it's static/instance method/field. */static private voidemitNamesSigs (PrintWriter d, // Where to write data String tag, // Identifying tag Field [] farr) // Array of fields{ for (int i = 0; i < farr.length; i++) { d.println ("static const Char nm" + tag + "_" + i + "[] = {"); Repr.emitCharData (d, farr [i].name); d.println ("};"); d.println ("static const Char sg" + tag + "_" + i + "[] = {"); Repr.emitCharData (d, farr [i].signature); d.println ("};"); } return;} // clname(d, c) -- generate class name constant.//// Some class names are needed during initialization, but the string// constant generated here is later replaced by an interned version.static private void clname(PrintWriter d, ClassData c){ d.println(); d.println("static const CARRAY(" + c.name.length() + ") nmchars = {&acl_char, 0, " + c.name.length() + ", 0,"); Repr.emitCharData (d, c.name); d.println("};"); d.println("static struct in_java_lang_String classname ="); d.println(" { &cl_java_lang_String, 0, (Object)&nmchars, 0, " + c.name.length() + " };");}// cltables(d, c) -- generate variable static tables.static private void cltables(PrintWriter d, ClassData c){ /* We have to match these structures from toba.h:struct vt_generic { int offset; If nonzero, is offset of field from instance start void *addr; If nonnull, is address of class variable const Char * name_chars; Name of the field int name_len; Length of field name const Char * sig_chars; Signature of the field int sig_len; Length of field signature int localp; Nonzero iff field is declared in this class (not superclass) int access; Access flags for field int classfilePos; Index of variable in original classfile};struct mt_generic { TobaMethodInvokeType itype; Type/source of method Void (*f) (); Function entry point const Char * name_chars; Name of the method int name_len; Length of method name const Char * sig_chars; Signature of the method int sig_len; Length of method signature int localp; Nonzero iff method is declared in this class (not superclass) int access; Access flags for method int classfilePos; Index of method in original classfile Class *xlist; Exception list, if local method}; */ /* Have to generate Java-format strings for instance and static fields, * and instance and static methods, names and signatures both. */ emitNamesSigs (d, "cv", c.cvtable); emitNamesSigs (d, "iv", c.ivtable); emitNamesSigs (d, "sm", c.smtable); emitNamesSigs (d, "im", c.imtable); // Class variable table d.println(); d.println("static struct vt_generic cv_table[] = {"); for (int i = 0; i < c.cvtable.length; i++) { Field f = c.cvtable[i]; d.println(" {0," + "&cl_" + c.cname + ".V." + f.cname + ",(const Char *)&nmcv_" + i + "," + f.name.length () + ",(const Char *)&sgcv_" + i + "," + f.signature.length () + (f.isInArray (c.fields) ? ",1" : ",0") + ",0x" + Integer.toHexString (f.access) + "," + f.classfilePos + "}, "); } if (c.cvtable.length == 0) { d.println(" {0}"); } d.println("};"); // Instance variable table d.println(); // Define the offsetof macro d.println("#ifndef offsetof"); d.println("#define offsetof(s,m) ((int)&(((s *)0))->m)"); d.println("#endif"); d.println("static struct vt_generic iv_table[] = {"); for (int i = 0; i < c.ivtable.length; i++) { Field f = c.ivtable[i]; d.println(" { offsetof(struct in_" +c.cname+", " +f.cname+"), 0" + ",(const Char *)&nmiv_" + i + "," + f.name.length () + ",(const Char *)&sgiv_" + i + "," + f.signature.length () + (f.isInArray (c.fields) ? ",1" : ",0") + ",0x" + Integer.toHexString (f.access) + "," + f.classfilePos + "}, "); } if (c.ivtable.length == 0) d.println(" {0}"); d.println("};"); d.println("#undef offsetof");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -