Skip to content

Commit 1da4d50

Browse files
committed
Upgrade to ASM master (7.0 beta) and CGLIB 3.2.8
Issue: SPR-17267
1 parent e473550 commit 1da4d50

26 files changed

+512
-338
lines changed

spring-core/spring-core.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ dependencyManagement {
77
}
88
}
99

10-
// As of Spring 5.0.3, spring-core includes asm 6.x and repackages cglib 3.2.6+, inlining
11-
// both into the spring-core jar. cglib 3.2.6+ itself depends on asm 6.x and is therefore
10+
// As of Spring 5.1, spring-core includes asm 7.0 and repackages cglib 3.2.8, inlining
11+
// both into the spring-core jar. cglib 3.2.8 itself depends on asm 6+ and is therefore
1212
// further transformed by the JarJar task to depend on org.springframework.asm; this
1313
// avoids including two different copies of asm unnecessarily.
14-
def cglibVersion = "3.2.7"
14+
def cglibVersion = "3.2.8"
1515
def objenesisVersion = "2.6"
1616

1717
configurations {

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

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929

3030
/**
3131
* A visitor to visit a Java annotation. The methods of this class must be called in the following
32-
* order: ( <tt>visit</tt> | <tt>visitEnum</tt> | <tt>visitAnnotation</tt> | <tt>visitArray</tt> )*
33-
* <tt>visitEnd</tt>.
32+
* order: ( {@code visit} | {@code visitEnum} | {@code visitAnnotation} | {@code visitArray} )*
33+
* {@code visitEnd}.
3434
*
3535
* @author Eric Bruneton
3636
* @author Eugene Kuleshov
@@ -39,7 +39,7 @@ public abstract class AnnotationVisitor {
3939

4040
/**
4141
* The ASM API version implemented by this visitor. The value of this field must be one of {@link
42-
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
42+
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
4343
*/
4444
protected final int api;
4545

@@ -50,8 +50,7 @@ public abstract class AnnotationVisitor {
5050
* Constructs a new {@link AnnotationVisitor}.
5151
*
5252
* @param api the ASM API version implemented by this visitor. Must be one of {@link
53-
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link
54-
* Opcodes#ASM7_EXPERIMENTAL}.
53+
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
5554
*/
5655
public AnnotationVisitor(final int api) {
5756
this(api, null);
@@ -61,16 +60,12 @@ public AnnotationVisitor(final int api) {
6160
* Constructs a new {@link AnnotationVisitor}.
6261
*
6362
* @param api the ASM API version implemented by this visitor. Must be one of {@link
64-
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link
65-
* Opcodes#ASM7_EXPERIMENTAL}.
63+
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
6664
* @param annotationVisitor the annotation visitor to which this visitor must delegate method
6765
* calls. May be null.
6866
*/
6967
public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) {
70-
if (api != Opcodes.ASM6
71-
&& api != Opcodes.ASM5
72-
&& api != Opcodes.ASM4
73-
&& api != Opcodes.ASM7_EXPERIMENTAL) {
68+
if (api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 && api != Opcodes.ASM7) {
7469
throw new IllegalArgumentException();
7570
}
7671
this.api = api;
@@ -112,9 +107,9 @@ public void visitEnum(final String name, final String descriptor, final String v
112107
*
113108
* @param name the value name.
114109
* @param descriptor the class descriptor of the nested annotation class.
115-
* @return a visitor to visit the actual nested annotation value, or <tt>null</tt> if this visitor
116-
* is not interested in visiting this nested annotation. <i>The nested annotation value must
117-
* be fully visited before calling other methods on this annotation visitor</i>.
110+
* @return a visitor to visit the actual nested annotation value, or {@literal null} if this
111+
* visitor is not interested in visiting this nested annotation. <i>The nested annotation
112+
* value must be fully visited before calling other methods on this annotation visitor</i>.
118113
*/
119114
public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
120115
if (av != null) {
@@ -129,8 +124,8 @@ public AnnotationVisitor visitAnnotation(final String name, final String descrip
129124
* visit}. This is what {@link ClassReader} does.
130125
*
131126
* @param name the value name.
132-
* @return a visitor to visit the actual array value elements, or <tt>null</tt> if this visitor is
133-
* not interested in visiting these values. The 'name' parameters passed to the methods of
127+
* @return a visitor to visit the actual array value elements, or {@literal null} if this visitor
128+
* is not interested in visiting these values. The 'name' parameters passed to the methods of
134129
* this visitor are ignored. <i>All the array values must be visited before calling other
135130
* methods on this annotation visitor</i>.
136131
*/

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ final class AnnotationWriter extends AnnotationVisitor {
112112
final boolean useNamedValues,
113113
final ByteVector annotation,
114114
final AnnotationWriter previousAnnotation) {
115-
super(Opcodes.ASM6);
115+
super(Opcodes.ASM7);
116116
this.symbolTable = symbolTable;
117117
this.useNamedValues = useNamedValues;
118118
this.annotation = annotation;

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

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@
3131
* A non standard class, field, method or code attribute, as defined in the Java Virtual Machine
3232
* Specification (JVMS).
3333
*
34-
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7">JVMS
34+
* @see <a href= "https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7">JVMS
3535
* 4.7</a>
36-
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.3">JVMS
36+
* @see <a href= "https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.3">JVMS
3737
* 4.7.3</a>
3838
* @author Eric Bruneton
3939
* @author Eugene Kuleshov
@@ -52,7 +52,7 @@ public class Attribute {
5252

5353
/**
5454
* The next attribute in this attribute list (Attribute instances can be linked via this field to
55-
* store a list of class, field, method or code attributes). May be <tt>null</tt>.
55+
* store a list of class, field, method or code attributes). May be {@literal null}.
5656
*/
5757
Attribute nextAttribute;
5858

@@ -66,23 +66,23 @@ protected Attribute(final String type) {
6666
}
6767

6868
/**
69-
* Returns <tt>true</tt> if this type of attribute is unknown. This means that the attribute
69+
* Returns {@literal true} if this type of attribute is unknown. This means that the attribute
7070
* content can't be parsed to extract constant pool references, labels, etc. Instead, the
7171
* attribute content is read as an opaque byte array, and written back as is. This can lead to
7272
* invalid attributes, if the content actually contains constant pool references, labels, or other
7373
* symbolic references that need to be updated when there are changes to the constant pool, the
74-
* method bytecode, etc. The default implementation of this method always returns <tt>true</tt>.
74+
* method bytecode, etc. The default implementation of this method always returns {@literal true}.
7575
*
76-
* @return <tt>true</tt> if this type of attribute is unknown.
76+
* @return {@literal true} if this type of attribute is unknown.
7777
*/
7878
public boolean isUnknown() {
7979
return true;
8080
}
8181

8282
/**
83-
* Returns <tt>true</tt> if this type of attribute is a code attribute.
83+
* Returns {@literal true} if this type of attribute is a code attribute.
8484
*
85-
* @return <tt>true</tt> if this type of attribute is a code attribute.
85+
* @return {@literal true} if this type of attribute is a code attribute.
8686
*/
8787
public boolean isCodeAttribute() {
8888
return false;
@@ -91,8 +91,8 @@ public boolean isCodeAttribute() {
9191
/**
9292
* Returns the labels corresponding to this attribute.
9393
*
94-
* @return the labels corresponding to this attribute, or <tt>null</tt> if this attribute is not a
95-
* code attribute that contains labels.
94+
* @return the labels corresponding to this attribute, or {@literal null} if this attribute is not
95+
* a code attribute that contains labels.
9696
*/
9797
protected Label[] getLabels() {
9898
return new Label[0];
@@ -114,8 +114,8 @@ protected Label[] getLabels() {
114114
* in {@link ClassReader#b}, or -1 if the attribute to be read is not a code attribute. The 6
115115
* attribute header bytes (attribute_name_index and attribute_length) are not taken into
116116
* account here.
117-
* @param labels the labels of the method's code, or <tt>null</tt> if the attribute to be read is
118-
* not a code attribute.
117+
* @param labels the labels of the method's code, or {@literal null} if the attribute to be read
118+
* is not a code attribute.
119119
* @return a <i>new</i> {@link Attribute} object corresponding to the specified bytes.
120120
*/
121121
protected Attribute read(
@@ -138,7 +138,7 @@ protected Attribute read(
138138
*
139139
* @param classWriter the class to which this attribute must be added. This parameter can be used
140140
* to add the items that corresponds to this attribute to the constant pool of this class.
141-
* @param code the bytecode of the method corresponding to this code attribute, or <tt>null</tt>
141+
* @param code the bytecode of the method corresponding to this code attribute, or {@literal null}
142142
* if this attribute is not a code attribute. Corresponds to the 'code' field of the Code
143143
* attribute.
144144
* @param codeLength the length of the bytecode of the method corresponding to this code
@@ -197,8 +197,9 @@ final int computeAttributesSize(final SymbolTable symbolTable) {
197197
* attribute_length) per attribute. Also adds the attribute type names to the constant pool.
198198
*
199199
* @param symbolTable where the constants used in the attributes must be stored.
200-
* @param code the bytecode of the method corresponding to these code attributes, or <tt>null</tt>
201-
* if they are not code attributes. Corresponds to the 'code' field of the Code attribute.
200+
* @param code the bytecode of the method corresponding to these code attributes, or {@literal
201+
* null} if they are not code attributes. Corresponds to the 'code' field of the Code
202+
* attribute.
202203
* @param codeLength the length of the bytecode of the method corresponding to these code
203204
* attributes, or 0 if they are not code attributes. Corresponds to the 'code_length' field of
204205
* the Code attribute.
@@ -248,8 +249,9 @@ final void putAttributes(final SymbolTable symbolTable, final ByteVector output)
248249
* attribute.
249250
*
250251
* @param symbolTable where the constants used in the attributes must be stored.
251-
* @param code the bytecode of the method corresponding to these code attributes, or <tt>null</tt>
252-
* if they are not code attributes. Corresponds to the 'code' field of the Code attribute.
252+
* @param code the bytecode of the method corresponding to these code attributes, or {@literal
253+
* null} if they are not code attributes. Corresponds to the 'code' field of the Code
254+
* attribute.
253255
* @param codeLength the length of the bytecode of the method corresponding to these code
254256
* attributes, or 0 if they are not code attributes. Corresponds to the 'code_length' field of
255257
* the Code attribute.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ final ByteVector encodeUTF8(final String stringValue, final int offset, final in
327327
* Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if
328328
* necessary.
329329
*
330-
* @param byteArrayValue an array of bytes. May be <tt>null</tt> to put <tt>byteLength</tt> null
330+
* @param byteArrayValue an array of bytes. May be {@literal null} to put {@code byteLength} null
331331
* bytes into this byte vector.
332332
* @param byteOffset index of the first byte of byteArrayValue that must be copied.
333333
* @param byteLength number of bytes of byteArrayValue that must be copied.

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

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ public ClassReader(
187187
int currentCpInfoIndex = 1;
188188
int currentCpInfoOffset = classFileOffset + 10;
189189
int currentMaxStringLength = 0;
190+
boolean hasBootstrapMethods = false;
190191
// The offset of the other entries depend on the total size of all the previous entries.
191192
while (currentCpInfoIndex < constantPoolCount) {
192193
cpInfoOffsets[currentCpInfoIndex++] = currentCpInfoOffset + 1;
@@ -198,9 +199,12 @@ public ClassReader(
198199
case Symbol.CONSTANT_INTEGER_TAG:
199200
case Symbol.CONSTANT_FLOAT_TAG:
200201
case Symbol.CONSTANT_NAME_AND_TYPE_TAG:
202+
cpInfoSize = 5;
203+
break;
201204
case Symbol.CONSTANT_INVOKE_DYNAMIC_TAG:
202205
case Symbol.CONSTANT_DYNAMIC_TAG:
203206
cpInfoSize = 5;
207+
hasBootstrapMethods = true;
204208
break;
205209
case Symbol.CONSTANT_LONG_TAG:
206210
case Symbol.CONSTANT_DOUBLE_TAG:
@@ -236,29 +240,8 @@ public ClassReader(
236240
this.header = currentCpInfoOffset;
237241

238242
// Read the BootstrapMethods attribute, if any (only get the offset of each method).
239-
int currentAttributeOffset = getFirstAttributeOffset();
240-
int[] currentBootstrapMethodOffsets = null;
241-
for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
242-
// Read the attribute_info's attribute_name and attribute_length fields.
243-
String attributeName = readUTF8(currentAttributeOffset, new char[maxStringLength]);
244-
int attributeLength = readInt(currentAttributeOffset + 2);
245-
currentAttributeOffset += 6;
246-
if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) {
247-
// Read the num_bootstrap_methods field and create an array of this size.
248-
currentBootstrapMethodOffsets = new int[readUnsignedShort(currentAttributeOffset)];
249-
// Compute and store the offset of each 'bootstrap_methods' array field entry.
250-
int currentBootstrapMethodOffset = currentAttributeOffset + 2;
251-
for (int j = 0; j < currentBootstrapMethodOffsets.length; ++j) {
252-
currentBootstrapMethodOffsets[j] = currentBootstrapMethodOffset;
253-
// Skip the bootstrap_method_ref and num_bootstrap_arguments fields (2 bytes each),
254-
// as well as the bootstrap_arguments array field (of size num_bootstrap_arguments * 2).
255-
currentBootstrapMethodOffset +=
256-
4 + readUnsignedShort(currentBootstrapMethodOffset + 2) * 2;
257-
}
258-
}
259-
currentAttributeOffset += attributeLength;
260-
}
261-
this.bootstrapMethodOffsets = currentBootstrapMethodOffsets;
243+
this.bootstrapMethodOffsets =
244+
hasBootstrapMethods ? readBootstrapMethodsAttribute(currentMaxStringLength) : null;
262245
}
263246

264247
/**
@@ -345,7 +328,7 @@ public String getClassName() {
345328
* Returns the internal of name of the super class (see {@link Type#getInternalName()}). For
346329
* interfaces, the super class is {@link Object}.
347330
*
348-
* @return the internal name of the super class, or <tt>null</tt> for {@link Object} class.
331+
* @return the internal name of the super class, or {@literal null} for {@link Object} class.
349332
* @see ClassVisitor#visit(int, int, String, String, String, String[])
350333
*/
351334
public String getSuperName() {
@@ -538,7 +521,7 @@ public void accept(
538521

539522
// Visit the NestHost attribute.
540523
if (nestHostClass != null) {
541-
classVisitor.visitNestHostExperimental(nestHostClass);
524+
classVisitor.visitNestHost(nestHostClass);
542525
}
543526

544527
// Visit the EnclosingMethod attribute.
@@ -648,7 +631,7 @@ public void accept(
648631
int numberOfNestMembers = readUnsignedShort(nestMembersOffset);
649632
int currentNestMemberOffset = nestMembersOffset + 2;
650633
while (numberOfNestMembers-- > 0) {
651-
classVisitor.visitNestMemberExperimental(readClass(currentNestMemberOffset, charBuffer));
634+
classVisitor.visitNestMember(readClass(currentNestMemberOffset, charBuffer));
652635
currentNestMemberOffset += 2;
653636
}
654637
}
@@ -2775,7 +2758,7 @@ private int readElementValues(
27752758
* @param annotationVisitor the visitor that must visit the element_value structure.
27762759
* @param elementValueOffset the start offset in {@link #b} of the element_value structure to be
27772760
* read.
2778-
* @param elementName the name of the element_value structure to be read, or <tt>null</tt>.
2761+
* @param elementName the name of the element_value structure to be read, or {@literal null}.
27792762
* @param charBuffer the buffer used to read strings in the constant pool.
27802763
* @return the end offset of the JVMS 'element_value' structure.
27812764
*/
@@ -3222,6 +3205,41 @@ final int getFirstAttributeOffset() {
32223205
return currentOffset + 2;
32233206
}
32243207

3208+
/**
3209+
* Reads the BootstrapMethods attribute to compute the offset of each bootstrap method.
3210+
*
3211+
* @param maxStringLength a conservative estimate of the maximum length of the strings contained
3212+
* in the constant pool of the class.
3213+
* @return the offsets of the bootstrap methods or null.
3214+
*/
3215+
private int[] readBootstrapMethodsAttribute(final int maxStringLength) {
3216+
char[] charBuffer = new char[maxStringLength];
3217+
int currentAttributeOffset = getFirstAttributeOffset();
3218+
int[] currentBootstrapMethodOffsets = null;
3219+
for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
3220+
// Read the attribute_info's attribute_name and attribute_length fields.
3221+
String attributeName = readUTF8(currentAttributeOffset, charBuffer);
3222+
int attributeLength = readInt(currentAttributeOffset + 2);
3223+
currentAttributeOffset += 6;
3224+
if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) {
3225+
// Read the num_bootstrap_methods field and create an array of this size.
3226+
currentBootstrapMethodOffsets = new int[readUnsignedShort(currentAttributeOffset)];
3227+
// Compute and store the offset of each 'bootstrap_methods' array field entry.
3228+
int currentBootstrapMethodOffset = currentAttributeOffset + 2;
3229+
for (int j = 0; j < currentBootstrapMethodOffsets.length; ++j) {
3230+
currentBootstrapMethodOffsets[j] = currentBootstrapMethodOffset;
3231+
// Skip the bootstrap_method_ref and num_bootstrap_arguments fields (2 bytes each),
3232+
// as well as the bootstrap_arguments array field (of size num_bootstrap_arguments * 2).
3233+
currentBootstrapMethodOffset +=
3234+
4 + readUnsignedShort(currentBootstrapMethodOffset + 2) * 2;
3235+
}
3236+
return currentBootstrapMethodOffsets;
3237+
}
3238+
currentAttributeOffset += attributeLength;
3239+
}
3240+
return null;
3241+
}
3242+
32253243
/**
32263244
* Reads a non standard JVMS 'attribute' structure in {@link #b}.
32273245
*
@@ -3236,8 +3254,8 @@ final int getFirstAttributeOffset() {
32363254
* @param codeAttributeOffset the start offset of the enclosing Code attribute in {@link #b}, or
32373255
* -1 if the attribute to be read is not a code attribute. The 6 attribute header bytes
32383256
* (attribute_name_index and attribute_length) are not taken into account here.
3239-
* @param labels the labels of the method's code, or <tt>null</tt> if the attribute to be read is
3240-
* not a code attribute.
3257+
* @param labels the labels of the method's code, or {@literal null} if the attribute to be read
3258+
* is not a code attribute.
32413259
* @return the attribute that has been read.
32423260
*/
32433261
private Attribute readAttribute(

0 commit comments

Comments
 (0)