classinfo.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,142 行 · 第 1/3 页

JAVA
1,142
字号
	    if  (name.string.equals(/*NOI18N*/"SourceFile")) {		if (ClassInfo.classDebug) {		    UnicodeConstant srcName =			(UnicodeConstant)constants[in.readUnsignedShort()];		    sourceFileAttr =			new SourceFileAttribute(name, bytes, srcName);		    clssAttr.addElement(sourceFileAttr);		} else {		    byte[] b = new byte[bytes];		    in.readFully(b);		    clssAttr.addElement			(new UninterpretedAttribute(name, bytes, b));		}	    } else if (name.string.equals("InnerClasses")) {		//Added to support the InnerClasses Attribute defined in the		//1.2 JVM Spec.		/* this need not be done if reflection isn't supported */		innerClassAttr = (InnerClassAttribute)InnerClassAttribute.readAttribute(in, bytes, name, constants);		clssAttr.addElement(innerClassAttr);            /* TODO :: BEGIN experimental code for future signature support.            } else if (name.string.equals("Signature")) {		// Added to support the Signature Attribute defined in the		// 1.5 VM spec.		// this need not be done if reflection isn't supported.		int idx = in.readUnsignedShort();		UnicodeConstant signature = (UnicodeConstant)constants[idx];		//StringConstant sigStr = StringConstant.utfToString(signature);		//sigStr = (StringConstant)cp.add(sigStr);		//sigStr.resolve(cp);		//constants = cp.getConstants();                signatureAttr =		    //new SignatureAttribute(name, bytes, sigStr);		    new SignatureAttribute(name, bytes, signature);		clssAttr.addElement(signatureAttr);            * TODO :: END */	    } else {		byte[] b = new byte[bytes];		in.readFully(b);		clssAttr.addElement		    (new UninterpretedAttribute(name, bytes, b));	    }	}	int nattr = clssAttr.size();	if (nattr > 0) {	    this.classAttributes = new Attribute[nattr];	    clssAttr.copyInto(classAttributes);	}    }    // Read in the entire classfile.    // Assumes that the file is open, and the magic numbers are o.k.    //    public void    read(DataInput in, boolean readCode)    throws IOException {	readConstantPool(in);        flattenConstants();        Assert.disallowClassloading();	ConstantObject constants[] = cp.getConstants();	access = in.readUnsignedShort();	thisClass = (ClassConstant) constants[in.readUnsignedShort()];	int sup = in.readUnsignedShort();	if (sup != 0) {	    superClass = (ClassConstant) constants[sup];        }	className = thisClass.name.string;	pkgNameLength = className.lastIndexOf(SIGC_PACKAGE);	// Read the various parts of the class file	readInterfaces( in );	readFields( in );	readMethods( in, readCode );	readAttributes( in );	/* DONT DO THIS HERE enterClass(); */        Assert.allowClassloading();    }    // Sets the classfile version numner:    public void setVersionInfo(int majorVersion, int minorVersion) {	this.majorVersion = majorVersion;	this.minorVersion = minorVersion;    }    // Compute the fieldtable for a class.  This requires laying    // out the fieldtable for our parent, then adding any fields    // that are not inherited.    public    void buildFieldtable(){	if (this.fieldtable != null) return; // already done.	FieldInfo fieldtable[];	int n;	int fieldoff;	int fieldtableLength = 0;	FieldInfo candidate[] = this.fields;	for( int i =0; i < candidate.length; i++ ){	    if ((candidate[i].access & Const.ACC_STATIC) == 0){		fieldtableLength++;	    }	}	if ( superClassInfo != null ){	    superClassInfo.buildFieldtable();	    n = superClassInfo.fieldtable.length;	    fieldtableLength += n;	    fieldoff = (n==0)? 0		    : (superClassInfo.fieldtable[n-1].instanceOffset +			superClassInfo.fieldtable[n-1].nSlots);	    fieldtable = new FieldInfo[ fieldtableLength ];	    System.arraycopy( superClassInfo.fieldtable, 0, fieldtable, 0, n );	} else {	    fieldtable = new FieldInfo[ fieldtableLength ];	    n = 0;	    fieldoff = 0;	}	for( int i =0; i < candidate.length; i++ ){	    if ((candidate[i].access & Const.ACC_STATIC) == 0){		fieldtable[n++] = candidate[i];		candidate[i].instanceOffset = fieldoff;		fieldoff += candidate[i].nSlots;	    }	}	this.fieldtable = fieldtable;	//	// Build a mapping of slot id to FieldInfo structure.	// This makes offset based calculations much easier -- for	// example stackmap computation	//	this.slottable  = buildSlotTable(fieldtable, fieldoff);    }    //    // Build a mapping of slot id to FieldInfo structure.    // This makes offset based calculations much easier -- for    // example stackmap computation    //    private FieldInfo[] buildSlotTable(FieldInfo[] fieldtable,				       int slotTableSize) {	FieldInfo[] slotTable = new FieldInfo[slotTableSize];	int sIdx = 0;	for (int i = 0; i < fieldtable.length; i++) {	    FieldInfo fld = fieldtable[i];	    if (fld.nSlots == 1) {		slotTable[sIdx] = fld;	    } else {		slotTable[sIdx]     = fld;		slotTable[sIdx + 1] = fld;	    }	    sIdx += fld.nSlots;	}	return slotTable;    }    // Compute the method table for a class.  This requires laying    // out the method table for our parent, then adding any methods    // that are not inherited.    //    // Jdk 1.4 javac does not insert miranda methods    // into a class if the class is abstract and does not     // declare all the methods of its direct superinterfaces,    // like older versions of javac. So we are doing it.    public    void buildMethodtable() {	if ( this.methodtable != null ) return; // already done.	MethodInfo table[];	MethodInfo methods0[] = this.methods;	ClassInfo sup = superClassInfo;	int myPkgNameLength = this.pkgNameLength;	if ((sup != null) && ( (sup.access&Const.ACC_INTERFACE)==(this.access&Const.ACC_INTERFACE) ) ) {	    sup.buildMethodtable();	    table = sup.methodtable;	} else {	    table = new MethodInfo[0];	}	//	// This might change soon, if we try to override the non-trivial	// finalizer of the superclass with a trivial one. Otherwise	// it stands.	//	if (sup != null) {	    this.hasNonTrivialFinalizer = sup.hasNonTrivialFinalizer;	}	/*	 * allocate a temporary table that is certainly large enough.	 * It starts as a copy of our parent's table	 */	MethodInfo newTable[] = new MethodInfo[table.length + methods0.length];	int index = table.length;	System.arraycopy( table, 0, newTable, 0, index );		if (sup == null) { 	    // finalize() goes into slot 0 of java.lang.Object	    index++;	}    method_loop:	for (int i = 0; i < methods0.length; i++) {	    if ((methods0[i].access & (Const.ACC_STATIC|Const.ACC_PRIVATE)) != 0) {		/* static and private methods don't go in the table */		continue method_loop;	    } else if (methods0[i].name.string.equals(/*NOI18N*/"<init>")) {		/* <init> methods don't go in the table */		continue method_loop;	    } else if (sup == null && methods0[i].name.string.equals(/*NOI18N*/"finalize") 		                   && methods0[i].type.string.equals(/*NOI18N*/"()V")) {		/* java.lang.Object.finalize()V always goes at the top of the table*/	        newTable[0] = methods0[i];		newTable[0].methodTableIndex = 0; // 1=>0 EJVM		continue method_loop;	    } 	    int j;	    int thisID = methods0[i].getID();	    if (thisID == finalizerID) {		/* Note that this class has its own finalizer */		this.hasNonTrivialFinalizer = methods0[i].isNonTrivial();	    }	    /*	     * Now search the table (initialized with our parent's table)	     * for a name/type match.	     * Since private methods aren't even in the table, we don't have	     * to worry about those. But we do need to consider	     * package scoping.	     */	match_loop:	    for ( j = 0; j < table.length; j++) {		if (thisID == table[j].getID()) {		    MethodInfo parentMethod = table[j];		    if ((parentMethod.access & (Const.ACC_PUBLIC|Const.ACC_PROTECTED)) 			== 0)		    {			/*			 * we must be in the same package to override this one			 * sadly, the only way to compare packages is 			 * to compare names			 */			int     parentPkgNameLength = parentMethod.parent.pkgNameLength;			boolean equalPkgNames;			if (parentPkgNameLength != myPkgNameLength){			    /* package names of unequal length. Quick failure */			    equalPkgNames = false;			} else if (myPkgNameLength == -1){			    equalPkgNames = true; // neither is in a package.			} else {			    equalPkgNames = parentMethod.parent.className.regionMatches(					    0, className, 0, myPkgNameLength);			}			if (! equalPkgNames){			    /* package names of unequal value. Failure */			    continue match_loop;			}		    }		    newTable[j] = methods0[i];		    newTable[j].methodTableIndex = j + 0; // 1=>0 EJVM		    continue method_loop;		}	    }	    // If we're not overriding our parent's method we do add	    // a new entry to the method table.	    newTable[index] = methods0[i];	    newTable[index].methodTableIndex = index + 0; // 1=>0 EJVM	    index++;	}	// now allocate a table of the correct size.	MethodInfo methodTable0[] = new MethodInfo[index];	System.arraycopy( newTable, 0, methodTable0, 0, index );        this.methodtable =  methodTable0;        // now try to resolve miranda methods.        MethodInfo thisMethodtable[] = null;        MethodInfo thisMethods[] = null;        if ((this.access&Const.ACC_ABSTRACT) != 0 &&            (this.access&Const.ACC_INTERFACE) == 0 ) {            int i;            int methodsnumber = methods.length;            for (i = 0; i < interfaces.length; i++) {                 ClassInfo superinterface = interfaces[i].find();                 superinterface.buildMethodtable();                 MethodInfo interfaceMethodtable[] = superinterface.methodtable;                 MethodInfo tmpTable[] = new MethodInfo[interfaceMethodtable.length];                 int idx = 0;            interface_method_loop:                 for (int j = 0; j < interfaceMethodtable.length; j++) {                     int imID = interfaceMethodtable[j].getID();                     for (int k = 0; k < methodtable.length; k++) {                         if (imID == methodtable[k].getID()) {                             continue interface_method_loop;                          }                     }                     // We need to get a copy of the methodInfo, because                     // we are going to change its states.                     try {                         tmpTable[idx] =                              (MethodInfo)(interfaceMethodtable[j].clone());                         tmpTable[idx].parent = this;                         tmpTable[idx].index = methodsnumber;                         methodsnumber++;                     } catch (CloneNotSupportedException cnse) {                         cnse.printStackTrace();                     }                     idx++;                 }                 // We need to insert these miranda methods into                 // both this.methods[] and this.methodtable[].                 // The reason is methods[] data structure is                 // used to resolve MethodRef constant in quicken                 // process, while methodtable[] is used in                 // InterfaceMethodTable.generateInterfaceVector()                 // to verify if the class implements all the                  // interface methods.                 if (idx > 0) {                     int newMethodsNum = methods.length + idx;                     thisMethods = new MethodInfo[newMethodsNum];                     System.arraycopy(methods, 0, thisMethods, 0, methods.length);                     System.arraycopy(tmpTable, 0, thisMethods, methods.length, idx);                     this.methods = thisMethods;                     int newTableLen = methodtable.length + idx;                     thisMethodtable = new MethodInfo[newTableLen];                     System.arraycopy(methodtable, 0,                         thisMethodtable, 0, methodtable.length);                     System.arraycopy(tmpTable, 0,                         thisMethodtable, methodtable.length, idx);                     for (int mtidx = methodtable.length; mtidx < newTableLen; mtidx++) {                         thisMethodtable[mtidx].methodTableIndex = mtidx + 0;                     }                     this.methodtable = thisMethodtable;                 }            }        }     }    private static boolean    conditionalAdd( Vector v, Object o ){	if ( v.contains( o ) )	    return false;	v.addElement( o );	return true;    }    /*     * Compute the vector of all interfaces this class implements (or     * this interface extends). Not only the interfaced declared in     * the implements clause, which is what the interfaces[] field     * represents, but all interfaces, including those of our superclasses     * and those extended/implemented by any interfaces we implement.     *     */    public void    findAllInterfaces(){	/*	 * This works recursively, by computing parent's interface	 * set first. THIS ASSUMES NON-CIRCULARITY, as does the rest	 * of the Java system. This assumption will fail loudly, if	 * at all.	 */	if ( allInterfaces != null )	    return; // already done	if ( superClassInfo == null ){	    // we must be java.lang.Object!	    allInterfaces = new Vector(5); // a generous size.	} else {	    if ( superClassInfo.allInterfaces == null )		superClassInfo.findAllInterfaces();	    allInterfaces = (Vector)(superClassInfo.allInterfaces.clone());	}	if ( interfaces == null ) return; // all done!	for( int i = 0; i < interfaces.length; i++ ){	    ClassInfo interf = interfaces[i].find();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?