Browse Source

Upgrade to ASM master (7.0 beta) and CGLIB 3.2.8

Issue: SPR-17267
pull/1955/head
Juergen Hoeller 7 years ago
parent
commit
1da4d504c4
  1. 6
      spring-core/spring-core.gradle
  2. 27
      spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java
  3. 2
      spring-core/src/main/java/org/springframework/asm/AnnotationWriter.java
  4. 36
      spring-core/src/main/java/org/springframework/asm/Attribute.java
  5. 2
      spring-core/src/main/java/org/springframework/asm/ByteVector.java
  6. 76
      spring-core/src/main/java/org/springframework/asm/ClassReader.java
  7. 63
      spring-core/src/main/java/org/springframework/asm/ClassTooLargeException.java
  8. 130
      spring-core/src/main/java/org/springframework/asm/ClassVisitor.java
  9. 35
      spring-core/src/main/java/org/springframework/asm/ClassWriter.java
  10. 10
      spring-core/src/main/java/org/springframework/asm/ConstantDynamic.java
  11. 29
      spring-core/src/main/java/org/springframework/asm/FieldVisitor.java
  12. 16
      spring-core/src/main/java/org/springframework/asm/FieldWriter.java
  13. 10
      spring-core/src/main/java/org/springframework/asm/Frame.java
  14. 16
      spring-core/src/main/java/org/springframework/asm/Handler.java
  15. 2
      spring-core/src/main/java/org/springframework/asm/Label.java
  16. 83
      spring-core/src/main/java/org/springframework/asm/MethodTooLargeException.java
  17. 107
      spring-core/src/main/java/org/springframework/asm/MethodVisitor.java
  18. 63
      spring-core/src/main/java/org/springframework/asm/MethodWriter.java
  19. 19
      spring-core/src/main/java/org/springframework/asm/ModuleVisitor.java
  20. 2
      spring-core/src/main/java/org/springframework/asm/ModuleWriter.java
  21. 15
      spring-core/src/main/java/org/springframework/asm/Opcodes.java
  22. 6
      spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.java
  23. 9
      spring-core/src/main/java/org/springframework/asm/Symbol.java
  24. 28
      spring-core/src/main/java/org/springframework/asm/SymbolTable.java
  25. 52
      spring-core/src/main/java/org/springframework/asm/Type.java
  26. 6
      spring-core/src/main/java/org/springframework/asm/TypePath.java

6
spring-core/spring-core.gradle

