Upgrade to ASM 9.0 beta

Closes gh-24872
This commit is contained in:
Juergen Hoeller 2020-07-07 16:17:58 +02:00
parent 8e02d2706e
commit a1bab14140
17 changed files with 89 additions and 98 deletions

View File

@ -68,12 +68,13 @@ public abstract class AnnotationVisitor {
* calls. May be {@literal null}. * calls. May be {@literal null}.
*/ */
public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) { public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) {
if (api != Opcodes.ASM8 if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7 && api != Opcodes.ASM7
&& api != Opcodes.ASM6 && api != Opcodes.ASM6
&& api != Opcodes.ASM5 && api != Opcodes.ASM5
&& api != Opcodes.ASM4 && api != Opcodes.ASM4
&& api != Opcodes.ASM9_EXPERIMENTAL) { && api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api); throw new IllegalArgumentException("Unsupported api " + api);
} }
// SPRING PATCH: no preview mode check for ASM 9 experimental // SPRING PATCH: no preview mode check for ASM 9 experimental

View File

@ -112,7 +112,7 @@ final class AnnotationWriter extends AnnotationVisitor {
final boolean useNamedValues, final boolean useNamedValues,
final ByteVector annotation, final ByteVector annotation,
final AnnotationWriter previousAnnotation) { final AnnotationWriter previousAnnotation) {
super(/* latest api = */ Opcodes.ASM8); super(/* latest api = */ Opcodes.ASM9);
this.symbolTable = symbolTable; this.symbolTable = symbolTable;
this.useNamedValues = useNamedValues; this.useNamedValues = useNamedValues;
this.annotation = annotation; this.annotation = annotation;

View File

@ -100,7 +100,8 @@ public class ClassReader {
@Deprecated @Deprecated
// DontCheck(MemberName): can't be renamed (for backward binary compatibility). // DontCheck(MemberName): can't be renamed (for backward binary compatibility).
public final byte[] b; public final byte[] b;
/** The offset in bytes of the ClassFile's access_flags field. */
public final int header;
/** /**
* A byte array containing the JVMS ClassFile structure to be parsed. <i>The content of this array * A byte array containing the JVMS ClassFile structure to be parsed. <i>The content of this array
* must not be modified. This field is intended for {@link Attribute} sub classes, and is normally * must not be modified. This field is intended for {@link Attribute} sub classes, and is normally
@ -111,7 +112,6 @@ public class ClassReader {
* ClassFile element offsets within this byte array. * ClassFile element offsets within this byte array.
*/ */
final byte[] classFileBuffer; final byte[] classFileBuffer;
/** /**
* The offset in bytes, in {@link #classFileBuffer}, of each cp_info entry of the ClassFile's * The offset in bytes, in {@link #classFileBuffer}, of each cp_info entry of the ClassFile's
* constant_pool array, <i>plus one</i>. In other words, the offset of constant pool entry i is * constant_pool array, <i>plus one</i>. In other words, the offset of constant pool entry i is
@ -119,19 +119,16 @@ public class ClassReader {
* 1]. * 1].
*/ */
private final int[] cpInfoOffsets; private final int[] cpInfoOffsets;
/** /**
* The String objects corresponding to the CONSTANT_Utf8 constant pool items. This cache avoids * The String objects corresponding to the CONSTANT_Utf8 constant pool items. This cache avoids
* multiple parsing of a given CONSTANT_Utf8 constant pool item. * multiple parsing of a given CONSTANT_Utf8 constant pool item.
*/ */
private final String[] constantUtf8Values; private final String[] constantUtf8Values;
/** /**
* The ConstantDynamic objects corresponding to the CONSTANT_Dynamic constant pool items. This * The ConstantDynamic objects corresponding to the CONSTANT_Dynamic constant pool items. This
* cache avoids multiple parsing of a given CONSTANT_Dynamic constant pool item. * cache avoids multiple parsing of a given CONSTANT_Dynamic constant pool item.
*/ */
private final ConstantDynamic[] constantDynamicValues; private final ConstantDynamic[] constantDynamicValues;
/** /**
* The start offsets in {@link #classFileBuffer} of each element of the bootstrap_methods array * The start offsets in {@link #classFileBuffer} of each element of the bootstrap_methods array
* (in the BootstrapMethods attribute). * (in the BootstrapMethods attribute).
@ -140,16 +137,12 @@ public class ClassReader {
* 4.7.23</a> * 4.7.23</a>
*/ */
private final int[] bootstrapMethodOffsets; private final int[] bootstrapMethodOffsets;
/** /**
* A conservative estimate of the maximum length of the strings contained in the constant pool of * A conservative estimate of the maximum length of the strings contained in the constant pool of
* the class. * the class.
*/ */
private final int maxStringLength; private final int maxStringLength;
/** The offset in bytes of the ClassFile's access_flags field. */
public final int header;
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
// Constructors // Constructors
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
@ -191,7 +184,7 @@ public class ClassReader {
this.b = classFileBuffer; this.b = classFileBuffer;
// Check the class' major_version. This field is after the magic and minor_version fields, which // Check the class' major_version. This field is after the magic and minor_version fields, which
// use 4 and 2 bytes respectively. // use 4 and 2 bytes respectively.
if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V15) { if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V16) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Unsupported class file major version " + readShort(classFileOffset + 6)); "Unsupported class file major version " + readShort(classFileOffset + 6));
} }
@ -415,7 +408,6 @@ public class ClassReader {
* @param parsingOptions the options to use to parse this class. One or more of {@link * @param parsingOptions the options to use to parse this class. One or more of {@link
* #SKIP_CODE}, {@link #SKIP_DEBUG}, {@link #SKIP_FRAMES} or {@link #EXPAND_FRAMES}. * #SKIP_CODE}, {@link #SKIP_DEBUG}, {@link #SKIP_FRAMES} or {@link #EXPAND_FRAMES}.
*/ */
@SuppressWarnings("deprecation") // for visitPermittedSubtypeExperimental
public void accept( public void accept(
final ClassVisitor classVisitor, final ClassVisitor classVisitor,
final Attribute[] attributePrototypes, final Attribute[] attributePrototypes,
@ -468,8 +460,8 @@ public class ClassReader {
String nestHostClass = null; String nestHostClass = null;
// - The offset of the NestMembers attribute, or 0. // - The offset of the NestMembers attribute, or 0.
int nestMembersOffset = 0; int nestMembersOffset = 0;
// - The offset of the PermittedSubtypes attribute, or 0 // - The offset of the PermittedSubclasses attribute, or 0
int permittedSubtypesOffset = 0; int permittedSubclassesOffset = 0;
// - The offset of the Record attribute, or 0. // - The offset of the Record attribute, or 0.
int recordOffset = 0; int recordOffset = 0;
// - The non standard attributes (linked with their {@link Attribute#nextAttribute} field). // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field).
@ -494,8 +486,8 @@ public class ClassReader {
nestHostClass = readClass(currentAttributeOffset, charBuffer); nestHostClass = readClass(currentAttributeOffset, charBuffer);
} else if (Constants.NEST_MEMBERS.equals(attributeName)) { } else if (Constants.NEST_MEMBERS.equals(attributeName)) {
nestMembersOffset = currentAttributeOffset; nestMembersOffset = currentAttributeOffset;
} else if (Constants.PERMITTED_SUBTYPES.equals(attributeName)) { } else if (Constants.PERMITTED_SUBCLASSES.equals(attributeName)) {
permittedSubtypesOffset = currentAttributeOffset; permittedSubclassesOffset = currentAttributeOffset;
} else if (Constants.SIGNATURE.equals(attributeName)) { } else if (Constants.SIGNATURE.equals(attributeName)) {
signature = readUTF8(currentAttributeOffset, charBuffer); signature = readUTF8(currentAttributeOffset, charBuffer);
} else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) { } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) {
@ -673,14 +665,14 @@ public class ClassReader {
} }
} }
// Visit the PermittedSubtypes attribute. // Visit the PermittedSubclasses attribute.
if (permittedSubtypesOffset != 0) { if (permittedSubclassesOffset != 0) {
int numberOfPermittedSubtypes = readUnsignedShort(permittedSubtypesOffset); int numberOfPermittedSubclasses = readUnsignedShort(permittedSubclassesOffset);
int currentPermittedSubtypeOffset = permittedSubtypesOffset + 2; int currentPermittedSubclassesOffset = permittedSubclassesOffset + 2;
while (numberOfPermittedSubtypes-- > 0) { while (numberOfPermittedSubclasses-- > 0) {
classVisitor.visitPermittedSubtypeExperimental( classVisitor.visitPermittedSubclass(
readClass(currentPermittedSubtypeOffset, charBuffer)); readClass(currentPermittedSubclassesOffset, charBuffer));
currentPermittedSubtypeOffset += 2; currentPermittedSubclassesOffset += 2;
} }
} }

View File

@ -30,7 +30,7 @@ package org.springframework.asm;
/** /**
* A visitor to visit a Java class. The methods of this class must be called in the following order: * A visitor to visit a Java class. The methods of this class must be called in the following order:
* {@code visit} [ {@code visitSource} ] [ {@code visitModule} ][ {@code visitNestHost} ][ {@code * {@code visit} [ {@code visitSource} ] [ {@code visitModule} ][ {@code visitNestHost} ][ {@code
* visitPermittedSubtype} ][ {@code visitOuterClass} ] ( {@code visitAnnotation} | {@code * visitPermittedclass} ][ {@code visitOuterClass} ] ( {@code visitAnnotation} | {@code
* visitTypeAnnotation} | {@code visitAttribute} )* ( {@code visitNestMember} | {@code * visitTypeAnnotation} | {@code visitAttribute} )* ( {@code visitNestMember} | {@code
* visitInnerClass} | {@code visitRecordComponent} | {@code visitField} | {@code visitMethod} )* * visitInnerClass} | {@code visitRecordComponent} | {@code visitField} | {@code visitMethod} )*
* {@code visitEnd}. * {@code visitEnd}.
@ -62,18 +62,19 @@ public abstract class ClassVisitor {
* Constructs a new {@link ClassVisitor}. * Constructs a new {@link ClassVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of {@link * @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link
* Opcodes#ASM8}. * Opcodes#ASM8} or {@link Opcodes#ASM9}.
* @param classVisitor the class visitor to which this visitor must delegate method calls. May be * @param classVisitor the class visitor to which this visitor must delegate method calls. May be
* null. * null.
*/ */
public ClassVisitor(final int api, final ClassVisitor classVisitor) { public ClassVisitor(final int api, final ClassVisitor classVisitor) {
if (api != Opcodes.ASM8 if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7 && api != Opcodes.ASM7
&& api != Opcodes.ASM6 && api != Opcodes.ASM6
&& api != Opcodes.ASM5 && api != Opcodes.ASM5
&& api != Opcodes.ASM4 && api != Opcodes.ASM4
&& api != Opcodes.ASM9_EXPERIMENTAL) { && api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api); throw new IllegalArgumentException("Unsupported api " + api);
} }
// SPRING PATCH: no preview mode check for ASM 9 experimental // SPRING PATCH: no preview mode check for ASM 9 experimental
@ -139,7 +140,7 @@ public abstract class ClassVisitor {
*/ */
public ModuleVisitor visitModule(final String name, final int access, final String version) { public ModuleVisitor visitModule(final String name, final int access, final String version) {
if (api < Opcodes.ASM6) { if (api < Opcodes.ASM6) {
throw new UnsupportedOperationException("This feature requires ASM6"); throw new UnsupportedOperationException("Module requires ASM6");
} }
if (cv != null) { if (cv != null) {
return cv.visitModule(name, access, version); return cv.visitModule(name, access, version);
@ -159,7 +160,7 @@ public abstract class ClassVisitor {
*/ */
public void visitNestHost(final String nestHost) { public void visitNestHost(final String nestHost) {
if (api < Opcodes.ASM7) { if (api < Opcodes.ASM7) {
throw new UnsupportedOperationException("This feature requires ASM7"); throw new UnsupportedOperationException("NestHost requires ASM7");
} }
if (cv != null) { if (cv != null) {
cv.visitNestHost(nestHost); cv.visitNestHost(nestHost);
@ -215,7 +216,7 @@ public abstract class ClassVisitor {
public AnnotationVisitor visitTypeAnnotation( public AnnotationVisitor visitTypeAnnotation(
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
if (api < Opcodes.ASM5) { if (api < Opcodes.ASM5) {
throw new UnsupportedOperationException("This feature requires ASM5"); throw new UnsupportedOperationException("TypeAnnotation requires ASM5");
} }
if (cv != null) { if (cv != null) {
return cv.visitTypeAnnotation(typeRef, typePath, descriptor, visible); return cv.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
@ -245,7 +246,7 @@ public abstract class ClassVisitor {
*/ */
public void visitNestMember(final String nestMember) { public void visitNestMember(final String nestMember) {
if (api < Opcodes.ASM7) { if (api < Opcodes.ASM7) {
throw new UnsupportedOperationException("This feature requires ASM7"); throw new UnsupportedOperationException("NestMember requires ASM7");
} }
if (cv != null) { if (cv != null) {
cv.visitNestMember(nestMember); cv.visitNestMember(nestMember);
@ -253,20 +254,17 @@ public abstract class ClassVisitor {
} }
/** /**
* <b>Experimental, use at your own risk. This method will be renamed when it becomes stable, this * Visits a permitted subclasses. A permitted subclass is one of the allowed subclasses of the
* will break existing code using it</b>. Visits a permitted subtypes. A permitted subtypes is one * current class.
* of the allowed subtypes of the current class.
* *
* @param permittedSubtype the internal name of a permitted subtype. * @param permittedSubclass the internal name of a permitted subclass.
* @deprecated this API is experimental.
*/ */
@Deprecated public void visitPermittedSubclass(final String permittedSubclass) {
public void visitPermittedSubtypeExperimental(final String permittedSubtype) { if (api < Opcodes.ASM9) {
if (api != Opcodes.ASM9_EXPERIMENTAL) { throw new UnsupportedOperationException("PermittedSubclasses requires ASM9");
throw new UnsupportedOperationException("This feature requires ASM9_EXPERIMENTAL");
} }
if (cv != null) { if (cv != null) {
cv.visitPermittedSubtypeExperimental(permittedSubtype); cv.visitPermittedSubclass(permittedSubclass);
} }
} }
@ -302,7 +300,7 @@ public abstract class ClassVisitor {
public RecordComponentVisitor visitRecordComponent( public RecordComponentVisitor visitRecordComponent(
final String name, final String descriptor, final String signature) { final String name, final String descriptor, final String signature) {
if (api < Opcodes.ASM8) { if (api < Opcodes.ASM8) {
throw new UnsupportedOperationException("This feature requires ASM8"); throw new UnsupportedOperationException("Record requires ASM8");
} }
if (cv != null) { if (cv != null) {
return cv.visitRecordComponent(name, descriptor, signature); return cv.visitRecordComponent(name, descriptor, signature);

View File

@ -177,11 +177,11 @@ public class ClassWriter extends ClassVisitor {
/** The 'classes' array of the NestMembers attribute, or {@literal null}. */ /** The 'classes' array of the NestMembers attribute, or {@literal null}. */
private ByteVector nestMemberClasses; private ByteVector nestMemberClasses;
/** The number_of_classes field of the PermittedSubtypes attribute, or 0. */ /** The number_of_classes field of the PermittedSubclasses attribute, or 0. */
private int numberOfPermittedSubtypeClasses; private int numberOfPermittedSubclasses;
/** The 'classes' array of the PermittedSubtypes attribute, or {@literal null}. */ /** The 'classes' array of the PermittedSubclasses attribute, or {@literal null}. */
private ByteVector permittedSubtypeClasses; private ByteVector permittedSubclasses;
/** /**
* The record components of this class, stored in a linked list of {@link RecordComponentWriter} * The record components of this class, stored in a linked list of {@link RecordComponentWriter}
@ -254,7 +254,7 @@ public class ClassWriter extends ClassVisitor {
* maximum stack size nor the stack frames will be computed for these methods</i>. * maximum stack size nor the stack frames will be computed for these methods</i>.
*/ */
public ClassWriter(final ClassReader classReader, final int flags) { public ClassWriter(final ClassReader classReader, final int flags) {
super(/* latest api = */ Opcodes.ASM8); super(/* latest api = */ Opcodes.ASM9);
symbolTable = classReader == null ? new SymbolTable(this) : new SymbolTable(this, classReader); symbolTable = classReader == null ? new SymbolTable(this) : new SymbolTable(this, classReader);
if ((flags & COMPUTE_FRAMES) != 0) { if ((flags & COMPUTE_FRAMES) != 0) {
this.compute = MethodWriter.COMPUTE_ALL_FRAMES; this.compute = MethodWriter.COMPUTE_ALL_FRAMES;
@ -372,20 +372,13 @@ public class ClassWriter extends ClassVisitor {
nestMemberClasses.putShort(symbolTable.addConstantClass(nestMember).index); nestMemberClasses.putShort(symbolTable.addConstantClass(nestMember).index);
} }
/**
* <b>Experimental, use at your own risk.</b>
*
* @param permittedSubtype the internal name of a permitted subtype.
* @deprecated this API is experimental.
*/
@Override @Override
@Deprecated public final void visitPermittedSubclass(final String permittedSubclass) {
public final void visitPermittedSubtypeExperimental(final String permittedSubtype) { if (permittedSubclasses == null) {
if (permittedSubtypeClasses == null) { permittedSubclasses = new ByteVector();
permittedSubtypeClasses = new ByteVector();
} }
++numberOfPermittedSubtypeClasses; ++numberOfPermittedSubclasses;
permittedSubtypeClasses.putShort(symbolTable.addConstantClass(permittedSubtype).index); permittedSubclasses.putShort(symbolTable.addConstantClass(permittedSubclass).index);
} }
@Override @Override
@ -576,10 +569,10 @@ public class ClassWriter extends ClassVisitor {
size += 8 + nestMemberClasses.length; size += 8 + nestMemberClasses.length;
symbolTable.addConstantUtf8(Constants.NEST_MEMBERS); symbolTable.addConstantUtf8(Constants.NEST_MEMBERS);
} }
if (permittedSubtypeClasses != null) { if (permittedSubclasses != null) {
++attributesCount; ++attributesCount;
size += 8 + permittedSubtypeClasses.length; size += 8 + permittedSubclasses.length;
symbolTable.addConstantUtf8(Constants.PERMITTED_SUBTYPES); symbolTable.addConstantUtf8(Constants.PERMITTED_SUBCLASSES);
} }
int recordComponentCount = 0; int recordComponentCount = 0;
int recordSize = 0; int recordSize = 0;
@ -698,12 +691,12 @@ public class ClassWriter extends ClassVisitor {
.putShort(numberOfNestMemberClasses) .putShort(numberOfNestMemberClasses)
.putByteArray(nestMemberClasses.data, 0, nestMemberClasses.length); .putByteArray(nestMemberClasses.data, 0, nestMemberClasses.length);
} }
if (permittedSubtypeClasses != null) { if (permittedSubclasses != null) {
result result
.putShort(symbolTable.addConstantUtf8(Constants.PERMITTED_SUBTYPES)) .putShort(symbolTable.addConstantUtf8(Constants.PERMITTED_SUBCLASSES))
.putInt(permittedSubtypeClasses.length + 2) .putInt(permittedSubclasses.length + 2)
.putShort(numberOfPermittedSubtypeClasses) .putShort(numberOfPermittedSubclasses)
.putByteArray(permittedSubtypeClasses.data, 0, permittedSubtypeClasses.length); .putByteArray(permittedSubclasses.data, 0, permittedSubclasses.length);
} }
if ((accessFlags & Opcodes.ACC_RECORD) != 0 || firstRecordComponent != null) { if ((accessFlags & Opcodes.ACC_RECORD) != 0 || firstRecordComponent != null) {
result result
@ -752,8 +745,8 @@ public class ClassWriter extends ClassVisitor {
nestHostClassIndex = 0; nestHostClassIndex = 0;
numberOfNestMemberClasses = 0; numberOfNestMemberClasses = 0;
nestMemberClasses = null; nestMemberClasses = null;
numberOfPermittedSubtypeClasses = 0; numberOfPermittedSubclasses = 0;
permittedSubtypeClasses = null; permittedSubclasses = null;
firstRecordComponent = null; firstRecordComponent = null;
lastRecordComponent = null; lastRecordComponent = null;
firstAttribute = null; firstAttribute = null;

View File

@ -67,7 +67,7 @@ final class Constants {
static final String MODULE_MAIN_CLASS = "ModuleMainClass"; static final String MODULE_MAIN_CLASS = "ModuleMainClass";
static final String NEST_HOST = "NestHost"; static final String NEST_HOST = "NestHost";
static final String NEST_MEMBERS = "NestMembers"; static final String NEST_MEMBERS = "NestMembers";
static final String PERMITTED_SUBTYPES = "PermittedSubtypes"; static final String PERMITTED_SUBCLASSES = "PermittedSubclasses";
static final String RECORD = "Record"; static final String RECORD = "Record";
// ASM specific access flags. // ASM specific access flags.

View File

@ -38,8 +38,8 @@ public abstract class FieldVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field must be one of {@link * 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}, {@link Opcodes#ASM7} or {@link * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link
* Opcodes#ASM8}. * Opcodes#ASM8} or {@link Opcodes#ASM9}.
*/ */
protected final int api; protected final int api;
@ -50,8 +50,8 @@ public abstract class FieldVisitor {
* Constructs a new {@link FieldVisitor}. * Constructs a new {@link FieldVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of {@link * @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link
* Opcodes#ASM8}. * Opcodes#ASM8} or {@link Opcodes#ASM9}.
*/ */
public FieldVisitor(final int api) { public FieldVisitor(final int api) {
this(api, null); this(api, null);
@ -67,12 +67,13 @@ public abstract class FieldVisitor {
* null. * null.
*/ */
public FieldVisitor(final int api, final FieldVisitor fieldVisitor) { public FieldVisitor(final int api, final FieldVisitor fieldVisitor) {
if (api != Opcodes.ASM8 if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7 && api != Opcodes.ASM7
&& api != Opcodes.ASM6 && api != Opcodes.ASM6
&& api != Opcodes.ASM5 && api != Opcodes.ASM5
&& api != Opcodes.ASM4 && api != Opcodes.ASM4
&& api != Opcodes.ASM9_EXPERIMENTAL) { && api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api); throw new IllegalArgumentException("Unsupported api " + api);
} }
// SPRING PATCH: no preview mode check for ASM 9 experimental // SPRING PATCH: no preview mode check for ASM 9 experimental

View File

@ -124,7 +124,7 @@ final class FieldWriter extends FieldVisitor {
final String descriptor, final String descriptor,
final String signature, final String signature,
final Object constantValue) { final Object constantValue) {
super(/* latest api = */ Opcodes.ASM8); super(/* latest api = */ Opcodes.ASM9);
this.symbolTable = symbolTable; this.symbolTable = symbolTable;
this.accessFlags = access; this.accessFlags = access;
this.nameIndex = symbolTable.addConstantUtf8(name); this.nameIndex = symbolTable.addConstantUtf8(name);

View File

@ -80,12 +80,13 @@ public abstract class MethodVisitor {
* be null. * be null.
*/ */
public MethodVisitor(final int api, final MethodVisitor methodVisitor) { public MethodVisitor(final int api, final MethodVisitor methodVisitor) {
if (api != Opcodes.ASM8 if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7 && api != Opcodes.ASM7
&& api != Opcodes.ASM6 && api != Opcodes.ASM6
&& api != Opcodes.ASM5 && api != Opcodes.ASM5
&& api != Opcodes.ASM4 && api != Opcodes.ASM4
&& api != Opcodes.ASM9_EXPERIMENTAL) { && api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api); throw new IllegalArgumentException("Unsupported api " + api);
} }
// SPRING PATCH: no preview mode check for ASM 9 experimental // SPRING PATCH: no preview mode check for ASM 9 experimental

View File

@ -592,7 +592,7 @@ final class MethodWriter extends MethodVisitor {
final String signature, final String signature,
final String[] exceptions, final String[] exceptions,
final int compute) { final int compute) {
super(/* latest api = */ Opcodes.ASM8); super(/* latest api = */ Opcodes.ASM9);
this.symbolTable = symbolTable; this.symbolTable = symbolTable;
this.accessFlags = "<init>".equals(name) ? access | Constants.ACC_CONSTRUCTOR : access; this.accessFlags = "<init>".equals(name) ? access | Constants.ACC_CONSTRUCTOR : access;
this.nameIndex = symbolTable.addConstantUtf8(name); this.nameIndex = symbolTable.addConstantUtf8(name);

View File

@ -66,12 +66,13 @@ public abstract class ModuleVisitor {
* be null. * be null.
*/ */
public ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) { public ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) {
if (api != Opcodes.ASM8 if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7 && api != Opcodes.ASM7
&& api != Opcodes.ASM6 && api != Opcodes.ASM6
&& api != Opcodes.ASM5 && api != Opcodes.ASM5
&& api != Opcodes.ASM4 && api != Opcodes.ASM4
&& api != Opcodes.ASM9_EXPERIMENTAL) { && api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api); throw new IllegalArgumentException("Unsupported api " + api);
} }
// SPRING PATCH: no preview mode check for ASM 9 experimental // SPRING PATCH: no preview mode check for ASM 9 experimental

View File

@ -94,7 +94,7 @@ final class ModuleWriter extends ModuleVisitor {
private int mainClassIndex; private int mainClassIndex;
ModuleWriter(final SymbolTable symbolTable, final int name, final int access, final int version) { ModuleWriter(final SymbolTable symbolTable, final int name, final int access, final int version) {
super(/* latest api = */ Opcodes.ASM8); super(/* latest api = */ Opcodes.ASM9);
this.symbolTable = symbolTable; this.symbolTable = symbolTable;
this.moduleNameIndex = name; this.moduleNameIndex = name;
this.moduleFlags = access; this.moduleFlags = access;

View File

@ -48,13 +48,14 @@ public interface Opcodes {
int ASM6 = 6 << 16 | 0 << 8; int ASM6 = 6 << 16 | 0 << 8;
int ASM7 = 7 << 16 | 0 << 8; int ASM7 = 7 << 16 | 0 << 8;
int ASM8 = 8 << 16 | 0 << 8; int ASM8 = 8 << 16 | 0 << 8;
int ASM9 = 9 << 16 | 0 << 8;
/** /**
* <i>Experimental, use at your own risk. This field will be renamed when it becomes stable, this * <i>Experimental, use at your own risk. This field will be renamed when it becomes stable, this
* will break existing code using it. Only code compiled with --enable-preview can use this.</i> * will break existing code using it. Only code compiled with --enable-preview can use this.</i>
* <p>SPRING PATCH: no preview mode check for ASM 9 experimental, enabling it by default. * <p>SPRING PATCH: no preview mode check for ASM 9 experimental, enabling it by default.
*/ */
int ASM9_EXPERIMENTAL = 1 << 24 | 9 << 16 | 0 << 8; int ASM10_EXPERIMENTAL = 1 << 24 | 10 << 16 | 0 << 8;
/* /*
* Internal flags used to redirect calls to deprecated methods. For instance, if a visitOldStuff * Internal flags used to redirect calls to deprecated methods. For instance, if a visitOldStuff
@ -279,6 +280,7 @@ public interface Opcodes {
int V13 = 0 << 16 | 57; int V13 = 0 << 16 | 57;
int V14 = 0 << 16 | 58; int V14 = 0 << 16 | 58;
int V15 = 0 << 16 | 59; int V15 = 0 << 16 | 59;
int V16 = 0 << 16 | 60;
/** /**
* Version flag indicating that the class is using 'preview' features. * Version flag indicating that the class is using 'preview' features.

View File

@ -37,8 +37,8 @@ package org.springframework.asm;
*/ */
public abstract class RecordComponentVisitor { public abstract class RecordComponentVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field must be {@link * The ASM API version implemented by this visitor. The value of this field must be one of {@link
* Opcodes#ASM8}. * Opcodes#ASM8} or {@link Opcodes#ASM9}.
*/ */
protected final int api; protected final int api;
@ -50,7 +50,8 @@ public abstract class RecordComponentVisitor {
/** /**
* Constructs a new {@link RecordComponentVisitor}. * Constructs a new {@link RecordComponentVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM8}. * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM8}
* or {@link Opcodes#ASM9}.
*/ */
public RecordComponentVisitor(final int api) { public RecordComponentVisitor(final int api) {
this(api, null); this(api, null);
@ -65,12 +66,13 @@ public abstract class RecordComponentVisitor {
*/ */
public RecordComponentVisitor( public RecordComponentVisitor(
final int api, final RecordComponentVisitor recordComponentVisitor) { final int api, final RecordComponentVisitor recordComponentVisitor) {
if (api != Opcodes.ASM8 if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7 && api != Opcodes.ASM7
&& api != Opcodes.ASM6 && api != Opcodes.ASM6
&& api != Opcodes.ASM5 && api != Opcodes.ASM5
&& api != Opcodes.ASM4 && api != Opcodes.ASM4
&& api != Opcodes.ASM9_EXPERIMENTAL) { && api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api); throw new IllegalArgumentException("Unsupported api " + api);
} }
// SPRING PATCH: no preview mode check for ASM 9 experimental // SPRING PATCH: no preview mode check for ASM 9 experimental

View File

@ -94,7 +94,7 @@ final class RecordComponentWriter extends RecordComponentVisitor {
final String name, final String name,
final String descriptor, final String descriptor,
final String signature) { final String signature) {
super(/* latest api = */ Opcodes.ASM8); super(/* latest api = */ Opcodes.ASM9);
this.symbolTable = symbolTable; this.symbolTable = symbolTable;
this.nameIndex = symbolTable.addConstantUtf8(name); this.nameIndex = symbolTable.addConstantUtf8(name);
this.descriptorIndex = symbolTable.addConstantUtf8(descriptor); this.descriptorIndex = symbolTable.addConstantUtf8(descriptor);

View File

@ -18,7 +18,7 @@ package org.springframework.asm;
/** /**
* Utility class exposing constants related to Spring's internal repackaging * Utility class exposing constants related to Spring's internal repackaging
* of the ASM bytecode library: currently based on ASM 8.x plus minor patches. * of the ASM bytecode library: currently based on ASM 9.0 plus minor patches.
* *
* <p>See <a href="package-summary.html">package-level javadocs</a> for more * <p>See <a href="package-summary.html">package-level javadocs</a> for more
* information on {@code org.springframework.asm}. * information on {@code org.springframework.asm}.
@ -31,8 +31,8 @@ public final class SpringAsmInfo {
/** /**
* The ASM compatibility version for Spring's ASM visitor implementations: * The ASM compatibility version for Spring's ASM visitor implementations:
* currently {@link Opcodes#ASM9_EXPERIMENTAL}, as of Spring Framework 5.3. * currently {@link Opcodes#ASM10_EXPERIMENTAL}, as of Spring Framework 5.3.
*/ */
public static final int ASM_VERSION = Opcodes.ASM9_EXPERIMENTAL; public static final int ASM_VERSION = Opcodes.ASM10_EXPERIMENTAL;
} }

View File

@ -1,6 +1,6 @@
/** /**
* Spring's repackaging of * Spring's repackaging of
* <a href="https://gitlab.ow2.org/asm/asm">ASM 8.1</a> * <a href="https://gitlab.ow2.org/asm/asm">ASM 9.0</a>
* (with Spring-specific patches; for internal use only). * (with Spring-specific patches; for internal use only).
* *
* <p>This repackaging technique avoids any potential conflicts with * <p>This repackaging technique avoids any potential conflicts with