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 + -
显示快捷键?