📄 classdata.java
字号:
// ClassData.java -- the data from a Java class filepackage toba.classfile;import java.io.*;import java.util.*;public class ClassData { /* We need to keep a mapping from (name,ClassLoader) pairs to ClassData * structures, so we can get back a consistent ClassData structure when * we lookup interfaces by name. We may not have the classfile * available to re-read. Note that the fact that we can't use null as * a hash key means we need to swap in something else to represent * the system class loader. */ private static Hashtable name2cdata; private static Object pseudoSystemClassLoader = new Object (); /* Given the name of a class, and the loader that's supposed to define it, * dig out the ClassData structure we associated with that pair; or * return null if there is none. */ private static ClassData getByNameLoader (String nm, ClassLoader cld) { Hashtable cdh; Object ocld; /* Key is the class loader, or its valid substitute */ ocld = cld; if (null == ocld) { ocld = pseudoSystemClassLoader; } /* Get the hash from loaders to data structures. */ cdh = (Hashtable) name2cdata.get (nm); if (null != cdh) { return (ClassData) cdh.get (ocld); } return null; } /* Record a ClassData structure so if we want to find a named class * relative to a given class loader, we don't have to try to reconstruct * the raw class information. */ private static void addByNameLoader (String nm, ClassLoader cld, ClassData cd) { Hashtable cdh; Object ocld; ocld = cld; if (null == ocld) { ocld = pseudoSystemClassLoader; } cdh = (Hashtable) name2cdata.get (nm); if (null == cdh) { cdh = new Hashtable (); name2cdata.put (nm, cdh); } cdh.put (ocld, cd); return; } static private Runtime rts; static { name2cdata = new Hashtable (); rts = Runtime.getRuntime (); }// instance variables public String name; // class name public String cname; // name as used in C public String fname; // name used for toba file public String supername; // superclass name public int major, minor; // version numbers public int access; // access flags and other flags public Constant[] constants; // constant table public ClassRef[] interfaces; // interfaces implemented public Field[] fields; // fields public Field[] methods; // methods public Hashtable symtab; // symbol table (fields & methods) public Attribute[] attributes; // class attributes // built after superclass has been loaded by client public Field[] imtable; // instance method table public Field[] smtable; // static method table public Field[] ivtable; // instance variable table public Field[] cvtable; // class variable table public Hashtable visiblevars; // Hashtable of visible instance // fields // Not set by constructor Client must set. // (e.g. toba.translator.Super) public ClassData superclass; // superclass data // Not set by constructor Client must set. // (e.g. toba.runtime.CodeGen) public Class javaClass; // The java runtime counterpart // of this class public ClassRef myRef; // A ClassRef for this class public int state; // records what resolution has // been done to this class public int cdsrc; // Where did this come from?// potential states for ClassDatapublic static final int RES_NONE = 0;public static final int RES_SUPERCLASSES = 1;public static final int RES_CONSTANTS = 2;// flags from Java class filespublic static final int ACC_PUBLIC = 0x0001;public static final int ACC_PRIVATE = 0x0002;public static final int ACC_PROTECTED = 0x0004;public static final int ACC_STATIC = 0x0008;public static final int ACC_FINAL = 0x0010;public static final int ACC_SYNCHRONIZED = 0x0020;public static final int ACC_VOLATILE = 0x0040;public static final int ACC_TRANSIENT = 0x0080;public static final int ACC_NATIVE = 0x0100;public static final int ACC_INTERFACE = 0x0200;public static final int ACC_ABSTRACT = 0x0400;// Source of the classdata structurepublic static final int CDSRC_classfile = 0; // Some JVM class structurepublic static final int CDSRC_tobaclass = 1; // A pre-compiled Toba class struct// set by IHash.mark() ONLY IN TRANSLATOR (?)public static final int FLG_INTERFACE = 0x8000; // interface method// new ClassData(d) -- load class data from DataInputStream d//// Note: the file is closed after loading./** Initialize a basic ClassData structure from the data in the toba Class * structure at claddr. * @param cld raw ClassData instance to be filled in * @param cl Java Class which gets us access to native Class structure. * Toba hash code: _CC_a8RIy */private static native voidClassDataInternal (ClassData cld, Class cl);/** Add an array of fields to the symbol table. * @param farr fields to be added */private voidaddSymFields (Field farr[]){ int i; Field f; for (i = 0; i < farr.length; i++) { f = farr [i]; f.next = (Field) symtab.get (f.name); symtab.put (f.name, f); } return;}/* Constructors are private: data should be located by name or file, to ensure * uniqueness. This one reconstructs the data from an existing Class object. */privateClassData(Class cl){ int i; // Use the native function to fill in what we can from the C structure ClassDataInternal (this, cl); // Complete filling out the stuff that's easier to do up here. /* Basic name mangling */ cname = Names.hashclass(name); fname = Names.classfile(name); major = 45; minor = 3; /* Mark this as from a Toba class, so we don't try to resolve things * that have already been set up. */ cdsrc = ClassData.CDSRC_tobaclass; /* Put fields and methods into symbol table */ symtab = new Hashtable(); for (i = 0; i < fields.length; i++) { Field f = fields [i]; f.cname = Names.hashvar(f.name); } addSymFields (fields); for (i = 0; i < methods.length; i++) { Field f = methods [i]; f.cname = Names.hashmethod(f.name, this.name, f.signature); } addSymFields (methods); /* Hope we don't need any attributes, cuz they're long gone. */ attributes = new Attribute[0]; /* We haven't done any resolution yet. */ state = RES_NONE; return;}/* This one sets up ClassData based on data in a class file. */privateClassData(DataInputStream d) throws ClassFormatError, IOException{ symtab = new Hashtable(); // read header if (d.readInt() != 0xCafeBabe) throw new ClassFormatError("bad magic number"); minor = d.readUnsignedShort(); major = d.readUnsignedShort(); // read constant table constants = Constant.load(d); // read access flags, class, superclass access = d.readUnsignedShort(); name = ((ClassRef)constants[d.readUnsignedShort()].value).name; cname = Names.hashclass(name); fname = Names.classfile(name); int i = d.readUnsignedShort(); if (i > 0) supername = ((ClassRef)constants[i].value).name; // read interface list interfaces = new ClassRef[d.readUnsignedShort()]; for (i = 0; i < interfaces.length; i++) { int j = d.readUnsignedShort(); if (j > 0) interfaces[i] = (ClassRef)constants[j].value; else interfaces[i] = null; } // read fields fields = new Field[d.readUnsignedShort()]; for (i = 0; i < fields.length; i++) { Field f = new Field(d, constants); // for naming purposes, assume no shadowing f.cname = Names.hashvar(f.name); f.classfilePos = i; fields[i] = f; } addSymFields (fields); // read methods methods = new Field[d.readUnsignedShort()]; for (i = 0; i < methods.length; i++) { Field f = new Field(d, constants); f.cname = Names.hashmethod(f.name, this.name, f.signature); f.classfilePos = i; methods[i] = f; } addSymFields (methods); // read class attributes attributes = new Attribute[d.readUnsignedShort()]; for (i = 0; i < attributes.length; i++) attributes[i] = new Attribute(d, constants); // no resolution has been done on this class this.myRef = ClassRef.byName (name); state = RES_NONE; // all done d.close(); // close file for convenience of caller cdsrc = ClassData.CDSRC_classfile; return;}public static ClassDataforStream (ClassLoader cld, DataInputStream d)throws IOException{ return ClassData.forStream (cld, d, true);}public static ClassDataforStream (ClassLoader cld, DataInputStream d, boolean rememberp)throws IOException{ ClassData ncd; ClassData ocd; /* Create a ClassData, so we know what name we're looking for. */ ncd = new ClassData (d); /* If we already have a ClassData structure for this name, return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -