classinfo.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,142 行 · 第 1/3 页
JAVA
1,142 行
/* * @(#)ClassInfo.java 1.48 06/10/22 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */package components;import jcc.Util;import jcc.Str2ID;import consts.Const;import util.*;import java.io.DataInput;import java.io.DataOutput;import java.io.IOException;import java.io.PrintStream;import java.util.Enumeration;import java.util.Hashtable;import java.util.Set;import java.util.Vector;/** * ClassInfo is the root of all information about the class * which comes out of the .class file, including its methods, * fields, interfaces, superclass, and any other attributes we * read in. * ClassInfo does not contain (in theory) any VM-specific data. * All the target-VM-specific information is kept in the corresponding * ClassClass: see field vmClass. ClassClass is abstract, so what is * really present is a target-VM-specific subclass of it, such as CVMClass. */publicclass ClassInfo{ public int majorVersion; public int minorVersion; public String className; public int access; public ClassConstant thisClass; public ClassConstant superClass; public ClassInfo superClassInfo; // Tables for all fields, methods and constants of this class public FieldInfo fields[]; public MethodInfo methods[]; private static ConstantPool nullCP = new ConstantPool(new ConstantObject[0]); private ConstantPool cp = nullCP; private ConstantObject oldConstants[]; public ClassConstant interfaces[]; // These are the tables of instance fields and methods. // The methodtable is turned into the virtual method lookup table // of the virtual machine. public FieldInfo fieldtable[]; public MethodInfo methodtable[]; /* * Info on each slot of an object, indexed by offset * instead of on its field # * The difference between fieldtable and slottable is slight * -- its just that double-word fields (types J and D) take * up 2 entries in the slottable. */ public FieldInfo slottable[]; // Class attributes that we do not interpret public Attribute[] classAttributes; public SourceFileAttribute sourceFileAttr; // Innerclass attribute accessed. public InnerClassAttribute innerClassAttr; // Class generics signature info: public SignatureAttribute signatureAttr; public ClassLoader loader; public vm.ClassClass vmClass; // used by in-core output writers public Vector allInterfaces; protected boolean verbose; protected static PrintStream log = System.out; public static boolean classDebug = false; public int flags; public static final int INCLUDE_ALL = 1; public int group; public static int finalizerID = Str2ID.sigHash.getID( /*NOI18N*/"finalize", /*NOI18N*/"()V" ); public boolean hasNonTrivialFinalizer = false; private int pkgNameLength; private final char SIGC_PACKAGE = util.ClassFileConst.SIGC_PACKAGE; public ClassInfo( boolean v ) { Assert.assertClassloadingIsAllowed(); verbose = v; flags = INCLUDE_ALL; // by default, we want all members. // what else should be here? } private String genericNativeName; public final String getGenericNativeName() { if (genericNativeName == null) genericNativeName = createGenericNativeName(); return genericNativeName; } public boolean isFinal() { return ((access & Const.ACC_FINAL) != 0); } // Is this class a subclass of java.lang.ref.Reference? public boolean isReference() { ClassInfo cinfo = this; while (cinfo != null) { if (cinfo.className.equals("java/lang/ref/Reference")) { return true; } cinfo = cinfo.superClassInfo; } return false; } // Is this class an interface? public boolean isInterface() { return ((this.access & Const.ACC_INTERFACE) != 0); } // Is this class the java.lang.Object class? public boolean isJavaLangObject() { ClassInfo cinfo = this; if ((cinfo != null) && cinfo.className.equals("java/lang/Object")) { return true; } return false; } // This will be overridden by subclasses protected String createGenericNativeName() { return Util.convertToClassName(className ); } /** * Reads in the constant pool from a classfile, and fills in the cp * (i.e. constantpool) field of this classinfo instance. The filled in * constants are not yet in a resolved state. */ private void readConstantPool(DataInput in) throws IOException { int num = in.readUnsignedShort(); if(verbose){ log.println(Localizer.getString( "classinfo.reading_entries_in_constant_pool", Integer.toString(num))); } ConstantObject[] constants = new ConstantObject[num]; for (int i = 1; i < num; i+=constants[i].nSlots) { constants[i] = ConstantObject.readObject(in); constants[i].index = i; constants[i].containingClass = this; } cp = new ConstantPool(constants); } /** * Flatten all CP entries so that they need not indirect through the * constant pool to get to the symbollic info. For example, a class * constant is defined by a CP index which point to a UTF8 string. A * flattened class constant will refer to the UTF8 string directly instead * of needing to index into the constant pool to get to it. */ private void flattenConstants() { if (verbose) { log.println(Localizer.getString( "classinfo.>>>resolving_constants")); } ConstantObject constants[] = cp.getConstants(); for (int i = 1; i < constants.length; i+=constants[i].nSlots) { constants[i].flatten(cp); } } /* * Iterate through the constant pool. * Look for class constants that don't point to anything, yet. * Put those String names in the undefClasses set. */ public void findUndefinedClasses(Set undefClasses) { ConstantObject constants[] = cp.getConstants(); for (int i = 1; i < constants.length; i+=constants[i].nSlots) { if (constants[i].tag == Const.CONSTANT_CLASS) { ClassConstant c = (ClassConstant) constants[i]; if (c.find() == null){ String stringname = c.name.string; c.forget(); if (stringname.charAt(0) == '['){ // this is an array. // DO NOT put the array in the table. // but we may need to put an underlying // object type in, so take a closer look. int lindex = stringname.indexOf('L'); if (lindex == -1){ // primitive array type. // not interesting. continue; } // capture the name between the L and the ; stringname = stringname.substring( lindex+1, stringname.length()-1); if (loader.lookupClass(stringname) != null){ continue; // found it. } } undefClasses.add(stringname); } } } } /* * we can make our own table smaller by deleting unreferenced elements. * At this point, * all non-code references into it are by object reference, NEVER * by index -- everything has been resolved! Thus we can * compact our table, deleting all the UnicodeConstants. * We adjust each constant's index entry accordingly. * Naturally, we preserve the null entries. */ public void smashConstantPool() { ConstantObject constants[] = cp.getConstants(); int nOld = constants.length; int nNew = 1; ConstantObject o; // first, count and index. for (int i = 1; i < nOld; i += o.nSlots) { o = constants[i]; if (!o.shared) { if (o.getReferences() == 0) { o.index = -1; // trouble. } else { // we're keeping it. o.index = nNew; nNew += o.nSlots; } } } // now reallocate and copy. ConstantObject newConstants[] = new ConstantObject[ nNew ]; int j = 1; for (int i = 1; i < nOld; i += o.nSlots) { o = constants[i]; if (!o.shared && (o.getReferences() != 0)) { // we're keeping it. newConstants[j] = o; j += o.nSlots; } } oldConstants = constants; cp = new ConstantPool(newConstants); } public ConstantPool getConstantPool() { return cp; } public void setConstantPool(ConstantPool c) { cp = c; } // Read the list of interfaces this class supports void readInterfaces( DataInput in ) throws IOException { int count = in.readUnsignedShort(); if(verbose){ log.println(Localizer.getString( "classinfo.reading_interfaces_implemented", Integer.toString(count))); } interfaces = new ClassConstant[count]; ConstantObject constants[] = cp.getConstants(); for (int i = 0; i < count; i++) { interfaces[i] = (ClassConstant) constants[in.readUnsignedShort()]; } } // Read the list of fields void readFields( DataInput in ) throws IOException { int count = in.readUnsignedShort(); fields = new FieldInfo[count]; if(verbose){ log.println(Localizer.getString("classinfo.reading_field_members", Integer.toString(count))); } int i, j; for (i = j = 0; i < count; i++) { FieldInfo fi = FieldInfo.readField(in, this); if (fi != null) { fields[j] = fi; fields[j].index = j; fields[j++].captureValueAttribute(); } } // If we have discarded any fields, re-create the table. if (j != i) { FieldInfo[] smaller = new FieldInfo[j]; System.arraycopy(fields, 0, smaller, 0, j); fields = smaller; } } // Read the list of methods from classfile void readMethods( DataInput in, boolean readCode ) throws IOException { int count = in.readUnsignedShort(); methods = new MethodInfo[count]; if(verbose){ log.println(Localizer.getString( "classinfo.reading_methods", Integer.toString(count))); } int i, j; for (i = j = 0; i < count; i++) { MethodInfo mi = MethodInfo.readMethod( in, this, readCode ); if (mi != null) { methods[j] = mi; methods[j].index = j++; } } // If we have discarded any methods, re-create the table. if ( j != i ) { MethodInfo[] smaller = new MethodInfo[j]; System.arraycopy(methods, 0, smaller, 0, j); methods = smaller; } } void readAttributes( DataInput in ) throws IOException { int count = in.readUnsignedShort(); Vector clssAttr = new Vector(); if(verbose){ log.println(Localizer.getString("classinfo.reading_attributes", Integer.toString(count))); } ConstantObject constants[] = cp.getConstants(); for (int i = 0; i < count; i++) { int nameIndex = in.readUnsignedShort(); int bytes = in.readInt(); UnicodeConstant name = (UnicodeConstant)constants[nameIndex];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?