@ -7,11 +7,11 @@ dependencyManagement { @@ -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 {

27
spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java

@ -29,8 +29,8 @@ package org.springframework.asm; @@ -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: ( <tt>visit</tt> | <tt>visitEnum</tt> | <tt>visitAnnotation</tt> | <tt>visitArray</tt> )*
* <tt>visitEnd</tt>.
* 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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 <tt>null</tt> if this visitor
* is not interested in visiting this nested annotation. <i>The nested annotation value must
* be fully visited before calling other methods on this annotation visitor</i>.
* @return a visitor to visit the actual nested annotation value, or {@literal null} if this
* visitor is not interested in visiting this nested annotation. <i>The nested annotation
* value must be fully visited before calling other methods on this annotation visitor</i>.
*/
public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
if (av != null) {
@ -129,8 +124,8 @@ public abstract class AnnotationVisitor { @@ -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 <tt>null</tt> 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. <i>All the array values must be visited before calling other
* methods on this annotation visitor</i>.
*/

2
spring-core/src/main/java/org/springframework/asm/AnnotationWriter.java

@ -112,7 +112,7 @@ final class AnnotationWriter extends AnnotationVisitor { @@ -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;

36
spring-core/src/main/java/org/springframework/asm/Attribute.java

@ -31,9 +31,9 @@ package org.springframework.asm; @@ -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 <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7">JVMS
* @see <a href= "https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7">JVMS
* 4.7</a>
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.3">JVMS
* @see <a href= "https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.3">JVMS
* 4.7.3</a>
* @author Eric Bruneton
* @author Eugene Kuleshov
@ -52,7 +52,7 @@ public class Attribute { @@ -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 <tt>null</tt>.
* store a list of class, field, method or code attributes). May be {@literal null}.
*/
Attribute nextAttribute;
@ -66,23 +66,23 @@ public class Attribute { @@ -66,23 +66,23 @@ public class Attribute {
}
/**
* Returns <tt>true</tt> 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 <tt>true</tt>.
* method bytecode, etc. The default implementation of this method always returns {@literal true}.
*
* @return <tt>true</tt> if this type of attribute is unknown.
* @return {@literal true} if this type of attribute is unknown.
*/
public boolean isUnknown() {
return true;
}
/**
* Returns <tt>true</tt> if this type of attribute is a code attribute.
* Returns {@literal true} if this type of attribute is a code attribute.
*
* @return <tt>true</tt> 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 { @@ -91,8 +91,8 @@ public class Attribute {
/**
* Returns the labels corresponding to this attribute.
*
* @return the labels corresponding to this attribute, or <tt>null</tt> 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 { @@ -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 <tt>null</tt> 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 <i>new</i> {@link Attribute} object corresponding to the specified bytes.
*/
protected Attribute read(
@ -138,7 +138,7 @@ public class Attribute { @@ -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 <tt>null</tt>
* @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 { @@ -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 <tt>null</tt>
* 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 { @@ -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 <tt>null</tt>
* 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.

2
spring-core/src/main/java/org/springframework/asm/ByteVector.java

@ -327,7 +327,7 @@ public class ByteVector { @@ -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 <tt>null</tt> to put <tt>byteLength</tt> 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.

76
spring-core/src/main/java/org/springframework/asm/ClassReader.java

@ -187,6 +187,7 @@ public class ClassReader { @@ -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 { @@ -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 { @@ -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 { @@ -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 <tt>null</tt> 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 { @@ -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 { @@ -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 { @@ -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 <tt>null</tt>.
* @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 { @@ -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 { @@ -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 <tt>null</tt> 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(

63
spring-core/src/main/java/org/springframework/asm/ClassTooLargeException.java

@ -0,0 +1,63 @@ @@ -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;
}
}

130
spring-core/src/main/java/org/springframework/asm/ClassVisitor.java

@ -29,10 +29,10 @@ package org.springframework.asm; @@ -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:
* <tt>visit</tt> [ <tt>visitSource</tt> ] [ <tt>visitModule</tt> ][ <tt>visitNestHost</tt> ][
* <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> | <tt>visitTypeAnnotation</tt> |
* <tt>visitAttribute</tt> )* ( <tt>visitNestMember</tt> | <tt>visitInnerClass</tt> |
* <tt>visitField</tt> | <tt>visitMethod</tt> )* <tt>visitEnd</tt>.
* {@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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 <tt>null</tt> 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 <tt>null</tt>, 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 <tt>null</tt>.
* Type#getInternalName()}). May be {@literal null}.
*/
public void visit(
final int version,
@ -109,10 +104,10 @@ public abstract class ClassVisitor { @@ -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
* <tt>null</tt>.
* @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 <tt>null</tt>.
* 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 { @@ -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 <tt>null</tt>.
* @return a visitor to visit the module values, or <tt>null</tt> 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 { @@ -141,22 +136,21 @@ public abstract class ClassVisitor {
}
/**
* <b>Experimental, use at your own risk. This method will be renamed when it becomes stable, this
* will break existing code using it</b>. 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 { @@ -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 <tt>null</tt> 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 <tt>null</tt> 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 { @@ -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 <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 { @@ -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 <tt>null</tt> 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 <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 { @@ -229,22 +223,20 @@ public abstract class ClassVisitor {
}
/**
* <b>Experimental, use at your own risk. This method will be renamed when it becomes stable, this
* will break existing code using it</b>. 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 { @@ -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 <tt>null</tt> 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
* <tt>null</tt> 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 { @@ -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 <tt>null</tt> 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 <tt>null</tt> 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 <tt>int</tt>, <tt>float</tt>,
* <tt>long</tt> or <tt>String</tt> fields respectively). <i>This parameter is only used for
* static fields</i>. 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 <tt>null</tt> 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). <i>This parameter is only used for static
* fields</i>. 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 { @@ -299,19 +291,19 @@ public abstract class ClassVisitor {
/**
* Visits a method of the class. This method <i>must</i> return a new {@link MethodVisitor}
* instance (or <tt>null</tt>) 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 <tt>null</tt> 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 <tt>null</tt>.
* @return an object to visit the byte code of the method, or <tt>null</tt> 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,

35
spring-core/src/main/java/org/springframework/asm/ClassWriter.java

@ -123,7 +123,7 @@ public class ClassWriter extends ClassVisitor { @@ -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 <tt>null</tt>. */
/** 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 { @@ -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 <tt>null</tt>. */
/** 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 <tt>null</tt>.
* {@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 <tt>null</tt>.
* {@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 <tt>null</tt>.
* 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 <tt>null</tt>.
* with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
*/
private AnnotationWriter lastRuntimeInvisibleTypeAnnotation;
/** The Module attribute of this class, or <tt>null</tt>. */
/** 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 { @@ -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 <tt>null</tt>. */
/** 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 <tt>null</tt>.
* Attribute#nextAttribute} field. May be {@literal null}.
*
* <p><b>WARNING</b>: this list stores the attributes in the <i>reverse</i> 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 { @@ -234,7 +234,7 @@ public class ClassWriter extends ClassVisitor {
* maximum stack size nor the stack frames will be computed for these methods</i>.
*/
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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 <tt>true</tt> if <tt>owner</tt> 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(

10
spring-core/src/main/java/org/springframework/asm/ConstantDynamic.java

@ -109,6 +109,16 @@ public final class ConstantDynamic { @@ -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) {

29
spring-core/src/main/java/org/springframework/asm/FieldVisitor.java

@ -29,8 +29,8 @@ package org.springframework.asm; @@ -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:
* ( <tt>visitAnnotation</tt> | <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )*
* <tt>visitEnd</tt>.
* ( {@code visitAnnotation} | {@code visitTypeAnnotation} | {@code visitAttribute} )* {@code
* visitEnd}.
*
* @author Eric Bruneton
*/
@ -38,7 +38,7 @@ public abstract class FieldVisitor { @@ -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 { @@ -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 { @@ -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 { @@ -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 <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 { @@ -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 <tt>null</tt> 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 <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> 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);

16
spring-core/src/main/java/org/springframework/asm/FieldWriter.java

@ -70,31 +70,31 @@ final class FieldWriter extends FieldVisitor { @@ -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 <tt>null</tt>.
* {@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 <tt>null</tt>.
* {@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 <tt>null</tt>.
* 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 <tt>null</tt>.
* 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 <tt>null</tt>.
* Attribute#nextAttribute} field. May be {@literal null}.
*
* <p><b>WARNING</b>: this list stores the attributes in the <i>reverse</i> 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 { @@ -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 <tt>null</tt>.
* @param constantValue the field's constant value. May be <tt>null</tt>.
* @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 { @@ -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);

10
spring-core/src/main/java/org/springframework/asm/Frame.java

@ -1105,15 +1105,15 @@ class Frame { @@ -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 <tt>true</tt> 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 <tt>true</tt> 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 { @@ -1242,7 +1242,7 @@ class Frame {
/**
* Merges the type at the given index in the given abstract type array with the given type.
* Returns <tt>true</tt> 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 { @@ -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 <tt>true</tt> 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,

16
spring-core/src/main/java/org/springframework/asm/Handler.java

@ -64,8 +64,8 @@ final class Handler { @@ -64,8 +64,8 @@ final class Handler {
final int catchType;
/**
* The internal name of the type of exceptions handled by this handler, or <tt>null</tt> 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 { @@ -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 <tt>null</tt> to catch any exceptions.
* or {@literal null} to catch any exceptions.
*/
Handler(
final Label startPc,
@ -111,9 +111,9 @@ final class Handler { @@ -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 <tt>null</tt>.
* @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 <tt>null</tt>.
* @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 { @@ -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 <tt>null</tt>.
* @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 { @@ -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. <i>This includes the exception_table_length field.</i>
*
* @param firstHandler the beginning of a Handler list. May be <tt>null</tt>.
* @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 { @@ -180,7 +180,7 @@ final class Handler {
* Puts the JVMS exception_table corresponding to the Handler list that begins with the given
* element. <i>This includes the exception_table_length field.</i>
*
* @param firstHandler the beginning of a Handler list. May be <tt>null</tt>.
* @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) {

2
spring-core/src/main/java/org/springframework/asm/Label.java

@ -435,7 +435,7 @@ public class Label { @@ -435,7 +435,7 @@ public class Label {
*
* @param code the bytecode of the method.
* @param bytecodeOffset the bytecode offset of this label.
* @return <tt>true</tt> 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

83
spring-core/src/main/java/org/springframework/asm/MethodTooLargeException.java

@ -0,0 +1,83 @@ @@ -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;
}
}

107
spring-core/src/main/java/org/springframework/asm/MethodVisitor.java

@ -29,20 +29,20 @@ package org.springframework.asm; @@ -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: ( <tt>visitParameter</tt> )* [ <tt>visitAnnotationDefault</tt> ] (
* <tt>visitAnnotation</tt> | <tt>visitAnnotableParameterCount</tt> |
* <tt>visitParameterAnnotation</tt> <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* [
* <tt>visitCode</tt> ( <tt>visitFrame</tt> | <tt>visit<i>X</i>Insn</tt> | <tt>visitLabel</tt> |
* <tt>visitInsnAnnotation</tt> | <tt>visitTryCatchBlock</tt> | <tt>visitTryCatchAnnotation</tt> |
* <tt>visitLocalVariable</tt> | <tt>visitLocalVariableAnnotation</tt> | <tt>visitLineNumber</tt> )*
* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In addition, the <tt>visit<i>X</i>Insn</tt> and
* <tt>visitLabel</tt> methods must be called in the sequential order of the bytecode instructions
* of the visited code, <tt>visitInsnAnnotation</tt> must be called <i>after</i> the annotated
* instruction, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the labels passed as
* arguments have been visited, <tt>visitTryCatchBlockAnnotation</tt> must be called <i>after</i>
* the corresponding try catch block has been visited, and the <tt>visitLocalVariable</tt>,
* <tt>visitLocalVariableAnnotation</tt> and <tt>visitLineNumber</tt> methods must be called
* <i>after</i> 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 visit<i>X</i>Insn} | {@code visitLabel} | {@code visitInsnAnnotation} | {@code
* visitTryCatchBlock} | {@code visitTryCatchAnnotation} | {@code visitLocalVariable} | {@code
* visitLocalVariableAnnotation} | {@code visitLineNumber} )* {@code visitMaxs} ] {@code visitEnd}.
* In addition, the {@code visit<i>X</i>Insn} and {@code visitLabel} methods must be called in the
* sequential order of the bytecode instructions of the visited code, {@code visitInsnAnnotation}
* must be called <i>after</i> the annotated instruction, {@code visitTryCatchBlock} must be called
* <i>before</i> the labels passed as arguments have been visited, {@code
* visitTryCatchBlockAnnotation} must be called <i>after</i> the corresponding try catch block has
* been visited, and the {@code visitLocalVariable}, {@code visitLocalVariableAnnotation} and {@code
* visitLineNumber} methods must be called <i>after</i> the labels passed as arguments have been
* visited.
*
* @author Eric Bruneton
*/
@ -52,7 +52,7 @@ public abstract class MethodVisitor { @@ -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 { @@ -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 { @@ -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 { @@ -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 <tt>ACC_FINAL</tt>, <tt>ACC_SYNTHETIC</tt>
* or/and <tt>ACC_MANDATED</tt> 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 { @@ -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
* <tt>null</tt> 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 { @@ -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 <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 { @@ -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 <tt>null</tt> 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 <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 { @@ -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 <tt>true</tt> to define the number of method parameters that can have
* annotations visible at runtime, <tt>false</tt> 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 { @@ -197,8 +192,8 @@ public abstract class MethodVisitor {
* descriptor</i>, 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 <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 { @@ -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 <tt>.class</tt> 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 { @@ -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 { @@ -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. <tt>labels[i]</tt> is the beginning of the
* handler block for the <tt>min + i</tt> 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 { @@ -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. <tt>labels[i]</tt> is the beginning of the
* handler block for the <tt>keys[i]</tt> 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 { @@ -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 <tt>null</tt> 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 <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 { @@ -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
* <tt>null</tt> 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 { @@ -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 <tt>null</tt> 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 <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 { @@ -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 <tt>null</tt> 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 { @@ -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 <tt>null</tt> 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 { @@ -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 <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 { @@ -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 <tt>start</tt> 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) {

63
spring-core/src/main/java/org/springframework/asm/MethodWriter.java

@ -322,35 +322,37 @@ final class MethodWriter extends MethodVisitor { @@ -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 <tt>null</tt>.
* 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 <tt>null</tt>.
* 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 <tt>null</tt>. */
/** 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 <tt>null</tt>. */
/**
* 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
* <tt>null</tt>.
* 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 { @@ -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 <tt>null</tt>.
* 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 <tt>null</tt>.
* 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 <tt>null</tt>.
* {@link Attribute#nextAttribute} field. May be {@literal null}.
*
* <p><b>WARNING</b>: this list stores the attributes in the <i>reverse</i> 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 { @@ -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 <tt>null</tt>. */
/** 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 { @@ -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 <tt>null</tt>.
* {@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 <tt>null</tt>.
* the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
*/
private AnnotationWriter lastRuntimeInvisibleAnnotation;
@ -411,8 +413,8 @@ final class MethodWriter extends MethodVisitor { @@ -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 <tt>null</tt> - the previous ones can be accessed with
* the {@link AnnotationWriter#previousAnnotation} field). May be <tt>null</tt>.
* 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 { @@ -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 <tt>null</tt> - the previous ones can be accessed
* with the {@link AnnotationWriter#previousAnnotation} field). May be <tt>null</tt>.
* 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 <tt>null</tt>.
* 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 <tt>null</tt>.
* with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
*/
private AnnotationWriter lastRuntimeInvisibleTypeAnnotation;
/** The default_value field of the AnnotationDefault attribute, or <tt>null</tt>. */
/** 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 <tt>null</tt>. */
/** 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 <tt>null</tt>.
* Attribute#nextAttribute} field. May be {@literal null}.
*
* <p><b>WARNING</b>: this list stores the attributes in the <i>reverse</i> 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 { @@ -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 <tt>null</tt> 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 { @@ -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 <tt>null</tt>.
* @param exceptions the internal names of the method's exceptions. May be <tt>null</tt>.
* @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 { @@ -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 = "<init>".equals(name) ? access | Constants.ACC_CONSTRUCTOR : access;
this.nameIndex = symbolTable.addConstantUtf8(name);
@ -1289,9 +1291,13 @@ final class MethodWriter extends MethodVisitor { @@ -1289,9 +1291,13 @@ final class MethodWriter extends MethodVisitor {
// Add the instruction to the bytecode of the method.
Symbol constantSymbol = symbolTable.addConstant(value);
int constantIndex = constantSymbol.index;
char firstDescriptorChar;
boolean isLongOrDouble =
constantSymbol.tag == Symbol.CONSTANT_LONG_TAG
|| constantSymbol.tag == Symbol.CONSTANT_DOUBLE_TAG;
|| constantSymbol.tag == Symbol.CONSTANT_DOUBLE_TAG
|| (constantSymbol.tag == Symbol.CONSTANT_DYNAMIC_TAG
&& ((firstDescriptorChar = constantSymbol.value.charAt(0)) == 'J'
|| firstDescriptorChar == 'D'));
if (isLongOrDouble) {
code.put12(Constants.LDC2_W, constantIndex);
} else if (constantIndex >= 256) {
@ -1843,7 +1849,7 @@ final class MethodWriter extends MethodVisitor { @@ -1843,7 +1849,7 @@ final class MethodWriter extends MethodVisitor {
/**
* Ends the visit of {@link #currentFrame} by writing it in the StackMapTable entries and by
* updating the StackMapTable number_of_entries (except if the current frame is the first one,
* which is implicit in StackMapTable). Then resets {@link #currentFrame} to <tt>null</tt>.
* which is implicit in StackMapTable). Then resets {@link #currentFrame} to {@literal null}.
*/
void visitFrameEnd() {
if (previousFrame != null) {
@ -2076,7 +2082,8 @@ final class MethodWriter extends MethodVisitor { @@ -2076,7 +2082,8 @@ final class MethodWriter extends MethodVisitor {
// For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
if (code.length > 0) {
if (code.length > 65535) {
throw new IndexOutOfBoundsException("Method code too large!");
throw new MethodTooLargeException(
symbolTable.getClassName(), name, descriptor, code.length);
}
symbolTable.addConstantUtf8(Constants.CODE);
// The Code attribute has 6 header bytes, plus 2, 2, 4 and 2 bytes respectively for max_stack,

19
spring-core/src/main/java/org/springframework/asm/ModuleVisitor.java

@ -29,9 +29,8 @@ package org.springframework.asm; @@ -29,9 +29,8 @@ package org.springframework.asm;
/**
* A visitor to visit a Java module. The methods of this class must be called in the following
* order: <tt>visitMainClass</tt> | ( <tt>visitPackage</tt> | <tt>visitRequire</tt> |
* <tt>visitExport</tt> | <tt>visitOpen</tt> | <tt>visitUse</tt> | <tt>visitProvide</tt> )*
* <tt>visitEnd</tt>.
* order: ( {@code visitMainClass} | ( {@code visitPackage} | {@code visitRequire} | {@code
* visitExport} | {@code visitOpen} | {@code visitUse} | {@code visitProvide} )* ) {@code visitEnd}.
*
* @author Remi Forax
* @author Eric Bruneton
@ -39,7 +38,7 @@ package org.springframework.asm; @@ -39,7 +38,7 @@ package org.springframework.asm;
public abstract class ModuleVisitor {
/**
* The ASM API version implemented by this visitor. The value of this field must be one of {@link
* Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
* Opcodes#ASM6} or {@link Opcodes#ASM7}.
*/
protected final int api;
@ -50,7 +49,7 @@ public abstract class ModuleVisitor { @@ -50,7 +49,7 @@ public abstract class ModuleVisitor {
* Constructs a new {@link ModuleVisitor}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6}
* or {@link Opcodes#ASM7_EXPERIMENTAL}.
* or {@link Opcodes#ASM7}.
*/
public ModuleVisitor(final int api) {
this(api, null);
@ -60,12 +59,12 @@ public abstract class ModuleVisitor { @@ -60,12 +59,12 @@ public abstract class ModuleVisitor {
* Constructs a new {@link ModuleVisitor}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6}
* or {@link Opcodes#ASM7_EXPERIMENTAL}.
* or {@link Opcodes#ASM7}.
* @param moduleVisitor the module visitor to which this visitor must delegate method calls. May
* be null.
*/
public ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) {
if (api != Opcodes.ASM6 && api != Opcodes.ASM7_EXPERIMENTAL) {
if (api != Opcodes.ASM6 && api != Opcodes.ASM7) {
throw new IllegalArgumentException();
}
this.api = api;
@ -100,7 +99,7 @@ public abstract class ModuleVisitor { @@ -100,7 +99,7 @@ public abstract class ModuleVisitor {
* @param module the fully qualified name (using dots) of the dependence.
* @param access the access flag of the dependence among {@code ACC_TRANSITIVE}, {@code
* ACC_STATIC_PHASE}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
* @param version the module version at compile time, or <tt>null</tt>.
* @param version the module version at compile time, or {@literal null}.
*/
public void visitRequire(final String module, final int access, final String version) {
if (mv != null) {
@ -115,7 +114,7 @@ public abstract class ModuleVisitor { @@ -115,7 +114,7 @@ public abstract class ModuleVisitor {
* @param access the access flag of the exported package, valid values are among {@code
* ACC_SYNTHETIC} and {@code ACC_MANDATED}.
* @param modules the fully qualified names (using dots) of the modules that can access the public
* classes of the exported package, or <tt>null</tt>.
* classes of the exported package, or {@literal null}.
*/
public void visitExport(final String packaze, final int access, final String... modules) {
if (mv != null) {
@ -130,7 +129,7 @@ public abstract class ModuleVisitor { @@ -130,7 +129,7 @@ public abstract class ModuleVisitor {
* @param access the access flag of the opened package, valid values are among {@code
* ACC_SYNTHETIC} and {@code ACC_MANDATED}.
* @param modules the fully qualified names (using dots) of the modules that can use deep
* reflection to the classes of the open package, or <tt>null</tt>.
* reflection to the classes of the open package, or {@literal null}.
*/
public void visitOpen(final String packaze, final int access, final String... modules) {
if (mv != null) {

2
spring-core/src/main/java/org/springframework/asm/ModuleWriter.java

@ -94,7 +94,7 @@ final class ModuleWriter extends ModuleVisitor { @@ -94,7 +94,7 @@ final class ModuleWriter extends ModuleVisitor {
private int mainClassIndex;
ModuleWriter(final SymbolTable symbolTable, final int name, final int access, final int version) {
super(Opcodes.ASM6);
super(Opcodes.ASM7);
this.symbolTable = symbolTable;
this.moduleNameIndex = name;
this.moduleFlags = access;

15
spring-core/src/main/java/org/springframework/asm/Opcodes.java

@ -45,12 +45,7 @@ public interface Opcodes { @@ -45,12 +45,7 @@ public interface Opcodes {
int ASM4 = 4 << 16 | 0 << 8;
int ASM5 = 5 << 16 | 0 << 8;
int ASM6 = 6 << 16 | 0 << 8;
/**
* <b>Experimental, use at your own risk. This field will be renamed when it becomes stable, this
* will break existing code using it</b>.
*/
int ASM7_EXPERIMENTAL = 1 << 24 | 7 << 16 | 0 << 8;
int ASM7 = 7 << 16 | 0 << 8;
// Java ClassFile versions (the minor version is stored in the 16 most
// significant bits, and the
@ -72,12 +67,10 @@ public interface Opcodes { @@ -72,12 +67,10 @@ public interface Opcodes {
/**
* Version flag indicating that the class is using 'preview' features.
*
* <p>{@code version & V_PREVIEW_EXPERIMENTAL == V_PREVIEW_EXPERIMENTAL} tests if a version is
* flagged with {@code V_PREVIEW_EXPERIMENTAL}.
*
* @deprecated This API is experimental.
* <p>{@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

6
spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.java

@ -18,7 +18,7 @@ package org.springframework.asm; @@ -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.
*
* <p>See <a href="package-summary.html">package-level javadocs</a> for more
* information on {@code org.springframework.asm}.
@ -31,8 +31,8 @@ public final class SpringAsmInfo { @@ -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;
}

9
spring-core/src/main/java/org/springframework/asm/Symbol.java

@ -153,7 +153,7 @@ abstract class Symbol { @@ -153,7 +153,7 @@ abstract class Symbol {
* symbols,
* <li>an internal class name for {@link #CONSTANT_CLASS_TAG}, {@link #TYPE_TAG} and {@link
* #UNINITIALIZED_TYPE_TAG} symbols,
* <li><tt>null</tt> for the other types of symbol.
* <li>{@literal null} for the other types of symbol.
* </ul>
*/
final String value;
@ -205,9 +205,10 @@ abstract class Symbol { @@ -205,9 +205,10 @@ abstract class Symbol {
* @param index the symbol index in the constant pool, in the BootstrapMethods attribute, or in
* the (ASM specific) type table of a class (depending on 'tag').
* @param tag the symbol type. Must be one of the static tag values defined in this class.
* @param owner The internal name of the symbol's owner class. Maybe <tt>null</tt>.
* @param name The name of the symbol's corresponding class field or method. Maybe <tt>null</tt>.
* @param value The string value of this symbol. Maybe <tt>null</tt>.
* @param owner The internal name of the symbol's owner class. Maybe {@literal null}.
* @param name The name of the symbol's corresponding class field or method. Maybe {@literal
* null}.
* @param value The string value of this symbol. Maybe {@literal null}.
* @param data The numeric value of this symbol.
*/
Symbol(

28
spring-core/src/main/java/org/springframework/asm/SymbolTable.java

@ -99,7 +99,7 @@ final class SymbolTable { @@ -99,7 +99,7 @@ final class SymbolTable {
final ClassWriter classWriter;
/**
* The ClassReader from which this SymbolTable was constructed, or <tt>null</tt> if it was
* The ClassReader from which this SymbolTable was constructed, or {@literal null} if it was
* constructed from scratch.
*/
private final ClassReader sourceClassReader;
@ -161,7 +161,7 @@ final class SymbolTable { @@ -161,7 +161,7 @@ final class SymbolTable {
* be stored in the constant pool. This type table is used by the control flow and data flow
* analysis algorithm used to compute stack map frames from scratch. This array stores {@link
* Symbol#TYPE_TAG} and {@link Symbol#UNINITIALIZED_TYPE_TAG}) Symbol. The type symbol at index
* <tt>i</tt> has its {@link Symbol#index} equal to <tt>i</tt> (and vice versa).
* {@code i} has its {@link Symbol#index} equal to {@code i} (and vice versa).
*/
private Entry[] typeTable;
@ -203,6 +203,7 @@ final class SymbolTable { @@ -203,6 +203,7 @@ final class SymbolTable {
// method calls below), and to account for bootstrap method entries.
entries = new Entry[constantPoolCount * 2];
char[] charBuffer = new char[classReader.getMaxStringLength()];
boolean hasBootstrapMethods = false;
int itemIndex = 1;
while (itemIndex < constantPoolCount) {
int itemOffset = classReader.getItem(itemIndex);
@ -252,6 +253,7 @@ final class SymbolTable { @@ -252,6 +253,7 @@ final class SymbolTable {
break;
case Symbol.CONSTANT_DYNAMIC_TAG:
case Symbol.CONSTANT_INVOKE_DYNAMIC_TAG:
hasBootstrapMethods = true;
nameAndTypeItemOffset =
classReader.getItem(classReader.readUnsignedShort(itemOffset + 2));
addConstantDynamicOrInvokeDynamicReference(
@ -276,7 +278,23 @@ final class SymbolTable { @@ -276,7 +278,23 @@ final class SymbolTable {
(itemTag == Symbol.CONSTANT_LONG_TAG || itemTag == Symbol.CONSTANT_DOUBLE_TAG) ? 2 : 1;
}
// Copy the BootstrapMethods 'bootstrap_methods' array binary content, if any.
// Copy the BootstrapMethods, if any.
if (hasBootstrapMethods) {
copyBootstrapMethods(classReader, charBuffer);
}
}
/**
* Read the BootstrapMethods 'bootstrap_methods' array binary content and add them as entries of
* the SymbolTable.
*
* @param classReader the ClassReader whose bootstrap methods must be copied to initialize the
* SymbolTable.
* @param charBuffer a buffer used to read strings in the constant pool.
*/
private void copyBootstrapMethods(final ClassReader classReader, final char[] charBuffer) {
// Find attributOffset of the 'bootstrap_methods' array.
byte[] inputBytes = classReader.b;
int currentAttributeOffset = classReader.getFirstAttributeOffset();
for (int i = classReader.readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
String attributeName = classReader.readUTF8(currentAttributeOffset, charBuffer);
@ -313,8 +331,8 @@ final class SymbolTable { @@ -313,8 +331,8 @@ final class SymbolTable {
}
/**
* @return the ClassReader from which this SymbolTable was constructed, or <tt>null</tt> if it was
* constructed from scratch.
* @return the ClassReader from which this SymbolTable was constructed, or {@literal null} if it
* was constructed from scratch.
*/
ClassReader getSource() {
return sourceClassReader;

52
spring-core/src/main/java/org/springframework/asm/Type.java

@ -39,31 +39,31 @@ import java.lang.reflect.Method; @@ -39,31 +39,31 @@ import java.lang.reflect.Method;
*/
public class Type {
/** The sort of the <tt>void</tt> type. See {@link #getSort}. */
/** The sort of the {@code void} type. See {@link #getSort}. */
public static final int VOID = 0;
/** The sort of the <tt>boolean</tt> type. See {@link #getSort}. */
/** The sort of the {@code boolean} type. See {@link #getSort}. */
public static final int BOOLEAN = 1;
/** The sort of the <tt>char</tt> type. See {@link #getSort}. */
/** The sort of the {@code char} type. See {@link #getSort}. */
public static final int CHAR = 2;
/** The sort of the <tt>byte</tt> type. See {@link #getSort}. */
/** The sort of the {@code byte} type. See {@link #getSort}. */
public static final int BYTE = 3;
/** The sort of the <tt>short</tt> type. See {@link #getSort}. */
/** The sort of the {@code short} type. See {@link #getSort}. */
public static final int SHORT = 4;
/** The sort of the <tt>int</tt> type. See {@link #getSort}. */
/** The sort of the {@code int} type. See {@link #getSort}. */
public static final int INT = 5;
/** The sort of the <tt>float</tt> type. See {@link #getSort}. */
/** The sort of the {@code float} type. See {@link #getSort}. */
public static final int FLOAT = 6;
/** The sort of the <tt>long</tt> type. See {@link #getSort}. */
/** The sort of the {@code long} type. See {@link #getSort}. */
public static final int LONG = 7;
/** The sort of the <tt>double</tt> type. See {@link #getSort}. */
/** The sort of the {@code double} type. See {@link #getSort}. */
public static final int DOUBLE = 8;
/** The sort of array reference types. See {@link #getSort}. */
@ -81,32 +81,32 @@ public class Type { @@ -81,32 +81,32 @@ public class Type {
/** The descriptors of the primitive types. */
private static final String PRIMITIVE_DESCRIPTORS = "VZCBSIFJD";
/** The <tt>void</tt> type. */
/** The {@code void} type. */
public static final Type VOID_TYPE = new Type(VOID, PRIMITIVE_DESCRIPTORS, VOID, VOID + 1);
/** The <tt>boolean</tt> type. */
/** The {@code boolean} type. */
public static final Type BOOLEAN_TYPE =
new Type(BOOLEAN, PRIMITIVE_DESCRIPTORS, BOOLEAN, BOOLEAN + 1);
/** The <tt>char</tt> type. */
/** The {@code char} type. */
public static final Type CHAR_TYPE = new Type(CHAR, PRIMITIVE_DESCRIPTORS, CHAR, CHAR + 1);
/** The <tt>byte</tt> type. */
/** The {@code byte} type. */
public static final Type BYTE_TYPE = new Type(BYTE, PRIMITIVE_DESCRIPTORS, BYTE, BYTE + 1);
/** The <tt>short</tt> type. */
/** The {@code short} type. */
public static final Type SHORT_TYPE = new Type(SHORT, PRIMITIVE_DESCRIPTORS, SHORT, SHORT + 1);
/** The <tt>int</tt> type. */
/** The {@code int} type. */
public static final Type INT_TYPE = new Type(INT, PRIMITIVE_DESCRIPTORS, INT, INT + 1);
/** The <tt>float</tt> type. */
/** The {@code float} type. */
public static final Type FLOAT_TYPE = new Type(FLOAT, PRIMITIVE_DESCRIPTORS, FLOAT, FLOAT + 1);
/** The <tt>long</tt> type. */
/** The {@code long} type. */
public static final Type LONG_TYPE = new Type(LONG, PRIMITIVE_DESCRIPTORS, LONG, LONG + 1);
/** The <tt>double</tt> type. */
/** The {@code double} type. */
public static final Type DOUBLE_TYPE =
new Type(DOUBLE, PRIMITIVE_DESCRIPTORS, DOUBLE, DOUBLE + 1);
@ -366,8 +366,8 @@ public class Type { @@ -366,8 +366,8 @@ public class Type {
* @param methodDescriptor a method descriptor.
* @return the size of the arguments of the method (plus one for the implicit this argument),
* argumentsSize, and the size of its return value, returnSize, packed into a single int i =
* <tt>(argumentsSize &lt;&lt; 2) | returnSize</tt> (argumentsSize is therefore equal to <tt>i
* &gt;&gt; 2</tt>, and returnSize to <tt>i &amp; 0x03</tt>).
* {@code (argumentsSize &lt;&lt; 2) | returnSize} (argumentsSize is therefore equal to {@code
* i &gt;&gt; 2}, and returnSize to {@code i &amp; 0x03}).
*/
public static int getArgumentsAndReturnSizes(final String methodDescriptor) {
int argumentsSize = 1;
@ -560,8 +560,8 @@ public class Type { @@ -560,8 +560,8 @@ public class Type {
*
* @return the size of the arguments of the method (plus one for the implicit this argument),
* argumentsSize, and the size of its return value, returnSize, packed into a single int i =
* <tt>(argumentsSize &lt;&lt; 2) | returnSize</tt> (argumentsSize is therefore equal to <tt>i
* &gt;&gt; 2</tt>, and returnSize to <tt>i &amp; 0x03</tt>).
* {@code (argumentsSize &lt;&lt; 2) | returnSize} (argumentsSize is therefore equal to {@code
* i &gt;&gt; 2}, and returnSize to {@code i &amp; 0x03}).
*/
public int getArgumentsAndReturnSizes() {
return getArgumentsAndReturnSizes(getDescriptor());
@ -742,8 +742,8 @@ public class Type { @@ -742,8 +742,8 @@ public class Type {
/**
* Returns the size of values of this type. This method must not be used for method types.
*
* @return the size of values of this type, i.e., 2 for <tt>long</tt> and <tt>double</tt>, 0 for
* <tt>void</tt> and 1 otherwise.
* @return the size of values of this type, i.e., 2 for {@code long} and {@code double}, 0 for
* {@code void} and 1 otherwise.
*/
public int getSize() {
switch (sort) {
@ -775,7 +775,7 @@ public class Type { @@ -775,7 +775,7 @@ public class Type {
* IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL, ISHR, IUSHR, IAND, IOR, IXOR and
* IRETURN.
* @return an opcode that is similar to the given opcode, but adapted to this {@link Type}. For
* example, if this type is <tt>float</tt> and <tt>opcode</tt> is IRETURN, this method returns
* example, if this type is {@code float} and {@code opcode} is IRETURN, this method returns
* FRETURN.
*/
public int getOpcode(final int opcode) {
@ -848,7 +848,7 @@ public class Type { @@ -848,7 +848,7 @@ public class Type {
* Tests if the given object is equal to this type.
*
* @param object the object to be compared to this type.
* @return <tt>true</tt> if the given object is equal to this type.
* @return {@literal true} if the given object is equal to this type.
*/
@Override
public boolean equals(final Object object) {

6
spring-core/src/main/java/org/springframework/asm/TypePath.java

@ -113,8 +113,8 @@ public class TypePath { @@ -113,8 +113,8 @@ public class TypePath {
* object.
*
* @param typePath a type path in string form, in the format used by {@link #toString()}. May be
* <tt>null</tt> or empty.
* @return the corresponding TypePath object, or <tt>null</tt> if the path is empty.
* {@literal null} or empty.
* @return the corresponding TypePath object, or {@literal null} if the path is empty.
*/
public static TypePath fromString(final String typePath) {
if (typePath == null || typePath.length() == 0) {
@ -187,7 +187,7 @@ public class TypePath { @@ -187,7 +187,7 @@ public class TypePath {
* Puts the type_path JVMS structure corresponding to the given TypePath into the given
* ByteVector.
*
* @param typePath a TypePath instance, or <tt>null</tt> for empty paths.
* @param typePath a TypePath instance, or {@literal null} for empty paths.
* @param output where the type path must be put.
*/
static void put(final TypePath typePath, final ByteVector output) {

Loading…
Cancel
Save