classholder.java

来自「derby database source code.good for you.」· Java 代码 · 共 907 行 · 第 1/2 页

JAVA
907
字号
	public int addClassReference(String fullyQualifiedName) {		if (ClassHolder.isExternalClassName(fullyQualifiedName)) {			fullyQualifiedName = ClassHolder.convertToInternalClassName(fullyQualifiedName);			// System.out.println("addClassReference " + fullyQualifiedName);		}		int name_index = addUtf8Entry(fullyQualifiedName).getIndex();		return addIndexReference(VMDescriptor.CONSTANT_Class, name_index, 0);	}	/**		Add a name and type entry	*/	private int addNameAndType(String name, String descriptor) {		int nameIndex = addUtf8Entry(name).getIndex();		int descriptorIndex = addUtf8Entry(descriptor).getIndex();		return addIndexReference(VMDescriptor.CONSTANT_NameAndType, nameIndex, descriptorIndex);	}	/**		Add a UTF8 into the pool and return the index to it.	*/	private CONSTANT_Utf8_info addUtf8Entry(String value) {		CONSTANT_Utf8_info item = (CONSTANT_Utf8_info) findMatchingEntry(value);		if (item == null) {			item = new CONSTANT_Utf8_info(value);			addEntry(value, item);		}		return item;	}	/**		Add an extra UTF8 into the pool 	*/	private CONSTANT_Utf8_info addExtraUtf8(String value) {		CONSTANT_Utf8_info item = new CONSTANT_Utf8_info(value);		addEntry(null, item);		return item;	}	/**		Add a string entry	*/	private int addString(String value) {		CONSTANT_Utf8_info sutf = addUtf8Entry(value);		int valueIndex = sutf.setAsString();		if (valueIndex == 0) {			// string is already being used as code			valueIndex = addExtraUtf8(value).getIndex();			sutf.setAlternative(valueIndex);		}		return addIndexReference(VMDescriptor.CONSTANT_String, valueIndex, 0);	}	/**		Add a string entry	*/	private int addCodeUtf8(String value) {		CONSTANT_Utf8_info sutf = addUtf8Entry(value);		int index = sutf.setAsCode();		if (index == 0) {			// code string is already being used as string			CONSTANT_Utf8_info eutf = addExtraUtf8(value);			eutf.setAsCode(); // ensure the replace will happen			index = eutf.getIndex();			sutf.setAlternative(index);		}		return index;	} 	protected void cptPut(ClassFormatOutput out) throws IOException {		for (Enumeration e = cptEntries.elements(); e.hasMoreElements(); ) {			ConstantPoolEntry item = (ConstantPoolEntry) e.nextElement();			if (item == null) {				continue;			}			item.put(out);		}	}	/*	** Methods to convert indexes to constant pool entries and vice-versa.	*/	ConstantPoolEntry getEntry(int index) {		return (ConstantPoolEntry) cptEntries.elementAt(index);	}	/**		Return the class name for an index to a CONSTANT_Class_info.	*/	protected String className(int classIndex) {		CONSTANT_Index_info ci = (CONSTANT_Index_info) getEntry(classIndex);		return nameIndexToString(ci.getI1()).replace('/', '.');	}	/*	** Methods to find specific types of constant pool entries.	   In these methods we try to avoid using the ConstantPoolEntry.matchValue()	   as that requires creating a new object for the search. The matchValue()	   call is really intended for when objects are being added to the constant pool.	*/	/**		Return the index of a UTF entry or -1 if it doesn't exist.	*/	int findUtf8(String value) {		ConstantPoolEntry item = findMatchingEntry(value);		if (item == null)			return -1;		return item.getIndex();	}	/**		Find a class descriptor (section 4.4.1) and return its		index, returns -1 if not found.	*/	public int findClass(String fullyQualifiedName) {		String internalName = ClassHolder.convertToInternalClassName(fullyQualifiedName);		int utf_index = findUtf8(internalName);		if (utf_index < 0)			return -1;		return findIndexIndex(VMDescriptor.CONSTANT_Class,			utf_index, 0);	}	/**		Find a name and type descriptor (section 4.4.6) and		return it's index.         <p>        returns -1 if not found.	*/	public int findNameAndType(String name, String descriptor) {		int name_index = findUtf8(name);		if (name_index < 0)			return -1;		int descriptor_index = findUtf8(descriptor);		if (descriptor_index < 0)			return -1;		return findIndexIndex(VMDescriptor.CONSTANT_NameAndType,			name_index, descriptor_index);	}/*	public ClassMember findReference(int classIndex, int nameAndTypeIndex) {		CONSTANT_Index_info item = findIndexEntry(VMDescriptor.CONSTANT_Methodref,				classIndex, nameAndTypeIndex);		if (item == null) {			item = findIndexEntry(VMDescriptor.CONSTANT_InterfaceMethodref,				classIndex, nameAndTypeIndex);			if (item == null) {				item = findIndexEntry(VMDescriptor.CONSTANT_Fieldref,					classIndex, nameAndTypeIndex);				if (item == null)					return null;			}		}		return new ReferenceMember(this, item);	}*/	protected CONSTANT_Index_info findIndexEntry(int tag, int i1, int i2) {		// search for the item using the pre-allocated object 		searchIndex.set(tag, i1, i2);		return (CONSTANT_Index_info) findMatchingEntry(searchIndex);	}	protected int findIndexIndex(int tag, int i1, int i2) {		CONSTANT_Index_info item = findIndexEntry(tag, i1, i2);		if (item == null)			return -1;		return item.getIndex();	}	protected ConstantPoolEntry findMatchingEntry(Object key) {		return (ConstantPoolEntry) cptHashTable.get(key);	}	/** get a string (UTF) given a name_index into the constant pool	   */	String nameIndexToString(int index) {		return getEntry(index).toString();	}	/** get the class name of a Class given the index of its CONSTANT_Class_info	    entry in the Constant Pool.		*/	protected String getClassName(int index) {		if (index == 0)			return ""; // must be the super class of java.lang.Object, ie. nothing.		return 	nameIndexToString(getEntry(index).getI1());	}	/*	 * Determine whether the class descriptor string is 	 * in external format or not.  Assumes that to be in external	 * format means it must have a '.' or end in an ']'.	 * 	 * @param className	the name of the class to check	 *	 * @return true/false	 */	public static boolean isExternalClassName(String className)	{		int len;		if (className.indexOf('.') != -1)		{			return true;		}		else if ((len = className.length()) == 0)		{ 			return false;		}		return (className.charAt(len - 1) == ']');	}	/*	 * Convert a class name to the internal VM class name format.	   See sections 4.3.2, 4.4.1 of the vm spec.	 * The normal leading 'L' and trailing ';' are left	 * off of objects.  This is intended primarily for	 * the class manager.	 * <p>	 * An example of a conversion would be java.lang.Double[]	 * to "[Ljava/lang/Double;".	 <BR>	   java.lang.Double would be converted to "java/lang/Double"	<BR>	Note that for array types the result of convertToInternalClassName()	and convertToInternalDescriptor() are identical.	 *	 * @param the external name (cannot be null)	 *	 * @return the internal string	 */	public static String convertToInternalClassName(String externalName)	{		return convertToInternal(externalName, false);	}	/*	 * Convert a class name to internal JVM descriptor format.	   See sections 4.3.2 of the vm spec.	 * <p>	 * An example of a conversion would be "java.lang.Double[]"	 * to "[Ljava/lang/Double;".	 *	 <BR>	   java.lang.Double would be converted to "Ljava/lang/Double;"	<BR>	Note that for array types the result of convertToInternalClassName()	and convertToInternalDescriptor() are identical.	 * @param the external name (cannot be null)	 *	 * @return the internal string	 */	public static String convertToInternalDescriptor(String externalName)	{		return convertToInternal(externalName, true);	}	/*	** Workhorse method.  Convert to internal format.		@param descriptor True if converting to descriptor format, false if		converting to class name format.	**	** Lifted from BCClass.java. 	**	** Returns the result string.	*/	private static String convertToInternal(String externalName, boolean descriptor)	{		if (SanityManager.DEBUG)		{			SanityManager.ASSERT(externalName != null, "unexpected null");		}		int len = externalName.length();		String internalName;			String retVal = null;			int origLen = len;		int arity = 0;		// first walk through all array-ness		if (externalName.charAt(len-1) == ']')		{			while (len > 0				&& externalName.charAt(len-1) == ']'				&& externalName.charAt(len-2) == '[') 			{				len -= 2;				arity++;			}		}		if (SanityManager.DEBUG) {			SanityManager.ASSERT(len > 0);		}		internalName = (origLen == len)? 						  externalName 						: externalName.substring(0,len);	    // then check for primitive types ... 		// in length by expected frequency order		switch (len) {			case 7 :		        if ("boolean".equals(internalName)) {					retVal = makeDesc(VMDescriptor.C_BOOLEAN, arity);				}				break;			case 4 :		        if ("void".equals(internalName)) {					retVal = makeDesc(VMDescriptor.C_VOID, arity);				}		        else if ("long".equals(internalName)) {					retVal = makeDesc(VMDescriptor.C_LONG, arity);				}		        else if ("byte".equals(internalName)) {					retVal = makeDesc(VMDescriptor.C_BYTE, arity);				}		        else if ("char".equals(internalName)) {					retVal = makeDesc(VMDescriptor.C_CHAR, arity);				}				break;			case 3 :		        if ("int".equals(internalName)) {					retVal = makeDesc(VMDescriptor.C_INT, arity);				}				break;			case 6 :		        if ("double".equals(internalName)) {					retVal = makeDesc(VMDescriptor.C_DOUBLE, arity);				}				break;			case 5 :		        if ("short".equals(internalName)) {					retVal = makeDesc(VMDescriptor.C_SHORT, arity);				}		        else if ("float".equals(internalName)) {					retVal = makeDesc(VMDescriptor.C_FLOAT, arity);				}				break;		}		// then it must be a Java class		if (retVal == null)			retVal = makeDesc(internalName, arity, descriptor);		return retVal;	}	/**		A helper to build a type description based on a built-in type		and an array arity.	 */	static private String makeDesc (char builtin, int arity) {		if (arity == 0)			switch (builtin) {				case VMDescriptor.C_BYTE : return VMDescriptor.BYTE;				case VMDescriptor.C_CHAR : return VMDescriptor.CHAR;				case VMDescriptor.C_DOUBLE : return VMDescriptor.DOUBLE;				case VMDescriptor.C_FLOAT : return VMDescriptor.FLOAT;				case VMDescriptor.C_INT : return VMDescriptor.INT;				case VMDescriptor.C_LONG : return VMDescriptor.LONG;				case VMDescriptor.C_SHORT : return VMDescriptor.SHORT;				case VMDescriptor.C_BOOLEAN : return VMDescriptor.BOOLEAN;				case VMDescriptor.C_VOID : return VMDescriptor.VOID;				default: 					if (SanityManager.DEBUG)						SanityManager.THROWASSERT("No type match");					return null;			}		else {			StringBuffer desc = new StringBuffer(arity+3);			for (int i=0;i<arity;i++)				desc.append(VMDescriptor.C_ARRAY);			desc.append(ClassHolder.makeDesc(builtin, 0));			return desc.toString();		}	}	/**		A helper to build a type description based on a Java class		and an array arity.		If descriptor is true create a descriptor according to		section 4.3.2 of the vm spec. If false create a class name		according to sections 4.3.2 and 4.4.1 of the vm spec.		 */	static private String makeDesc (String className, int arity, boolean descriptor) {		if (!descriptor && (arity == 0)) {			return className.replace('.','/');		}		StringBuffer desc = new StringBuffer(arity+2+className.length());		for (int i=0;i<arity;i++)			desc.append(VMDescriptor.C_ARRAY);		desc.append(VMDescriptor.C_CLASS);		desc.append(className.replace('.','/'));		desc.append(VMDescriptor.C_ENDCLASS);		return desc.toString();	}}

⌨️ 快捷键说明

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