diff --git a/spring-core/spring-core.gradle b/spring-core/spring-core.gradle index 9f26b7a993..14475d3221 100644 --- a/spring-core/spring-core.gradle +++ b/spring-core/spring-core.gradle @@ -7,11 +7,11 @@ dependencyManagement { } } -// As of Spring 5.0.3, spring-core includes asm 6.x and repackages cglib 3.2.6+, inlining -// both into the spring-core jar. cglib 3.2.6+ itself depends on asm 6.x and is therefore +// As of Spring 5.1, spring-core includes asm 7.0 and repackages cglib 3.2.8, inlining +// both into the spring-core jar. cglib 3.2.8 itself depends on asm 6+ and is therefore // further transformed by the JarJar task to depend on org.springframework.asm; this // avoids including two different copies of asm unnecessarily. -def cglibVersion = "3.2.7" +def cglibVersion = "3.2.8" def objenesisVersion = "2.6" configurations { diff --git a/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java b/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java index 9a1dc9a90a..e9111fce40 100644 --- a/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java @@ -29,8 +29,8 @@ package org.springframework.asm; /** * A visitor to visit a Java annotation. The methods of this class must be called in the following - * order: ( visit | visitEnum | visitAnnotation | visitArray )* - * visitEnd. + * order: ( {@code visit} | {@code visitEnum} | {@code visitAnnotation} | {@code visitArray} )* + * {@code visitEnd}. * * @author Eric Bruneton * @author Eugene Kuleshov @@ -39,7 +39,7 @@ public abstract class AnnotationVisitor { /** * The ASM API version implemented by this visitor. The value of this field must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. */ protected final int api; @@ -50,8 +50,7 @@ public abstract class AnnotationVisitor { * Constructs a new {@link AnnotationVisitor}. * * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link - * Opcodes#ASM7_EXPERIMENTAL}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. */ public AnnotationVisitor(final int api) { this(api, null); @@ -61,16 +60,12 @@ public abstract class AnnotationVisitor { * Constructs a new {@link AnnotationVisitor}. * * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link - * Opcodes#ASM7_EXPERIMENTAL}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. * @param annotationVisitor the annotation visitor to which this visitor must delegate method * calls. May be null. */ public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) { - if (api != Opcodes.ASM6 - && api != Opcodes.ASM5 - && api != Opcodes.ASM4 - && api != Opcodes.ASM7_EXPERIMENTAL) { + if (api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 && api != Opcodes.ASM7) { throw new IllegalArgumentException(); } this.api = api; @@ -112,9 +107,9 @@ public abstract class AnnotationVisitor { * * @param name the value name. * @param descriptor the class descriptor of the nested annotation class. - * @return a visitor to visit the actual nested annotation value, or null if this visitor - * is not interested in visiting this nested annotation. The nested annotation value must - * be fully visited before calling other methods on this annotation visitor. + * @return a visitor to visit the actual nested annotation value, or {@literal null} if this + * visitor is not interested in visiting this nested annotation. The nested annotation + * value must be fully visited before calling other methods on this annotation visitor. */ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) { if (av != null) { @@ -129,8 +124,8 @@ public abstract class AnnotationVisitor { * visit}. This is what {@link ClassReader} does. * * @param name the value name. - * @return a visitor to visit the actual array value elements, or null if this visitor is - * not interested in visiting these values. The 'name' parameters passed to the methods of + * @return a visitor to visit the actual array value elements, or {@literal null} if this visitor + * is not interested in visiting these values. The 'name' parameters passed to the methods of * this visitor are ignored. All the array values must be visited before calling other * methods on this annotation visitor. */ diff --git a/spring-core/src/main/java/org/springframework/asm/AnnotationWriter.java b/spring-core/src/main/java/org/springframework/asm/AnnotationWriter.java index e740469242..b85e792a46 100644 --- a/spring-core/src/main/java/org/springframework/asm/AnnotationWriter.java +++ b/spring-core/src/main/java/org/springframework/asm/AnnotationWriter.java @@ -112,7 +112,7 @@ final class AnnotationWriter extends AnnotationVisitor { final boolean useNamedValues, final ByteVector annotation, final AnnotationWriter previousAnnotation) { - super(Opcodes.ASM6); + super(Opcodes.ASM7); this.symbolTable = symbolTable; this.useNamedValues = useNamedValues; this.annotation = annotation; diff --git a/spring-core/src/main/java/org/springframework/asm/Attribute.java b/spring-core/src/main/java/org/springframework/asm/Attribute.java index 82fc1b2a6e..7db7de081b 100644 --- a/spring-core/src/main/java/org/springframework/asm/Attribute.java +++ b/spring-core/src/main/java/org/springframework/asm/Attribute.java @@ -31,9 +31,9 @@ package org.springframework.asm; * A non standard class, field, method or code attribute, as defined in the Java Virtual Machine * Specification (JVMS). * - * @see JVMS + * @see JVMS * 4.7 - * @see JVMS + * @see JVMS * 4.7.3 * @author Eric Bruneton * @author Eugene Kuleshov @@ -52,7 +52,7 @@ public class Attribute { /** * The next attribute in this attribute list (Attribute instances can be linked via this field to - * store a list of class, field, method or code attributes). May be null. + * store a list of class, field, method or code attributes). May be {@literal null}. */ Attribute nextAttribute; @@ -66,23 +66,23 @@ public class Attribute { } /** - * Returns true if this type of attribute is unknown. This means that the attribute + * Returns {@literal true} if this type of attribute is unknown. This means that the attribute * content can't be parsed to extract constant pool references, labels, etc. Instead, the * attribute content is read as an opaque byte array, and written back as is. This can lead to * invalid attributes, if the content actually contains constant pool references, labels, or other * symbolic references that need to be updated when there are changes to the constant pool, the - * method bytecode, etc. The default implementation of this method always returns true. + * method bytecode, etc. The default implementation of this method always returns {@literal true}. * - * @return true if this type of attribute is unknown. + * @return {@literal true} if this type of attribute is unknown. */ public boolean isUnknown() { return true; } /** - * Returns true if this type of attribute is a code attribute. + * Returns {@literal true} if this type of attribute is a code attribute. * - * @return true if this type of attribute is a code attribute. + * @return {@literal true} if this type of attribute is a code attribute. */ public boolean isCodeAttribute() { return false; @@ -91,8 +91,8 @@ public class Attribute { /** * Returns the labels corresponding to this attribute. * - * @return the labels corresponding to this attribute, or null if this attribute is not a - * code attribute that contains labels. + * @return the labels corresponding to this attribute, or {@literal null} if this attribute is not + * a code attribute that contains labels. */ protected Label[] getLabels() { return new Label[0]; @@ -114,8 +114,8 @@ public class Attribute { * in {@link ClassReader#b}, or -1 if the attribute to be read is not a code attribute. The 6 * attribute header bytes (attribute_name_index and attribute_length) are not taken into * account here. - * @param labels the labels of the method's code, or null if the attribute to be read is - * not a code attribute. + * @param labels the labels of the method's code, or {@literal null} if the attribute to be read + * is not a code attribute. * @return a new {@link Attribute} object corresponding to the specified bytes. */ protected Attribute read( @@ -138,7 +138,7 @@ public class Attribute { * * @param classWriter the class to which this attribute must be added. This parameter can be used * to add the items that corresponds to this attribute to the constant pool of this class. - * @param code the bytecode of the method corresponding to this code attribute, or null + * @param code the bytecode of the method corresponding to this code attribute, or {@literal null} * if this attribute is not a code attribute. Corresponds to the 'code' field of the Code * attribute. * @param codeLength the length of the bytecode of the method corresponding to this code @@ -197,8 +197,9 @@ public class Attribute { * attribute_length) per attribute. Also adds the attribute type names to the constant pool. * * @param symbolTable where the constants used in the attributes must be stored. - * @param code the bytecode of the method corresponding to these code attributes, or null - * if they are not code attributes. Corresponds to the 'code' field of the Code attribute. + * @param code the bytecode of the method corresponding to these code attributes, or {@literal + * null} if they are not code attributes. Corresponds to the 'code' field of the Code + * attribute. * @param codeLength the length of the bytecode of the method corresponding to these code * attributes, or 0 if they are not code attributes. Corresponds to the 'code_length' field of * the Code attribute. @@ -248,8 +249,9 @@ public class Attribute { * attribute. * * @param symbolTable where the constants used in the attributes must be stored. - * @param code the bytecode of the method corresponding to these code attributes, or null - * if they are not code attributes. Corresponds to the 'code' field of the Code attribute. + * @param code the bytecode of the method corresponding to these code attributes, or {@literal + * null} if they are not code attributes. Corresponds to the 'code' field of the Code + * attribute. * @param codeLength the length of the bytecode of the method corresponding to these code * attributes, or 0 if they are not code attributes. Corresponds to the 'code_length' field of * the Code attribute. diff --git a/spring-core/src/main/java/org/springframework/asm/ByteVector.java b/spring-core/src/main/java/org/springframework/asm/ByteVector.java index 73852d91e1..17d2132024 100644 --- a/spring-core/src/main/java/org/springframework/asm/ByteVector.java +++ b/spring-core/src/main/java/org/springframework/asm/ByteVector.java @@ -327,7 +327,7 @@ public class ByteVector { * Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if * necessary. * - * @param byteArrayValue an array of bytes. May be null to put byteLength null + * @param byteArrayValue an array of bytes. May be {@literal null} to put {@code byteLength} null * bytes into this byte vector. * @param byteOffset index of the first byte of byteArrayValue that must be copied. * @param byteLength number of bytes of byteArrayValue that must be copied. diff --git a/spring-core/src/main/java/org/springframework/asm/ClassReader.java b/spring-core/src/main/java/org/springframework/asm/ClassReader.java index 99c7f4ab1c..e6fa8d2619 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassReader.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassReader.java @@ -187,6 +187,7 @@ public class ClassReader { int currentCpInfoIndex = 1; int currentCpInfoOffset = classFileOffset + 10; int currentMaxStringLength = 0; + boolean hasBootstrapMethods = false; // The offset of the other entries depend on the total size of all the previous entries. while (currentCpInfoIndex < constantPoolCount) { cpInfoOffsets[currentCpInfoIndex++] = currentCpInfoOffset + 1; @@ -198,9 +199,12 @@ public class ClassReader { case Symbol.CONSTANT_INTEGER_TAG: case Symbol.CONSTANT_FLOAT_TAG: case Symbol.CONSTANT_NAME_AND_TYPE_TAG: + cpInfoSize = 5; + break; case Symbol.CONSTANT_INVOKE_DYNAMIC_TAG: case Symbol.CONSTANT_DYNAMIC_TAG: cpInfoSize = 5; + hasBootstrapMethods = true; break; case Symbol.CONSTANT_LONG_TAG: case Symbol.CONSTANT_DOUBLE_TAG: @@ -236,29 +240,8 @@ public class ClassReader { this.header = currentCpInfoOffset; // Read the BootstrapMethods attribute, if any (only get the offset of each method). - int currentAttributeOffset = getFirstAttributeOffset(); - int[] currentBootstrapMethodOffsets = null; - for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) { - // Read the attribute_info's attribute_name and attribute_length fields. - String attributeName = readUTF8(currentAttributeOffset, new char[maxStringLength]); - int attributeLength = readInt(currentAttributeOffset + 2); - currentAttributeOffset += 6; - if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) { - // Read the num_bootstrap_methods field and create an array of this size. - currentBootstrapMethodOffsets = new int[readUnsignedShort(currentAttributeOffset)]; - // Compute and store the offset of each 'bootstrap_methods' array field entry. - int currentBootstrapMethodOffset = currentAttributeOffset + 2; - for (int j = 0; j < currentBootstrapMethodOffsets.length; ++j) { - currentBootstrapMethodOffsets[j] = currentBootstrapMethodOffset; - // Skip the bootstrap_method_ref and num_bootstrap_arguments fields (2 bytes each), - // as well as the bootstrap_arguments array field (of size num_bootstrap_arguments * 2). - currentBootstrapMethodOffset += - 4 + readUnsignedShort(currentBootstrapMethodOffset + 2) * 2; - } - } - currentAttributeOffset += attributeLength; - } - this.bootstrapMethodOffsets = currentBootstrapMethodOffsets; + this.bootstrapMethodOffsets = + hasBootstrapMethods ? readBootstrapMethodsAttribute(currentMaxStringLength) : null; } /** @@ -345,7 +328,7 @@ public class ClassReader { * Returns the internal of name of the super class (see {@link Type#getInternalName()}). For * interfaces, the super class is {@link Object}. * - * @return the internal name of the super class, or null for {@link Object} class. + * @return the internal name of the super class, or {@literal null} for {@link Object} class. * @see ClassVisitor#visit(int, int, String, String, String, String[]) */ public String getSuperName() { @@ -538,7 +521,7 @@ public class ClassReader { // Visit the NestHost attribute. if (nestHostClass != null) { - classVisitor.visitNestHostExperimental(nestHostClass); + classVisitor.visitNestHost(nestHostClass); } // Visit the EnclosingMethod attribute. @@ -648,7 +631,7 @@ public class ClassReader { int numberOfNestMembers = readUnsignedShort(nestMembersOffset); int currentNestMemberOffset = nestMembersOffset + 2; while (numberOfNestMembers-- > 0) { - classVisitor.visitNestMemberExperimental(readClass(currentNestMemberOffset, charBuffer)); + classVisitor.visitNestMember(readClass(currentNestMemberOffset, charBuffer)); currentNestMemberOffset += 2; } } @@ -2775,7 +2758,7 @@ public class ClassReader { * @param annotationVisitor the visitor that must visit the element_value structure. * @param elementValueOffset the start offset in {@link #b} of the element_value structure to be * read. - * @param elementName the name of the element_value structure to be read, or null. + * @param elementName the name of the element_value structure to be read, or {@literal null}. * @param charBuffer the buffer used to read strings in the constant pool. * @return the end offset of the JVMS 'element_value' structure. */ @@ -3222,6 +3205,41 @@ public class ClassReader { return currentOffset + 2; } + /** + * Reads the BootstrapMethods attribute to compute the offset of each bootstrap method. + * + * @param maxStringLength a conservative estimate of the maximum length of the strings contained + * in the constant pool of the class. + * @return the offsets of the bootstrap methods or null. + */ + private int[] readBootstrapMethodsAttribute(final int maxStringLength) { + char[] charBuffer = new char[maxStringLength]; + int currentAttributeOffset = getFirstAttributeOffset(); + int[] currentBootstrapMethodOffsets = null; + for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) { + // Read the attribute_info's attribute_name and attribute_length fields. + String attributeName = readUTF8(currentAttributeOffset, charBuffer); + int attributeLength = readInt(currentAttributeOffset + 2); + currentAttributeOffset += 6; + if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) { + // Read the num_bootstrap_methods field and create an array of this size. + currentBootstrapMethodOffsets = new int[readUnsignedShort(currentAttributeOffset)]; + // Compute and store the offset of each 'bootstrap_methods' array field entry. + int currentBootstrapMethodOffset = currentAttributeOffset + 2; + for (int j = 0; j < currentBootstrapMethodOffsets.length; ++j) { + currentBootstrapMethodOffsets[j] = currentBootstrapMethodOffset; + // Skip the bootstrap_method_ref and num_bootstrap_arguments fields (2 bytes each), + // as well as the bootstrap_arguments array field (of size num_bootstrap_arguments * 2). + currentBootstrapMethodOffset += + 4 + readUnsignedShort(currentBootstrapMethodOffset + 2) * 2; + } + return currentBootstrapMethodOffsets; + } + currentAttributeOffset += attributeLength; + } + return null; + } + /** * Reads a non standard JVMS 'attribute' structure in {@link #b}. * @@ -3236,8 +3254,8 @@ public class ClassReader { * @param codeAttributeOffset the start offset of the enclosing Code attribute in {@link #b}, or * -1 if the attribute to be read is not a code attribute. The 6 attribute header bytes * (attribute_name_index and attribute_length) are not taken into account here. - * @param labels the labels of the method's code, or null if the attribute to be read is - * not a code attribute. + * @param labels the labels of the method's code, or {@literal null} if the attribute to be read + * is not a code attribute. * @return the attribute that has been read. */ private Attribute readAttribute( diff --git a/spring-core/src/main/java/org/springframework/asm/ClassTooLargeException.java b/spring-core/src/main/java/org/springframework/asm/ClassTooLargeException.java new file mode 100644 index 0000000000..a5aea999cf --- /dev/null +++ b/spring-core/src/main/java/org/springframework/asm/ClassTooLargeException.java @@ -0,0 +1,63 @@ +// ASM: a very small and fast Java bytecode manipulation framework +// Copyright (c) 2000-2011 INRIA, France Telecom +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +// THE POSSIBILITY OF SUCH DAMAGE. +package org.springframework.asm; + +/** + * Exception thrown when the constant pool of a class produced by a {@link ClassWriter} is too + * large. + * + * @author Jason Zaugg + */ +@SuppressWarnings("serial") +public final class ClassTooLargeException extends IndexOutOfBoundsException { + + private final String className; + private final int constantPoolCount; + + /** + * Constructs a new {@link ClassTooLargeException}. + * + * @param className the internal name of the class. + * @param constantPoolCount the number of constant pool items of the class. + */ + public ClassTooLargeException(final String className, final int constantPoolCount) { + super("Class too large: " + className); + this.className = className; + this.constantPoolCount = constantPoolCount; + } + + /** @return the internal name of the class. */ + public String getClassName() { + return className; + } + + /** @return the number of constant pool items of the class. */ + public int getConstantPoolCount() { + return constantPoolCount; + } +} diff --git a/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java b/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java index 51daa6f329..4fafa67edc 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java @@ -29,10 +29,10 @@ package org.springframework.asm; /** * A visitor to visit a Java class. The methods of this class must be called in the following order: - * visit [ visitSource ] [ visitModule ][ visitNestHost ][ - * visitOuterClass ] ( visitAnnotation | visitTypeAnnotation | - * visitAttribute )* ( visitNestMember | visitInnerClass | - * visitField | visitMethod )* visitEnd. + * {@code visit} [ {@code visitSource} ] [ {@code visitModule} ][ {@code visitNestHost} ][ {@code + * visitOuterClass} ] ( {@code visitAnnotation} | {@code visitTypeAnnotation} | {@code + * visitAttribute} )* ( {@code visitNestMember} | {@code visitInnerClass} | {@code visitField} | + * {@code visitMethod} )* {@code visitEnd}. * * @author Eric Bruneton */ @@ -40,7 +40,7 @@ public abstract class ClassVisitor { /** * The ASM API version implemented by this visitor. The value of this field must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. */ protected final int api; @@ -51,8 +51,7 @@ public abstract class ClassVisitor { * Constructs a new {@link ClassVisitor}. * * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link - * Opcodes#ASM7_EXPERIMENTAL}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. */ public ClassVisitor(final int api) { this(api, null); @@ -62,16 +61,12 @@ public abstract class ClassVisitor { * Constructs a new {@link ClassVisitor}. * * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link - * Opcodes#ASM7_EXPERIMENTAL}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. * @param classVisitor the class visitor to which this visitor must delegate method calls. May be * null. */ public ClassVisitor(final int api, final ClassVisitor classVisitor) { - if (api != Opcodes.ASM6 - && api != Opcodes.ASM5 - && api != Opcodes.ASM4 - && api != Opcodes.ASM7_EXPERIMENTAL) { + if (api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 && api != Opcodes.ASM7) { throw new IllegalArgumentException(); } this.api = api; @@ -86,13 +81,13 @@ public abstract class ClassVisitor { * @param access the class's access flags (see {@link Opcodes}). This parameter also indicates if * the class is deprecated. * @param name the internal name of the class (see {@link Type#getInternalName()}). - * @param signature the signature of this class. May be null if the class is not a + * @param signature the signature of this class. May be {@literal null} if the class is not a * generic one, and does not extend or implement generic classes or interfaces. * @param superName the internal of name of the super class (see {@link Type#getInternalName()}). - * For interfaces, the super class is {@link Object}. May be null, but only for the + * For interfaces, the super class is {@link Object}. May be {@literal null}, but only for the * {@link Object} class. * @param interfaces the internal names of the class's interfaces (see {@link - * Type#getInternalName()}). May be null. + * Type#getInternalName()}). May be {@literal null}. */ public void visit( final int version, @@ -109,10 +104,10 @@ public abstract class ClassVisitor { /** * Visits the source of the class. * - * @param source the name of the source file from which the class was compiled. May be - * null. + * @param source the name of the source file from which the class was compiled. May be {@literal + * null}. * @param debug additional debug information to compute the correspondence between source and - * compiled elements of the class. May be null. + * compiled elements of the class. May be {@literal null}. */ public void visitSource(final String source, final String debug) { if (cv != null) { @@ -126,13 +121,13 @@ public abstract class ClassVisitor { * @param name the fully qualified name (using dots) of the module. * @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code * ACC_MANDATED}. - * @param version the module version, or null. - * @return a visitor to visit the module values, or null if this visitor is not + * @param version the module version, or {@literal null}. + * @return a visitor to visit the module values, or {@literal null} if this visitor is not * interested in visiting this module. */ public ModuleVisitor visitModule(final String name, final int access, final String version) { if (api < Opcodes.ASM6) { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("This feature requires ASM6"); } if (cv != null) { return cv.visitModule(name, access, version); @@ -141,22 +136,21 @@ public abstract class ClassVisitor { } /** - * Experimental, use at your own risk. This method will be renamed when it becomes stable, this - * will break existing code using it. Visits the nest host class of the class. A nest is a set - * of classes of the same package that share access to their private members. One of these - * classes, called the host, lists the other members of the nest, which in turn should link to the - * host of their nest. This method must be called only once and only if the visited class is a - * non-host member of a nest. A class is implicitly its own nest, so it's invalid to call this - * method with the visited class name as argument. + * Visits the nest host class of the class. A nest is a set of classes of the same package that + * share access to their private members. One of these classes, called the host, lists the other + * members of the nest, which in turn should link to the host of their nest. This method must be + * called only once and only if the visited class is a non-host member of a nest. A class is + * implicitly its own nest, so it's invalid to call this method with the visited class name as + * argument. * * @param nestHost the internal name of the host class of the nest. */ - public void visitNestHostExperimental(final String nestHost) { - if (api < Opcodes.ASM7_EXPERIMENTAL) { - throw new UnsupportedOperationException(); + public void visitNestHost(final String nestHost) { + if (api < Opcodes.ASM7) { + throw new UnsupportedOperationException("This feature requires ASM7"); } if (cv != null) { - cv.visitNestHostExperimental(nestHost); + cv.visitNestHost(nestHost); } } @@ -165,10 +159,10 @@ public abstract class ClassVisitor { * enclosing class. * * @param owner internal name of the enclosing class of the class. - * @param name the name of the method that contains the class, or null if the class is + * @param name the name of the method that contains the class, or {@literal null} if the class is * not enclosed in a method of its enclosing class. - * @param descriptor the descriptor of the method that contains the class, or null if the - * class is not enclosed in a method of its enclosing class. + * @param descriptor the descriptor of the method that contains the class, or {@literal null} if + * the class is not enclosed in a method of its enclosing class. */ public void visitOuterClass(final String owner, final String name, final String descriptor) { if (cv != null) { @@ -180,8 +174,8 @@ public abstract class ClassVisitor { * Visits an annotation of the class. * * @param descriptor the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if this visitor is not + * @param visible {@literal true} if the annotation is visible at runtime. + * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not * interested in visiting this annotation. */ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { @@ -199,17 +193,17 @@ public abstract class ClassVisitor { * TypeReference#CLASS_TYPE_PARAMETER_BOUND} or {@link TypeReference#CLASS_EXTENDS}. See * {@link TypeReference}. * @param typePath the path to the annotated type argument, wildcard bound, array element type, or - * static inner type within 'typeRef'. May be null if the annotation targets + * static inner type within 'typeRef'. May be {@literal null} if the annotation targets * 'typeRef' as a whole. * @param descriptor the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if this visitor is not + * @param visible {@literal true} if the annotation is visible at runtime. + * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not * interested in visiting this annotation. */ public AnnotationVisitor visitTypeAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { if (api < Opcodes.ASM5) { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("This feature requires ASM5"); } if (cv != null) { return cv.visitTypeAnnotation(typeRef, typePath, descriptor, visible); @@ -229,22 +223,20 @@ public abstract class ClassVisitor { } /** - * Experimental, use at your own risk. This method will be renamed when it becomes stable, this - * will break existing code using it. Visits a member of the nest. A nest is a set of classes - * of the same package that share access to their private members. One of these classes, called - * the host, lists the other members of the nest, which in turn should link to the host of their - * nest. This method must be called only if the visited class is the host of a nest. A nest host - * is implicitly a member of its own nest, so it's invalid to call this method with the visited - * class name as argument. + * Visits a member of the nest. A nest is a set of classes of the same package that share access + * to their private members. One of these classes, called the host, lists the other members of the + * nest, which in turn should link to the host of their nest. This method must be called only if + * the visited class is the host of a nest. A nest host is implicitly a member of its own nest, so + * it's invalid to call this method with the visited class name as argument. * * @param nestMember the internal name of a nest member. */ - public void visitNestMemberExperimental(final String nestMember) { - if (api < Opcodes.ASM7_EXPERIMENTAL) { - throw new UnsupportedOperationException(); + public void visitNestMember(final String nestMember) { + if (api < Opcodes.ASM7) { + throw new UnsupportedOperationException("This feature requires ASM7"); } if (cv != null) { - cv.visitNestMemberExperimental(nestMember); + cv.visitNestMember(nestMember); } } @@ -254,9 +246,9 @@ public abstract class ClassVisitor { * * @param name the internal name of an inner class (see {@link Type#getInternalName()}). * @param outerName the internal name of the class to which the inner class belongs (see {@link - * Type#getInternalName()}). May be null for not member classes. + * Type#getInternalName()}). May be {@literal null} for not member classes. * @param innerName the (simple) name of the inner class inside its enclosing class. May be - * null for anonymous inner classes. + * {@literal null} for anonymous inner classes. * @param access the access flags of the inner class as originally declared in the enclosing * class. */ @@ -274,15 +266,15 @@ public abstract class ClassVisitor { * the field is synthetic and/or deprecated. * @param name the field's name. * @param descriptor the field's descriptor (see {@link Type}). - * @param signature the field's signature. May be null if the field's type does not use + * @param signature the field's signature. May be {@literal null} if the field's type does not use * generic types. - * @param value the field's initial value. This parameter, which may be null if the field - * does not have an initial value, must be an {@link Integer}, a {@link Float}, a {@link - * Long}, a {@link Double} or a {@link String} (for int, float, - * long or String fields respectively). This parameter is only used for - * static fields. Its value is ignored for non static fields, which must be initialized - * through bytecode instructions in constructors or methods. - * @return a visitor to visit field annotations and attributes, or null if this class + * @param value the field's initial value. This parameter, which may be {@literal null} if the + * field does not have an initial value, must be an {@link Integer}, a {@link Float}, a {@link + * Long}, a {@link Double} or a {@link String} (for {@code int}, {@code float}, {@code long} + * or {@code String} fields respectively). This parameter is only used for static + * fields. Its value is ignored for non static fields, which must be initialized through + * bytecode instructions in constructors or methods. + * @return a visitor to visit field annotations and attributes, or {@literal null} if this class * visitor is not interested in visiting these annotations and attributes. */ public FieldVisitor visitField( @@ -299,19 +291,19 @@ public abstract class ClassVisitor { /** * Visits a method of the class. This method must return a new {@link MethodVisitor} - * instance (or null) each time it is called, i.e., it should not return a previously + * instance (or {@literal null}) each time it is called, i.e., it should not return a previously * returned visitor. * * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if * the method is synthetic and/or deprecated. * @param name the method's name. * @param descriptor the method's descriptor (see {@link Type}). - * @param signature the method's signature. May be null if the method parameters, return - * type and exceptions do not use generic types. + * @param signature the method's signature. May be {@literal null} if the method parameters, + * return type and exceptions do not use generic types. * @param exceptions the internal names of the method's exception classes (see {@link - * Type#getInternalName()}). May be null. - * @return an object to visit the byte code of the method, or null if this class visitor - * is not interested in visiting the code of this method. + * Type#getInternalName()}). May be {@literal null}. + * @return an object to visit the byte code of the method, or {@literal null} if this class + * visitor is not interested in visiting the code of this method. */ public MethodVisitor visitMethod( final int access, diff --git a/spring-core/src/main/java/org/springframework/asm/ClassWriter.java b/spring-core/src/main/java/org/springframework/asm/ClassWriter.java index ef76e1ef8e..4954f4f6f2 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassWriter.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassWriter.java @@ -123,7 +123,7 @@ public class ClassWriter extends ClassVisitor { /** The number_of_classes field of the InnerClasses attribute, or 0. */ private int numberOfInnerClasses; - /** The 'classes' array of the InnerClasses attribute, or null. */ + /** The 'classes' array of the InnerClasses attribute, or {@literal null}. */ private ByteVector innerClasses; /** The class_index field of the EnclosingMethod attribute, or 0. */ @@ -138,34 +138,34 @@ public class ClassWriter extends ClassVisitor { /** The source_file_index field of the SourceFile attribute, or 0. */ private int sourceFileIndex; - /** The debug_extension field of the SourceDebugExtension attribute, or null. */ + /** The debug_extension field of the SourceDebugExtension attribute, or {@literal null}. */ private ByteVector debugExtension; /** * The last runtime visible annotation of this class. The previous ones can be accessed with the - * {@link AnnotationWriter#previousAnnotation} field. May be null. + * {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastRuntimeVisibleAnnotation; /** * The last runtime invisible annotation of this class. The previous ones can be accessed with the - * {@link AnnotationWriter#previousAnnotation} field. May be null. + * {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastRuntimeInvisibleAnnotation; /** * The last runtime visible type annotation of this class. The previous ones can be accessed with - * the {@link AnnotationWriter#previousAnnotation} field. May be null. + * the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastRuntimeVisibleTypeAnnotation; /** * The last runtime invisible type annotation of this class. The previous ones can be accessed - * with the {@link AnnotationWriter#previousAnnotation} field. May be null. + * with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastRuntimeInvisibleTypeAnnotation; - /** The Module attribute of this class, or null. */ + /** The Module attribute of this class, or {@literal null}. */ private ModuleWriter moduleWriter; /** The host_class_index field of the NestHost attribute, or 0. */ @@ -174,12 +174,12 @@ public class ClassWriter extends ClassVisitor { /** The number_of_classes field of the NestMembers attribute, or 0. */ private int numberOfNestMemberClasses; - /** The 'classes' array of the NestMembers attribute, or null. */ + /** The 'classes' array of the NestMembers attribute, or {@literal null}. */ private ByteVector nestMemberClasses; /** * The first non standard attribute of this class. The next ones can be accessed with the {@link - * Attribute#nextAttribute} field. May be null. + * Attribute#nextAttribute} field. May be {@literal null}. * *
WARNING: this list stores the attributes in the reverse order of their visit. * firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link @@ -234,7 +234,7 @@ public class ClassWriter extends ClassVisitor { * maximum stack size nor the stack frames will be computed for these methods. */ public ClassWriter(final ClassReader classReader, final int flags) { - super(Opcodes.ASM6); + super(Opcodes.ASM7); symbolTable = classReader == null ? new SymbolTable(this) : new SymbolTable(this, classReader); if ((flags & COMPUTE_FRAMES) != 0) { this.compute = MethodWriter.COMPUTE_ALL_FRAMES; @@ -298,7 +298,7 @@ public class ClassWriter extends ClassVisitor { } @Override - public void visitNestHostExperimental(final String nestHost) { + public void visitNestHost(final String nestHost) { nestHostClassIndex = symbolTable.addConstantClass(nestHost).index; } @@ -355,7 +355,7 @@ public class ClassWriter extends ClassVisitor { } @Override - public void visitNestMemberExperimental(final String nestMember) { + public void visitNestMember(final String nestMember) { if (nestMemberClasses == null) { nestMemberClasses = new ByteVector(); } @@ -436,8 +436,10 @@ public class ClassWriter extends ClassVisitor { * Returns the content of the class file that was built by this ClassWriter. * * @return the binary content of the JVMS ClassFile structure that was built by this ClassWriter. + * @throws ClassTooLargeException if the constant pool of the class is too large. + * @throws MethodTooLargeException if the Code attribute of a method is too large. */ - public byte[] toByteArray() { + public byte[] toByteArray() throws ClassTooLargeException, MethodTooLargeException { // First step: compute the size in bytes of the ClassFile structure. // The magic field uses 4 bytes, 10 mandatory fields (minor_version, major_version, // constant_pool_count, access_flags, this_class, super_class, interfaces_count, fields_count, @@ -543,8 +545,9 @@ public class ClassWriter extends ClassVisitor { // IMPORTANT: this must be the last part of the ClassFile size computation, because the previous // statements can add attribute names to the constant pool, thereby changing its size! size += symbolTable.getConstantPoolLength(); - if (symbolTable.getConstantPoolCount() > 0xFFFF) { - throw new IndexOutOfBoundsException("Class file too large!"); + int constantPoolCount = symbolTable.getConstantPoolCount(); + if (constantPoolCount > 0xFFFF) { + throw new ClassTooLargeException(symbolTable.getClassName(), constantPoolCount); } // Second step: allocate a ByteVector of the correct size (in order to avoid any array copy in @@ -902,7 +905,7 @@ public class ClassWriter extends ClassVisitor { * @param owner the internal name of the method's owner class. * @param name the method's name. * @param descriptor the method's descriptor. - * @param isInterface true if owner is an interface. + * @param isInterface {@literal true} if {@code owner} is an interface. * @return the index of a new or already existing method reference item. */ public int newMethod( diff --git a/spring-core/src/main/java/org/springframework/asm/ConstantDynamic.java b/spring-core/src/main/java/org/springframework/asm/ConstantDynamic.java index 2d9e7e85e0..bb5a65563f 100644 --- a/spring-core/src/main/java/org/springframework/asm/ConstantDynamic.java +++ b/spring-core/src/main/java/org/springframework/asm/ConstantDynamic.java @@ -109,6 +109,16 @@ public final class ConstantDynamic { return bootstrapMethodArguments; } + /** + * Returns the size of this constant. + * + * @return the size of this constant, i.e., 2 for {@code long} and {@code double}, 1 otherwise. + */ + public int getSize() { + char firstCharOfDescriptor = descriptor.charAt(0); + return (firstCharOfDescriptor == 'J' || firstCharOfDescriptor == 'D') ? 2 : 1; + } + @Override public boolean equals(final Object object) { if (object == this) { diff --git a/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java b/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java index 1478646fde..390178a89a 100644 --- a/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java @@ -29,8 +29,8 @@ package org.springframework.asm; /** * A visitor to visit a Java field. The methods of this class must be called in the following order: - * ( visitAnnotation | visitTypeAnnotation | visitAttribute )* - * visitEnd. + * ( {@code visitAnnotation} | {@code visitTypeAnnotation} | {@code visitAttribute} )* {@code + * visitEnd}. * * @author Eric Bruneton */ @@ -38,7 +38,7 @@ public abstract class FieldVisitor { /** * The ASM API version implemented by this visitor. The value of this field must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. */ protected final int api; @@ -49,8 +49,7 @@ public abstract class FieldVisitor { * Constructs a new {@link FieldVisitor}. * * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link - * Opcodes#ASM7_EXPERIMENTAL}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. */ public FieldVisitor(final int api) { this(api, null); @@ -60,16 +59,12 @@ public abstract class FieldVisitor { * Constructs a new {@link FieldVisitor}. * * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link - * Opcodes#ASM7_EXPERIMENTAL}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. * @param fieldVisitor the field visitor to which this visitor must delegate method calls. May be * null. */ public FieldVisitor(final int api, final FieldVisitor fieldVisitor) { - if (api != Opcodes.ASM6 - && api != Opcodes.ASM5 - && api != Opcodes.ASM4 - && api != Opcodes.ASM7_EXPERIMENTAL) { + if (api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 && api != Opcodes.ASM7) { throw new IllegalArgumentException(); } this.api = api; @@ -80,8 +75,8 @@ public abstract class FieldVisitor { * Visits an annotation of the field. * * @param descriptor the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if this visitor is not + * @param visible {@literal true} if the annotation is visible at runtime. + * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not * interested in visiting this annotation. */ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { @@ -97,17 +92,17 @@ public abstract class FieldVisitor { * @param typeRef a reference to the annotated type. The sort of this type reference must be * {@link TypeReference#FIELD}. See {@link TypeReference}. * @param typePath the path to the annotated type argument, wildcard bound, array element type, or - * static inner type within 'typeRef'. May be null if the annotation targets + * static inner type within 'typeRef'. May be {@literal null} if the annotation targets * 'typeRef' as a whole. * @param descriptor the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if this visitor is not + * @param visible {@literal true} if the annotation is visible at runtime. + * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not * interested in visiting this annotation. */ public AnnotationVisitor visitTypeAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { if (api < Opcodes.ASM5) { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("This feature requires ASM5"); } if (fv != null) { return fv.visitTypeAnnotation(typeRef, typePath, descriptor, visible); diff --git a/spring-core/src/main/java/org/springframework/asm/FieldWriter.java b/spring-core/src/main/java/org/springframework/asm/FieldWriter.java index 491ee0e03c..c09398f9f9 100644 --- a/spring-core/src/main/java/org/springframework/asm/FieldWriter.java +++ b/spring-core/src/main/java/org/springframework/asm/FieldWriter.java @@ -70,31 +70,31 @@ final class FieldWriter extends FieldVisitor { /** * The last runtime visible annotation of this field. The previous ones can be accessed with the - * {@link AnnotationWriter#previousAnnotation} field. May be null. + * {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastRuntimeVisibleAnnotation; /** * The last runtime invisible annotation of this field. The previous ones can be accessed with the - * {@link AnnotationWriter#previousAnnotation} field. May be null. + * {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastRuntimeInvisibleAnnotation; /** * The last runtime visible type annotation of this field. The previous ones can be accessed with - * the {@link AnnotationWriter#previousAnnotation} field. May be null. + * the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastRuntimeVisibleTypeAnnotation; /** * The last runtime invisible type annotation of this field. The previous ones can be accessed - * with the {@link AnnotationWriter#previousAnnotation} field. May be null. + * with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastRuntimeInvisibleTypeAnnotation; /** * The first non standard attribute of this field. The next ones can be accessed with the {@link - * Attribute#nextAttribute} field. May be null. + * Attribute#nextAttribute} field. May be {@literal null}. * *
WARNING: this list stores the attributes in the reverse order of their visit. * firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link @@ -114,8 +114,8 @@ final class FieldWriter extends FieldVisitor { * @param access the field's access flags (see {@link Opcodes}). * @param name the field's name. * @param descriptor the field's descriptor (see {@link Type}). - * @param signature the field's signature. May be null. - * @param constantValue the field's constant value. May be null. + * @param signature the field's signature. May be {@literal null}. + * @param constantValue the field's constant value. May be {@literal null}. */ FieldWriter( final SymbolTable symbolTable, @@ -124,7 +124,7 @@ final class FieldWriter extends FieldVisitor { final String descriptor, final String signature, final Object constantValue) { - super(Opcodes.ASM6); + super(Opcodes.ASM7); this.symbolTable = symbolTable; this.accessFlags = access; this.nameIndex = symbolTable.addConstantUtf8(name); diff --git a/spring-core/src/main/java/org/springframework/asm/Frame.java b/spring-core/src/main/java/org/springframework/asm/Frame.java index b1b1f04db5..939e229893 100644 --- a/spring-core/src/main/java/org/springframework/asm/Frame.java +++ b/spring-core/src/main/java/org/springframework/asm/Frame.java @@ -1105,15 +1105,15 @@ class Frame { /** * Merges the input frame of the given {@link Frame} with the input and output frames of this - * {@link Frame}. Returns true if the given frame has been changed by this operation (the - * input and output frames of this {@link Frame} are never changed). + * {@link Frame}. Returns {@literal true} if the given frame has been changed by this operation + * (the input and output frames of this {@link Frame} are never changed). * * @param symbolTable the type table to use to lookup and store type {@link Symbol}. * @param dstFrame the {@link Frame} whose input frame must be updated. This should be the frame * of a successor, in the control flow graph, of the basic block corresponding to this frame. * @param catchTypeIndex if 'frame' corresponds to an exception handler basic block, the type * table index of the caught exception type, otherwise 0. - * @return true if the input frame of 'frame' has been changed by this operation. + * @return {@literal true} if the input frame of 'frame' has been changed by this operation. */ final boolean merge( final SymbolTable symbolTable, final Frame dstFrame, final int catchTypeIndex) { @@ -1242,7 +1242,7 @@ class Frame { /** * Merges the type at the given index in the given abstract type array with the given type. - * Returns true if the type array has been modified by this operation. + * Returns {@literal true} if the type array has been modified by this operation. * * @param symbolTable the type table to use to lookup and store type {@link Symbol}. * @param sourceType the abstract type with which the abstract type array element must be merged. @@ -1252,7 +1252,7 @@ class Frame { * {@link #REFERENCE_KIND} or {@link #UNINITIALIZED_KIND} kind, with positive or null array * dimensions. * @param dstIndex the index of the type that must be merged in dstTypes. - * @return true if the type array has been modified by this operation. + * @return {@literal true} if the type array has been modified by this operation. */ private static boolean merge( final SymbolTable symbolTable, diff --git a/spring-core/src/main/java/org/springframework/asm/Handler.java b/spring-core/src/main/java/org/springframework/asm/Handler.java index 514a9e3d8e..5b7f6bcb74 100644 --- a/spring-core/src/main/java/org/springframework/asm/Handler.java +++ b/spring-core/src/main/java/org/springframework/asm/Handler.java @@ -64,8 +64,8 @@ final class Handler { final int catchType; /** - * The internal name of the type of exceptions handled by this handler, or null to catch - * any exceptions. + * The internal name of the type of exceptions handled by this handler, or {@literal null} to + * catch any exceptions. */ final String catchTypeDescriptor; @@ -80,7 +80,7 @@ final class Handler { * @param handlerPc the handler_pc field of this JVMS exception_table entry. * @param catchType The catch_type field of this JVMS exception_table entry. * @param catchTypeDescriptor The internal name of the type of exceptions handled by this handler, - * or null to catch any exceptions. + * or {@literal null} to catch any exceptions. */ Handler( final Label startPc, @@ -111,9 +111,9 @@ final class Handler { * Removes the range between start and end from the Handler list that begins with the given * element. * - * @param firstHandler the beginning of a Handler list. May be null. + * @param firstHandler the beginning of a Handler list. May be {@literal null}. * @param start the start of the range to be removed. - * @param end the end of the range to be removed. Maybe null. + * @param end the end of the range to be removed. Maybe {@literal null}. * @return the exception handler list with the start-end range removed. */ static Handler removeRange(final Handler firstHandler, final Label start, final Label end) { @@ -152,7 +152,7 @@ final class Handler { /** * Returns the number of elements of the Handler list that begins with the given element. * - * @param firstHandler the beginning of a Handler list. May be null. + * @param firstHandler the beginning of a Handler list. May be {@literal null}. * @return the number of elements of the Handler list that begins with 'handler'. */ static int getExceptionTableLength(final Handler firstHandler) { @@ -169,7 +169,7 @@ final class Handler { * Returns the size in bytes of the JVMS exception_table corresponding to the Handler list that * begins with the given element. This includes the exception_table_length field. * - * @param firstHandler the beginning of a Handler list. May be null. + * @param firstHandler the beginning of a Handler list. May be {@literal null}. * @return the size in bytes of the exception_table_length and exception_table structures. */ static int getExceptionTableSize(final Handler firstHandler) { @@ -180,7 +180,7 @@ final class Handler { * Puts the JVMS exception_table corresponding to the Handler list that begins with the given * element. This includes the exception_table_length field. * - * @param firstHandler the beginning of a Handler list. May be null. + * @param firstHandler the beginning of a Handler list. May be {@literal null}. * @param output where the exception_table_length and exception_table structures must be put. */ static void putExceptionTable(final Handler firstHandler, final ByteVector output) { diff --git a/spring-core/src/main/java/org/springframework/asm/Label.java b/spring-core/src/main/java/org/springframework/asm/Label.java index 4e065cb27c..e34288bf84 100644 --- a/spring-core/src/main/java/org/springframework/asm/Label.java +++ b/spring-core/src/main/java/org/springframework/asm/Label.java @@ -435,7 +435,7 @@ public class Label { * * @param code the bytecode of the method. * @param bytecodeOffset the bytecode offset of this label. - * @return true if a blank that was left for this label was too small to store the + * @return {@literal true} if a blank that was left for this label was too small to store the * offset. In such a case the corresponding jump instruction is replaced with an equivalent * ASM specific instruction using an unsigned two bytes offset. These ASM specific * instructions are later replaced with standard bytecode instructions with wider offsets (4 diff --git a/spring-core/src/main/java/org/springframework/asm/MethodTooLargeException.java b/spring-core/src/main/java/org/springframework/asm/MethodTooLargeException.java new file mode 100644 index 0000000000..1f4164174f --- /dev/null +++ b/spring-core/src/main/java/org/springframework/asm/MethodTooLargeException.java @@ -0,0 +1,83 @@ +// ASM: a very small and fast Java bytecode manipulation framework +// Copyright (c) 2000-2011 INRIA, France Telecom +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +// THE POSSIBILITY OF SUCH DAMAGE. +package org.springframework.asm; + +/** + * Exception thrown when the Code attribute of a method produced by a {@link ClassWriter} is too + * large. + * + * @author Jason Zaugg + */ +@SuppressWarnings("serial") +public final class MethodTooLargeException extends IndexOutOfBoundsException { + + private final String className; + private final String methodName; + private final String descriptor; + private final int codeSize; + + /** + * Constructs a new {@link MethodTooLargeException}. + * + * @param className the internal name of the owner class. + * @param methodName the name of the method. + * @param descriptor the descriptor of the method. + * @param codeSize the size of the method's Code attribute, in bytes. + */ + public MethodTooLargeException( + final String className, + final String methodName, + final String descriptor, + final int codeSize) { + super("Method too large: " + className + "." + methodName + " " + descriptor); + this.className = className; + this.methodName = methodName; + this.descriptor = descriptor; + this.codeSize = codeSize; + } + + /** @return the internal name of the owner class. */ + public String getClassName() { + return className; + } + + /** @return the name of the method. */ + public String getMethodName() { + return methodName; + } + + /** @return the descriptor of the method. */ + public String getDescriptor() { + return descriptor; + } + + /** @return the size of the method's Code attribute, in bytes. */ + public int getCodeSize() { + return codeSize; + } +} diff --git a/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java b/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java index 024968d94d..2261791165 100644 --- a/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java @@ -29,20 +29,20 @@ package org.springframework.asm; /** * A visitor to visit a Java method. The methods of this class must be called in the following - * order: ( visitParameter )* [ visitAnnotationDefault ] ( - * visitAnnotation | visitAnnotableParameterCount | - * visitParameterAnnotation visitTypeAnnotation | visitAttribute )* [ - * visitCode ( visitFrame | visitXInsn | visitLabel | - * visitInsnAnnotation | visitTryCatchBlock | visitTryCatchAnnotation | - * visitLocalVariable | visitLocalVariableAnnotation | visitLineNumber )* - * visitMaxs ] visitEnd. In addition, the visitXInsn and - * visitLabel methods must be called in the sequential order of the bytecode instructions - * of the visited code, visitInsnAnnotation must be called after the annotated - * instruction, visitTryCatchBlock must be called before the labels passed as - * arguments have been visited, visitTryCatchBlockAnnotation must be called after - * the corresponding try catch block has been visited, and the visitLocalVariable, - * visitLocalVariableAnnotation and visitLineNumber methods must be called - * after the labels passed as arguments have been visited. + * order: ( {@code visitParameter} )* [ {@code visitAnnotationDefault} ] ( {@code visitAnnotation} | + * {@code visitAnnotableParameterCount} | {@code visitParameterAnnotation} {@code + * visitTypeAnnotation} | {@code visitAttribute} )* [ {@code visitCode} ( {@code visitFrame} | + * {@code visitXInsn} | {@code visitLabel} | {@code visitInsnAnnotation} | {@code + * visitTryCatchBlock} | {@code visitTryCatchAnnotation} | {@code visitLocalVariable} | {@code + * visitLocalVariableAnnotation} | {@code visitLineNumber} )* {@code visitMaxs} ] {@code visitEnd}. + * In addition, the {@code visitXInsn} and {@code visitLabel} methods must be called in the + * sequential order of the bytecode instructions of the visited code, {@code visitInsnAnnotation} + * must be called after the annotated instruction, {@code visitTryCatchBlock} must be called + * before the labels passed as arguments have been visited, {@code + * visitTryCatchBlockAnnotation} must be called after the corresponding try catch block has + * been visited, and the {@code visitLocalVariable}, {@code visitLocalVariableAnnotation} and {@code + * visitLineNumber} methods must be called after the labels passed as arguments have been + * visited. * * @author Eric Bruneton */ @@ -52,7 +52,7 @@ public abstract class MethodVisitor { /** * The ASM API version implemented by this visitor. The value of this field must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. */ protected final int api; @@ -63,8 +63,7 @@ public abstract class MethodVisitor { * Constructs a new {@link MethodVisitor}. * * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link - * Opcodes#ASM7_EXPERIMENTAL}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. */ public MethodVisitor(final int api) { this(api, null); @@ -74,16 +73,12 @@ public abstract class MethodVisitor { * Constructs a new {@link MethodVisitor}. * * @param api the ASM API version implemented by this visitor. Must be one of {@link - * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link - * Opcodes#ASM7_EXPERIMENTAL}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. * @param methodVisitor the method visitor to which this visitor must delegate method calls. May * be null. */ public MethodVisitor(final int api, final MethodVisitor methodVisitor) { - if (api != Opcodes.ASM6 - && api != Opcodes.ASM5 - && api != Opcodes.ASM4 - && api != Opcodes.ASM7_EXPERIMENTAL) { + if (api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 && api != Opcodes.ASM7) { throw new IllegalArgumentException(); } this.api = api; @@ -98,8 +93,8 @@ public abstract class MethodVisitor { * Visits a parameter of this method. * * @param name parameter name or null if none is provided. - * @param access the parameter's access flags, only ACC_FINAL, ACC_SYNTHETIC - * or/and ACC_MANDATED are allowed (see {@link Opcodes}). + * @param access the parameter's access flags, only {@code ACC_FINAL}, {@code ACC_SYNTHETIC} + * or/and {@code ACC_MANDATED} are allowed (see {@link Opcodes}). */ public void visitParameter(final String name, final int access) { if (api < Opcodes.ASM5) { @@ -114,9 +109,9 @@ public abstract class MethodVisitor { * Visits the default value of this annotation interface method. * * @return a visitor to the visit the actual default value of this annotation interface method, or - * null if this visitor is not interested in visiting this default value. The 'name' - * parameters passed to the methods of this annotation visitor are ignored. Moreover, exacly - * one visit method must be called on this annotation visitor, followed by visitEnd. + * {@literal null} if this visitor is not interested in visiting this default value. The + * 'name' parameters passed to the methods of this annotation visitor are ignored. Moreover, + * exacly one visit method must be called on this annotation visitor, followed by visitEnd. */ public AnnotationVisitor visitAnnotationDefault() { if (mv != null) { @@ -129,8 +124,8 @@ public abstract class MethodVisitor { * Visits an annotation of this method. * * @param descriptor the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if this visitor is not + * @param visible {@literal true} if the annotation is visible at runtime. + * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not * interested in visiting this annotation. */ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { @@ -149,11 +144,11 @@ public abstract class MethodVisitor { * TypeReference#METHOD_RECEIVER}, {@link TypeReference#METHOD_FORMAL_PARAMETER} or {@link * TypeReference#THROWS}. See {@link TypeReference}. * @param typePath the path to the annotated type argument, wildcard bound, array element type, or - * static inner type within 'typeRef'. May be null if the annotation targets + * static inner type within 'typeRef'. May be {@literal null} if the annotation targets * 'typeRef' as a whole. * @param descriptor the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if this visitor is not + * @param visible {@literal true} if the annotation is visible at runtime. + * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not * interested in visiting this annotation. */ public AnnotationVisitor visitTypeAnnotation( @@ -177,8 +172,8 @@ public abstract class MethodVisitor { * be strictly less when a method has synthetic parameters and when these parameters are * ignored when computing parameter indices for the purpose of parameter annotations (see * https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18). - * @param visible true to define the number of method parameters that can have - * annotations visible at runtime, false to define the number of method parameters + * @param visible {@literal true} to define the number of method parameters that can have + * annotations visible at runtime, {@literal false} to define the number of method parameters * that can have annotations invisible at runtime. */ public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) { @@ -197,8 +192,8 @@ public abstract class MethodVisitor { * descriptor, in particular in case of synthetic parameters (see * https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18). * @param descriptor the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if this visitor is not + * @param visible {@literal true} if the annotation is visible at runtime. + * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not * interested in visiting this annotation. */ public AnnotationVisitor visitParameterAnnotation( @@ -532,7 +527,7 @@ public abstract class MethodVisitor { * * @param value the constant to be loaded on the stack. This parameter must be a non null {@link * Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, a {@link - * Type} of OBJECT or ARRAY sort for .class constants, for classes whose version is + * Type} of OBJECT or ARRAY sort for {@code .class} constants, for classes whose version is * 49, a {@link Type} of METHOD sort for MethodType, a {@link Handle} for MethodHandle * constants, for classes whose version is 51 or a {@link ConstantDynamic} for a constant * dynamic for classes whose version is 55. @@ -543,7 +538,7 @@ public abstract class MethodVisitor { || (value instanceof Type && ((Type) value).getSort() == Type.METHOD))) { throw new UnsupportedOperationException(REQUIRES_ASM5); } - if (api != Opcodes.ASM7_EXPERIMENTAL && value instanceof ConstantDynamic) { + if (api != Opcodes.ASM7 && value instanceof ConstantDynamic) { throw new UnsupportedOperationException("This feature requires ASM7"); } if (mv != null) { @@ -569,8 +564,8 @@ public abstract class MethodVisitor { * @param min the minimum key value. * @param max the maximum key value. * @param dflt beginning of the default handler block. - * @param labels beginnings of the handler blocks. labels[i] is the beginning of the - * handler block for the min + i key. + * @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the + * handler block for the {@code min + i} key. */ public void visitTableSwitchInsn( final int min, final int max, final Label dflt, final Label... labels) { @@ -584,8 +579,8 @@ public abstract class MethodVisitor { * * @param dflt beginning of the default handler block. * @param keys the values of the keys. - * @param labels beginnings of the handler blocks. labels[i] is the beginning of the - * handler block for the keys[i] key. + * @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the + * handler block for the {@code keys[i]} key. */ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { if (mv != null) { @@ -617,11 +612,11 @@ public abstract class MethodVisitor { * TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link * TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}. * @param typePath the path to the annotated type argument, wildcard bound, array element type, or - * static inner type within 'typeRef'. May be null if the annotation targets + * static inner type within 'typeRef'. May be {@literal null} if the annotation targets * 'typeRef' as a whole. * @param descriptor the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if this visitor is not + * @param visible {@literal true} if the annotation is visible at runtime. + * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not * interested in visiting this annotation. */ public AnnotationVisitor visitInsnAnnotation( @@ -645,8 +640,8 @@ public abstract class MethodVisitor { * @param start the beginning of the exception handler's scope (inclusive). * @param end the end of the exception handler's scope (exclusive). * @param handler the beginning of the exception handler's code. - * @param type the internal name of the type of exceptions handled by the handler, or - * null to catch any exceptions (for "finally" blocks). + * @param type the internal name of the type of exceptions handled by the handler, or {@literal + * null} to catch any exceptions (for "finally" blocks). * @throws IllegalArgumentException if one of the labels has already been visited by this visitor * (by the {@link #visitLabel} method). */ @@ -665,11 +660,11 @@ public abstract class MethodVisitor { * @param typeRef a reference to the annotated type. The sort of this type reference must be * {@link TypeReference#EXCEPTION_PARAMETER}. See {@link TypeReference}. * @param typePath the path to the annotated type argument, wildcard bound, array element type, or - * static inner type within 'typeRef'. May be null if the annotation targets + * static inner type within 'typeRef'. May be {@literal null} if the annotation targets * 'typeRef' as a whole. * @param descriptor the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if this visitor is not + * @param visible {@literal true} if the annotation is visible at runtime. + * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not * interested in visiting this annotation. */ public AnnotationVisitor visitTryCatchAnnotation( @@ -688,7 +683,7 @@ public abstract class MethodVisitor { * * @param name the name of a local variable. * @param descriptor the type descriptor of this local variable. - * @param signature the type signature of this local variable. May be null if the local + * @param signature the type signature of this local variable. May be {@literal null} if the local * variable type does not use generic types. * @param start the first instruction corresponding to the scope of this local variable * (inclusive). @@ -716,7 +711,7 @@ public abstract class MethodVisitor { * {@link TypeReference#LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE}. See {@link * TypeReference}. * @param typePath the path to the annotated type argument, wildcard bound, array element type, or - * static inner type within 'typeRef'. May be null if the annotation targets + * static inner type within 'typeRef'. May be {@literal null} if the annotation targets * 'typeRef' as a whole. * @param start the fist instructions corresponding to the continuous ranges that make the scope * of this local variable (inclusive). @@ -725,8 +720,8 @@ public abstract class MethodVisitor { * @param index the local variable's index in each range. This array must have the same size as * the 'start' array. * @param descriptor the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if this visitor is not + * @param visible {@literal true} if the annotation is visible at runtime. + * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not * interested in visiting this annotation. */ public AnnotationVisitor visitLocalVariableAnnotation( @@ -753,7 +748,7 @@ public abstract class MethodVisitor { * @param line a line number. This number refers to the source file from which the class was * compiled. * @param start the first instruction corresponding to this line number. - * @throws IllegalArgumentException if start has not already been visited by this visitor + * @throws IllegalArgumentException if {@code start} has not already been visited by this visitor * (by the {@link #visitLabel} method). */ public void visitLineNumber(final int line, final Label start) { diff --git a/spring-core/src/main/java/org/springframework/asm/MethodWriter.java b/spring-core/src/main/java/org/springframework/asm/MethodWriter.java index 2e95eb42bc..e6b8adaff8 100644 --- a/spring-core/src/main/java/org/springframework/asm/MethodWriter.java +++ b/spring-core/src/main/java/org/springframework/asm/MethodWriter.java @@ -322,35 +322,37 @@ final class MethodWriter extends MethodVisitor { /** * The first element in the exception handler list (used to generate the exception_table of the * Code attribute). The next ones can be accessed with the {@link Handler#nextHandler} field. May - * be null. + * be {@literal null}. */ private Handler firstHandler; /** * The last element in the exception handler list (used to generate the exception_table of the * Code attribute). The next ones can be accessed with the {@link Handler#nextHandler} field. May - * be null. + * be {@literal null}. */ private Handler lastHandler; /** The line_number_table_length field of the LineNumberTable code attribute. */ private int lineNumberTableLength; - /** The line_number_table array of the LineNumberTable code attribute, or null. */ + /** The line_number_table array of the LineNumberTable code attribute, or {@literal null}. */ private ByteVector lineNumberTable; /** The local_variable_table_length field of the LocalVariableTable code attribute. */ private int localVariableTableLength; - /** The local_variable_table array of the LocalVariableTable code attribute, or null. */ + /** + * The local_variable_table array of the LocalVariableTable code attribute, or {@literal null}. + */ private ByteVector localVariableTable; /** The local_variable_type_table_length field of the LocalVariableTypeTable code attribute. */ private int localVariableTypeTableLength; /** - * The local_variable_type_table array of the LocalVariableTypeTable code attribute, or - * null. + * The local_variable_type_table array of the LocalVariableTypeTable code attribute, or {@literal + * null}. */ private ByteVector localVariableTypeTable; @@ -362,19 +364,19 @@ final class MethodWriter extends MethodVisitor { /** * The last runtime visible type annotation of the Code attribute. The previous ones can be - * accessed with the {@link AnnotationWriter#previousAnnotation} field. May be null. + * accessed with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastCodeRuntimeVisibleTypeAnnotation; /** * The last runtime invisible type annotation of the Code attribute. The previous ones can be - * accessed with the {@link AnnotationWriter#previousAnnotation} field. May be null. + * accessed with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastCodeRuntimeInvisibleTypeAnnotation; /** * The first non standard attribute of the Code attribute. The next ones can be accessed with the - * {@link Attribute#nextAttribute} field. May be null. + * {@link Attribute#nextAttribute} field. May be {@literal null}. * *
WARNING: this list stores the attributes in the reverse order of their visit. * firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link @@ -388,7 +390,7 @@ final class MethodWriter extends MethodVisitor { /** The number_of_exceptions field of the Exceptions attribute. */ private final int numberOfExceptions; - /** The exception_index_table array of the Exceptions attribute, or null. */ + /** The exception_index_table array of the Exceptions attribute, or {@literal null}. */ private final int[] exceptionIndexTable; /** The signature_index field of the Signature attribute. */ @@ -396,13 +398,13 @@ final class MethodWriter extends MethodVisitor { /** * The last runtime visible annotation of this method. The previous ones can be accessed with the - * {@link AnnotationWriter#previousAnnotation} field. May be null. + * {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastRuntimeVisibleAnnotation; /** * The last runtime invisible annotation of this method. The previous ones can be accessed with - * the {@link AnnotationWriter#previousAnnotation} field. May be null. + * the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastRuntimeInvisibleAnnotation; @@ -411,8 +413,8 @@ final class MethodWriter extends MethodVisitor { /** * The runtime visible parameter annotations of this method. Each array element contains the last - * annotation of a parameter (which can be null - the previous ones can be accessed with - * the {@link AnnotationWriter#previousAnnotation} field). May be null. + * annotation of a parameter (which can be {@literal null} - the previous ones can be accessed + * with the {@link AnnotationWriter#previousAnnotation} field). May be {@literal null}. */ private AnnotationWriter[] lastRuntimeVisibleParameterAnnotations; @@ -421,35 +423,35 @@ final class MethodWriter extends MethodVisitor { /** * The runtime invisible parameter annotations of this method. Each array element contains the - * last annotation of a parameter (which can be null - the previous ones can be accessed - * with the {@link AnnotationWriter#previousAnnotation} field). May be null. + * last annotation of a parameter (which can be {@literal null} - the previous ones can be + * accessed with the {@link AnnotationWriter#previousAnnotation} field). May be {@literal null}. */ private AnnotationWriter[] lastRuntimeInvisibleParameterAnnotations; /** * The last runtime visible type annotation of this method. The previous ones can be accessed with - * the {@link AnnotationWriter#previousAnnotation} field. May be null. + * the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastRuntimeVisibleTypeAnnotation; /** * The last runtime invisible type annotation of this method. The previous ones can be accessed - * with the {@link AnnotationWriter#previousAnnotation} field. May be null. + * with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}. */ private AnnotationWriter lastRuntimeInvisibleTypeAnnotation; - /** The default_value field of the AnnotationDefault attribute, or null. */ + /** The default_value field of the AnnotationDefault attribute, or {@literal null}. */ private ByteVector defaultValue; /** The parameters_count field of the MethodParameters attribute. */ private int parametersCount; - /** The 'parameters' array of the MethodParameters attribute, or null. */ + /** The 'parameters' array of the MethodParameters attribute, or {@literal null}. */ private ByteVector parameters; /** * The first non standard attribute of this method. The next ones can be accessed with the {@link - * Attribute#nextAttribute} field. May be null. + * Attribute#nextAttribute} field. May be {@literal null}. * *
WARNING: this list stores the attributes in the reverse order of their visit.
* firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link
@@ -483,7 +485,7 @@ final class MethodWriter extends MethodVisitor {
/**
* The current basic block, i.e. the basic block of the last visited instruction. When {@link
* #compute} is equal to {@link #COMPUTE_MAX_STACK_AND_LOCAL} or {@link #COMPUTE_ALL_FRAMES}, this
- * field is null for unreachable code. When {@link #compute} is equal to {@link
+ * field is {@literal null} for unreachable code. When {@link #compute} is equal to {@link
* #COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES} or {@link #COMPUTE_INSERTED_FRAMES}, this field stays
* unchanged throughout the whole method (i.e. the whole code is seen as a single basic block;
* indeed, the existing frames are sufficient by hypothesis to compute any intermediate frame -
@@ -579,8 +581,8 @@ final class MethodWriter extends MethodVisitor {
* @param access the method's access flags (see {@link Opcodes}).
* @param name the method's name.
* @param descriptor the method's descriptor (see {@link Type}).
- * @param signature the method's signature. May be null.
- * @param exceptions the internal names of the method's exceptions. May be null.
+ * @param signature the method's signature. May be {@literal null}.
+ * @param exceptions the internal names of the method's exceptions. May be {@literal null}.
* @param compute indicates what must be computed (see #compute).
*/
MethodWriter(
@@ -591,7 +593,7 @@ final class MethodWriter extends MethodVisitor {
final String signature,
final String[] exceptions,
final int compute) {
- super(Opcodes.ASM6);
+ super(Opcodes.ASM7);
this.symbolTable = symbolTable;
this.accessFlags = " {@code version & V_PREVIEW_EXPERIMENTAL == V_PREVIEW_EXPERIMENTAL} tests if a version is
- * flagged with {@code V_PREVIEW_EXPERIMENTAL}.
- *
- * @deprecated This API is experimental.
+ * {@code version & V_PREVIEW == V_PREVIEW} tests if a version is flagged with {@code
+ * V_PREVIEW}.
*/
- @Deprecated int V_PREVIEW_EXPERIMENTAL = 0xFFFF0000;
+ int V_PREVIEW = 0xFFFF0000;
// Access flags values, defined in
// - https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.1-200-E.1
diff --git a/spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.java b/spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.java
index 026b8505e5..bc3bd919bd 100644
--- a/spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.java
+++ b/spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.java
@@ -18,7 +18,7 @@ package org.springframework.asm;
/**
* Utility class exposing constants related to Spring's internal repackaging
- * of the ASM bytecode library: currently based on ASM 6.2 plus minor patches.
+ * of the ASM bytecode library: currently based on ASM 7.0 plus minor patches.
*
* See package-level javadocs for more
* information on {@code org.springframework.asm}.
@@ -31,8 +31,8 @@ public final class SpringAsmInfo {
/**
* The ASM compatibility version for Spring's ASM visitor implementations:
- * currently {@link Opcodes#ASM7_EXPERIMENTAL}.
+ * currently {@link Opcodes#ASM7}, as of Spring Framework 5.1.
*/
- public static final int ASM_VERSION = Opcodes.ASM7_EXPERIMENTAL;
+ public static final int ASM_VERSION = Opcodes.ASM7;
}
diff --git a/spring-core/src/main/java/org/springframework/asm/Symbol.java b/spring-core/src/main/java/org/springframework/asm/Symbol.java
index f7c0d6c593..c7e5877a38 100644
--- a/spring-core/src/main/java/org/springframework/asm/Symbol.java
+++ b/spring-core/src/main/java/org/springframework/asm/Symbol.java
@@ -153,7 +153,7 @@ abstract class Symbol {
* symbols,
*