/** * Returns the class's access flags (see {@link Opcodes}). This value may not reflect Deprecated * and Synthetic flags when bytecode is before 1.5 and those flags are represented by attributes. * * @return the class access flags. * @see ClassVisitor#visit(int, int, String, String, String, String[]) */ public int getAccess() { return readUnsignedShort(header); }
/** * Returns the class's access flags (see {@link Opcodes}). This value may * not reflect Deprecated and Synthetic flags when bytecode is before 1.5 * and those flags are represented by attributes. * * @return the class access flags * @see ClassVisitor#visit(int,int,String,String,String,String[]) */ public int getAccess() { return readUnsignedShort(header); }
/** * Returns the class's access flags (see {@link Opcodes}). This value may * not reflect Deprecated and Synthetic flags when bytecode is before 1.5 * and those flags are represented by attributes. * * @return the class access flags * * @see ClassVisitor#visit(int, int, String, String, String, String[]) */ public int getAccess() { return readUnsignedShort(header); }
/** * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method * is intended for {@link Attribute} sub classes, and is normally not needed * by class generators or adapters.</i> * * @param index the start index of an unsigned short value in {@link #b b}, * whose value is the index of an UTF8 constant pool item. * @param buf buffer to be used to read the item. This buffer must be * sufficiently large. It is not automatically resized. * @return the String corresponding to the specified UTF8 item. */ public String readUTF8(int index, final char[] buf) { int item = readUnsignedShort(index); String s = strings[item]; if (s != null) { return s; } index = items[item]; return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf); }
/** * Returns the start index of the attribute_info structure of this class. * * @return the start index of the attribute_info structure of this class. */ private int getAttributes() { // skips the header int u = header + 8 + readUnsignedShort(header + 6) * 2; // skips fields and methods for (int i = readUnsignedShort(u); i > 0; --i) { for (int j = readUnsignedShort(u + 8); j > 0; --j) { u += 6 + readInt(u + 12); } u += 8; } u += 2; for (int i = readUnsignedShort(u); i > 0; --i) { for (int j = readUnsignedShort(u + 8); j > 0; --j) { u += 6 + readInt(u + 12); } u += 8; } // the attribute_info structure starts just after the methods return u + 2; }
@Override protected Attribute read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels) { int resolution = cr.readUnsignedShort(off); return new ModuleResolutionAttribute(resolution); }
/** * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method * is intended for {@link Attribute} sub classes, and is normally not needed * by class generators or adapters.</i> * * @param index * the start index of an unsigned short value in {@link #b b}, * whose value is the index of an UTF8 constant pool item. * @param buf * buffer to be used to read the item. This buffer must be * sufficiently large. It is not automatically resized. * @return the String corresponding to the specified UTF8 item. */ public String readUTF8(int index, final char[] buf) { int item = readUnsignedShort(index); if (index == 0 || item == 0) { return null; } String s = strings[item]; if (s != null) { return s; } index = items[item]; return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf); }
/** * Read a stringish constant item (CONSTANT_Class, CONSTANT_String, * CONSTANT_MethodType, CONSTANT_Module or CONSTANT_Package * @param index * @param buf * @return */ private String readStringish(final int index, final char[] buf) { // computes the start index of the item in b // and reads the CONSTANT_Utf8 item designated by // the first two bytes of this item return readUTF8(items[readUnsignedShort(index)], buf); }
/** * Returns the internal of name of the super class (see * {@link Type#getInternalName() getInternalName}). For interfaces, the * super class is {@link Object}. * * @return the internal name of super class, or <tt>null</tt> for * {@link Object} class. * @see ClassVisitor#visit(int,int,String,String,String,String[]) */ public String getSuperName() { int n = items[readUnsignedShort(header + 4)]; return n == 0 ? null : readUTF8(n, new char[maxStringLength]); }
/** * Reads a CONSTANT_Class, CONSTANT_String, CONSTANT_MethodType, CONSTANT_Module or * CONSTANT_Package constant pool entry in {@link #b}. <i>This method is intended for {@link * Attribute} sub classes, and is normally not needed by class generators or adapters.</i> * * @param offset the start offset of an unsigned short value in {@link #b}, whose value is the * index of a CONSTANT_Class, CONSTANT_String, CONSTANT_MethodType, CONSTANT_Module or * CONSTANT_Package entry in class's constant pool table. * @param charBuffer the buffer to be used to read the item. This buffer must be sufficiently * large. It is not automatically resized. * @return the String corresponding to the specified constant pool entry. */ private String readStringish(final int offset, final char[] charBuffer) { // Get the start offset of the cp_info structure (plus one), and read the CONSTANT_Utf8 entry // designated by the first two bytes of this cp_info. return readUTF8(cpInfoOffsets[readUnsignedShort(offset)], charBuffer); }
/** * Reads a CONSTANT_Utf8 constant pool entry in {@link #b}. <i>This method is intended for {@link * Attribute} sub classes, and is normally not needed by class generators or adapters.</i> * * @param offset the start offset of an unsigned short value in {@link #b}, whose value is the * index of a CONSTANT_Utf8 entry in the class's constant pool table. * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently * large. It is not automatically resized. * @return the String corresponding to the specified CONSTANT_Utf8 entry. */ // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility). public String readUTF8(final int offset, final char[] charBuffer) { int constantPoolEntryIndex = readUnsignedShort(offset); if (offset == 0 || constantPoolEntryIndex == 0) { return null; } return readUtf(constantPoolEntryIndex, charBuffer); }
/** * Reads a class constant pool item in {@link #b b}. <i>This method is * intended for {@link Attribute} sub classes, and is normally not needed by * class generators or adapters.</i> * * @param index the start index of an unsigned short value in {@link #b b}, * whose value is the index of a class constant pool item. * @param buf buffer to be used to read the item. This buffer must be * sufficiently large. It is not automatically resized. * @return the String corresponding to the specified class item. */ public String readClass(final int index, final char[] buf) { // computes the start index of the CONSTANT_Class item in b // and reads the CONSTANT_Utf8 item designated by // the first two bytes of this CONSTANT_Class item return readUTF8(items[readUnsignedShort(index)], buf); }
/** * Reads a CONSTANT_Utf8 constant pool entry in {@link #b}. * * @param constantPoolEntryIndex the index of a CONSTANT_Utf8 entry in the class's constant pool * table. * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently * large. It is not automatically resized. * @return the String corresponding to the specified CONSTANT_Utf8 entry. */ final String readUtf(final int constantPoolEntryIndex, final char[] charBuffer) { String value = constantUtf8Values[constantPoolEntryIndex]; if (value != null) { return value; } int cpInfoOffset = cpInfoOffsets[constantPoolEntryIndex]; return constantUtf8Values[constantPoolEntryIndex] = readUtf(cpInfoOffset + 2, readUnsignedShort(cpInfoOffset), charBuffer); }
/** * Returns the bytecode offset corresponding to the specified JVMS 'type_annotation' structure, or * -1 if there is no such type_annotation of if it does not have a bytecode offset. * * @param typeAnnotationOffsets the offset of each 'type_annotation' entry in a * Runtime[In]VisibleTypeAnnotations attribute, or null. * @param typeAnnotationIndex the index a 'type_annotation' entry in typeAnnotationOffsets. * @return bytecode offset corresponding to the specified JVMS 'type_annotation' structure, or -1 * if there is no such type_annotation of if it does not have a bytecode offset. */ private int getTypeAnnotationBytecodeOffset( final int[] typeAnnotationOffsets, final int typeAnnotationIndex) { if (typeAnnotationOffsets == null || typeAnnotationIndex >= typeAnnotationOffsets.length || readByte(typeAnnotationOffsets[typeAnnotationIndex]) < TypeReference.INSTANCEOF) { return -1; } return readUnsignedShort(typeAnnotationOffsets[typeAnnotationIndex] + 1); }
/** * Returns the internal names of the implemented interfaces (see {@link Type#getInternalName()}). * * @return the internal names of the directly implemented interfaces. Inherited implemented * interfaces are not returned. * @see ClassVisitor#visit(int, int, String, String, String, String[]) */ public String[] getInterfaces() { // interfaces_count is after the access_flags, this_class and super_class fields (2 bytes each). int currentOffset = header + 6; int interfacesCount = readUnsignedShort(currentOffset); String[] interfaces = new String[interfacesCount]; if (interfacesCount > 0) { char[] charBuffer = new char[maxStringLength]; for (int i = 0; i < interfacesCount; ++i) { currentOffset += 2; interfaces[i] = readClass(currentOffset, charBuffer); } } return interfaces; }
/** * Returns the internal names of the class's interfaces (see * {@link Type#getInternalName() getInternalName}). * * @return the array of internal names for all implemented interfaces or * <tt>null</tt>. * * @see ClassVisitor#visit(int, int, String, String, String, String[]) */ public String[] getInterfaces() { int index = header + 6; int n = readUnsignedShort(index); String[] interfaces = new String[n]; if (n > 0) { char[] buf = new char[maxStringLength]; for (int i = 0; i < n; ++i) { index += 2; interfaces[i] = readClass(index, buf); } } return interfaces; }
/** * Returns the internal names of the class's interfaces (see * {@link Type#getInternalName() getInternalName}). * * @return the array of internal names for all implemented interfaces or * <tt>null</tt>. * @see ClassVisitor#visit(int,int,String,String,String,String[]) */ public String[] getInterfaces() { int index = header + 6; int n = readUnsignedShort(index); String[] interfaces = new String[n]; if (n > 0) { char[] buf = new char[maxStringLength]; for (int i = 0; i < n; ++i) { index += 2; interfaces[i] = readClass(index, buf); } } return interfaces; }
/** * Reads a CONSTANT_Dynamic constant pool entry in {@link #b}. * * @param constantPoolEntryIndex the index of a CONSTANT_Dynamic entry in the class's constant * pool table. * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently * large. It is not automatically resized. * @return the ConstantDynamic corresponding to the specified CONSTANT_Dynamic entry. */ private ConstantDynamic readConstantDynamic( final int constantPoolEntryIndex, final char[] charBuffer) { ConstantDynamic constantDynamic = constantDynamicValues[constantPoolEntryIndex]; if (constantDynamic != null) { return constantDynamic; } int cpInfoOffset = cpInfoOffsets[constantPoolEntryIndex]; int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 2)]; String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer); String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer); int bootstrapMethodOffset = bootstrapMethodOffsets[readUnsignedShort(cpInfoOffset)]; Handle handle = (Handle) readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer); Object[] bootstrapMethodArguments = new Object[readUnsignedShort(bootstrapMethodOffset + 2)]; bootstrapMethodOffset += 4; for (int i = 0; i < bootstrapMethodArguments.length; i++) { bootstrapMethodArguments[i] = readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer); bootstrapMethodOffset += 2; } return constantDynamicValues[constantPoolEntryIndex] = new ConstantDynamic(name, descriptor, handle, bootstrapMethodArguments); }
@Override protected Attribute read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels) { String hashAlgorithm = cr.readUTF8(off, buf); int count = cr.readUnsignedShort(off + 2); ArrayList<String> modules = new ArrayList<String>(count); ArrayList<byte[]> hashes = new ArrayList<byte[]>(count); off += 4; for (int i = 0; i < count; i++) { String module = cr.readModule(off, buf); int hashLength = cr.readUnsignedShort(off + 2); off += 4; byte[] hash = new byte[hashLength]; for (int j = 0; j < hashLength; j++) { hash[j] = (byte) (cr.readByte(off + j) & 0xff); } off += hashLength; modules.add(module); hashes.add(hash); } return new ModuleHashesAttribute(hashAlgorithm, modules, hashes); }
/** * Reads parameter annotations and makes the given visitor visit them. * * @param v start offset in {@link #b b} of the annotations to be read. * @param buf buffer to be used to call {@link #readUTF8 readUTF8}, * {@link #readClass(int,char[]) readClass} or * {@link #readConst readConst}. * @param visible <tt>true</tt> if the annotations to be read are visible * at runtime. * @param mv the visitor that must visit the annotations. */ private void readParameterAnnotations( int v, final char[] buf, final boolean visible, final MethodVisitor mv) { int n = b[v++] & 0xFF; for (int i = 0; i < n; ++i) { int j = readUnsignedShort(v); v += 2; for (; j > 0; --j) { v = readAnnotationValues(v + 2, buf, true, mv.visitParameterAnnotation(i, readUTF8(v, buf), visible)); } } }