Skip to content

Commit

Permalink
Upgrade to ASM 9.0 beta
Browse files Browse the repository at this point in the history
  • Loading branch information
jhoeller committed Jul 7, 2020
1 parent 8e02d27 commit a1bab14
Show file tree
Hide file tree
Showing 17 changed files with 89 additions and 98 deletions.
Expand Up @@ -68,12 +68,13 @@ public AnnotationVisitor(final int api) {
* calls. May be {@literal null}.
*/
public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) {
if (api != Opcodes.ASM8
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7
&& api != Opcodes.ASM6
&& api != Opcodes.ASM5
&& api != Opcodes.ASM4
&& api != Opcodes.ASM9_EXPERIMENTAL) {
&& api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api);
}
// SPRING PATCH: no preview mode check for ASM 9 experimental
Expand Down
Expand Up @@ -112,7 +112,7 @@ final class AnnotationWriter extends AnnotationVisitor {
final boolean useNamedValues,
final ByteVector annotation,
final AnnotationWriter previousAnnotation) {
super(/* latest api = */ Opcodes.ASM8);
super(/* latest api = */ Opcodes.ASM9);
this.symbolTable = symbolTable;
this.useNamedValues = useNamedValues;
this.annotation = annotation;
Expand Down
38 changes: 15 additions & 23 deletions spring-core/src/main/java/org/springframework/asm/ClassReader.java
Expand Up @@ -100,7 +100,8 @@ public class ClassReader {
@Deprecated
// DontCheck(MemberName): can't be renamed (for backward binary compatibility).
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
* must not be modified. This field is intended for {@link Attribute} sub classes, and is normally
Expand All @@ -111,27 +112,23 @@ public class ClassReader {
* ClassFile element offsets within this byte array.
*/
final byte[] classFileBuffer;

/**
* 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
* given by cpInfoOffsets[i] - 1, i.e. its cp_info's tag field is given by b[cpInfoOffsets[i] -
* 1].
*/
private final int[] cpInfoOffsets;

/**
* The String objects corresponding to the CONSTANT_Utf8 constant pool items. This cache avoids
* multiple parsing of a given CONSTANT_Utf8 constant pool item.
*/
private final String[] constantUtf8Values;

/**
* The ConstantDynamic objects corresponding to the CONSTANT_Dynamic constant pool items. This
* cache avoids multiple parsing of a given CONSTANT_Dynamic constant pool item.
*/
private final ConstantDynamic[] constantDynamicValues;

/**
* The start offsets in {@link #classFileBuffer} of each element of the bootstrap_methods array
* (in the BootstrapMethods attribute).
Expand All @@ -140,16 +137,12 @@ public class ClassReader {
* 4.7.23</a>
*/
private final int[] bootstrapMethodOffsets;

/**
* A conservative estimate of the maximum length of the strings contained in the constant pool of
* the class.
*/
private final int maxStringLength;

/** The offset in bytes of the ClassFile's access_flags field. */
public final int header;

// -----------------------------------------------------------------------------------------------
// Constructors
// -----------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -191,7 +184,7 @@ public ClassReader(
this.b = classFileBuffer;
// Check the class' major_version. This field is after the magic and minor_version fields, which
// use 4 and 2 bytes respectively.
if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V15) {
if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V16) {
throw new IllegalArgumentException(
"Unsupported class file major version " + readShort(classFileOffset + 6));
}
Expand Down Expand Up @@ -415,7 +408,6 @@ public void accept(final ClassVisitor classVisitor, final int parsingOptions) {
* @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}.
*/
@SuppressWarnings("deprecation") // for visitPermittedSubtypeExperimental
public void accept(
final ClassVisitor classVisitor,
final Attribute[] attributePrototypes,
Expand Down Expand Up @@ -468,8 +460,8 @@ public void accept(
String nestHostClass = null;
// - The offset of the NestMembers attribute, or 0.
int nestMembersOffset = 0;
// - The offset of the PermittedSubtypes attribute, or 0
int permittedSubtypesOffset = 0;
// - The offset of the PermittedSubclasses attribute, or 0
int permittedSubclassesOffset = 0;
// - The offset of the Record attribute, or 0.
int recordOffset = 0;
// - The non standard attributes (linked with their {@link Attribute#nextAttribute} field).
Expand All @@ -494,8 +486,8 @@ public void accept(
nestHostClass = readClass(currentAttributeOffset, charBuffer);
} else if (Constants.NEST_MEMBERS.equals(attributeName)) {
nestMembersOffset = currentAttributeOffset;
} else if (Constants.PERMITTED_SUBTYPES.equals(attributeName)) {
permittedSubtypesOffset = currentAttributeOffset;
} else if (Constants.PERMITTED_SUBCLASSES.equals(attributeName)) {
permittedSubclassesOffset = currentAttributeOffset;
} else if (Constants.SIGNATURE.equals(attributeName)) {
signature = readUTF8(currentAttributeOffset, charBuffer);
} else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) {
Expand Down Expand Up @@ -673,14 +665,14 @@ public void accept(
}
}

// Visit the PermittedSubtypes attribute.
if (permittedSubtypesOffset != 0) {
int numberOfPermittedSubtypes = readUnsignedShort(permittedSubtypesOffset);
int currentPermittedSubtypeOffset = permittedSubtypesOffset + 2;
while (numberOfPermittedSubtypes-- > 0) {
classVisitor.visitPermittedSubtypeExperimental(
readClass(currentPermittedSubtypeOffset, charBuffer));
currentPermittedSubtypeOffset += 2;
// Visit the PermittedSubclasses attribute.
if (permittedSubclassesOffset != 0) {
int numberOfPermittedSubclasses = readUnsignedShort(permittedSubclassesOffset);
int currentPermittedSubclassesOffset = permittedSubclassesOffset + 2;
while (numberOfPermittedSubclasses-- > 0) {
classVisitor.visitPermittedSubclass(
readClass(currentPermittedSubclassesOffset, charBuffer));
currentPermittedSubclassesOffset += 2;
}
}

Expand Down
38 changes: 18 additions & 20 deletions spring-core/src/main/java/org/springframework/asm/ClassVisitor.java
Expand Up @@ -30,7 +30,7 @@
/**
* 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
* visitPermittedSubtype} ][ {@code visitOuterClass} ] ( {@code visitAnnotation} | {@code
* visitPermittedclass} ][ {@code visitOuterClass} ] ( {@code visitAnnotation} | {@code
* visitTypeAnnotation} | {@code visitAttribute} )* ( {@code visitNestMember} | {@code
* visitInnerClass} | {@code visitRecordComponent} | {@code visitField} | {@code visitMethod} )*
* {@code visitEnd}.
Expand Down Expand Up @@ -62,18 +62,19 @@ public ClassVisitor(final int api) {
* 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}, {@link Opcodes#ASM7} or {@link
* Opcodes#ASM8}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link
* Opcodes#ASM8} or {@link Opcodes#ASM9}.
* @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.ASM8
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7
&& api != Opcodes.ASM6
&& api != Opcodes.ASM5
&& api != Opcodes.ASM4
&& api != Opcodes.ASM9_EXPERIMENTAL) {
&& api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api);
}
// SPRING PATCH: no preview mode check for ASM 9 experimental
Expand Down Expand Up @@ -139,7 +140,7 @@ public void visitSource(final String source, final String debug) {
*/
public ModuleVisitor visitModule(final String name, final int access, final String version) {
if (api < Opcodes.ASM6) {
throw new UnsupportedOperationException("This feature requires ASM6");
throw new UnsupportedOperationException("Module requires ASM6");
}
if (cv != null) {
return cv.visitModule(name, access, version);
Expand All @@ -159,7 +160,7 @@ public ModuleVisitor visitModule(final String name, final int access, final Stri
*/
public void visitNestHost(final String nestHost) {
if (api < Opcodes.ASM7) {
throw new UnsupportedOperationException("This feature requires ASM7");
throw new UnsupportedOperationException("NestHost requires ASM7");
}
if (cv != null) {
cv.visitNestHost(nestHost);
Expand Down Expand Up @@ -215,7 +216,7 @@ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean
public AnnotationVisitor visitTypeAnnotation(
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
if (api < Opcodes.ASM5) {
throw new UnsupportedOperationException("This feature requires ASM5");
throw new UnsupportedOperationException("TypeAnnotation requires ASM5");
}
if (cv != null) {
return cv.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
Expand Down Expand Up @@ -245,28 +246,25 @@ public void visitAttribute(final Attribute attribute) {
*/
public void visitNestMember(final String nestMember) {
if (api < Opcodes.ASM7) {
throw new UnsupportedOperationException("This feature requires ASM7");
throw new UnsupportedOperationException("NestMember requires ASM7");
}
if (cv != null) {
cv.visitNestMember(nestMember);
}
}

/**
* <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 permitted subtypes. A permitted subtypes is one
* of the allowed subtypes of the current class.
* Visits a permitted subclasses. A permitted subclass is one of the allowed subclasses of the
* current class.
*
* @param permittedSubtype the internal name of a permitted subtype.
* @deprecated this API is experimental.
* @param permittedSubclass the internal name of a permitted subclass.
*/
@Deprecated
public void visitPermittedSubtypeExperimental(final String permittedSubtype) {
if (api != Opcodes.ASM9_EXPERIMENTAL) {
throw new UnsupportedOperationException("This feature requires ASM9_EXPERIMENTAL");
public void visitPermittedSubclass(final String permittedSubclass) {
if (api < Opcodes.ASM9) {
throw new UnsupportedOperationException("PermittedSubclasses requires ASM9");
}
if (cv != null) {
cv.visitPermittedSubtypeExperimental(permittedSubtype);
cv.visitPermittedSubclass(permittedSubclass);
}
}

Expand Down Expand Up @@ -302,7 +300,7 @@ public void visitInnerClass(
public RecordComponentVisitor visitRecordComponent(
final String name, final String descriptor, final String signature) {
if (api < Opcodes.ASM8) {
throw new UnsupportedOperationException("This feature requires ASM8");
throw new UnsupportedOperationException("Record requires ASM8");
}
if (cv != null) {
return cv.visitRecordComponent(name, descriptor, signature);
Expand Down
47 changes: 20 additions & 27 deletions spring-core/src/main/java/org/springframework/asm/ClassWriter.java
Expand Up @@ -177,11 +177,11 @@ public class ClassWriter extends ClassVisitor {
/** The 'classes' array of the NestMembers attribute, or {@literal null}. */
private ByteVector nestMemberClasses;

/** The number_of_classes field of the PermittedSubtypes attribute, or 0. */
private int numberOfPermittedSubtypeClasses;
/** The number_of_classes field of the PermittedSubclasses attribute, or 0. */
private int numberOfPermittedSubclasses;

/** The 'classes' array of the PermittedSubtypes attribute, or {@literal null}. */
private ByteVector permittedSubtypeClasses;
/** The 'classes' array of the PermittedSubclasses attribute, or {@literal null}. */
private ByteVector permittedSubclasses;

/**
* The record components of this class, stored in a linked list of {@link RecordComponentWriter}
Expand Down Expand Up @@ -254,7 +254,7 @@ public ClassWriter(final int flags) {
* maximum stack size nor the stack frames will be computed for these methods</i>.
*/
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);
if ((flags & COMPUTE_FRAMES) != 0) {
this.compute = MethodWriter.COMPUTE_ALL_FRAMES;
Expand Down Expand Up @@ -372,20 +372,13 @@ public final void visitNestMember(final String nestMember) {
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
@Deprecated
public final void visitPermittedSubtypeExperimental(final String permittedSubtype) {
if (permittedSubtypeClasses == null) {
permittedSubtypeClasses = new ByteVector();
public final void visitPermittedSubclass(final String permittedSubclass) {
if (permittedSubclasses == null) {
permittedSubclasses = new ByteVector();
}
++numberOfPermittedSubtypeClasses;
permittedSubtypeClasses.putShort(symbolTable.addConstantClass(permittedSubtype).index);
++numberOfPermittedSubclasses;
permittedSubclasses.putShort(symbolTable.addConstantClass(permittedSubclass).index);
}

@Override
Expand Down Expand Up @@ -576,10 +569,10 @@ public byte[] toByteArray() {
size += 8 + nestMemberClasses.length;
symbolTable.addConstantUtf8(Constants.NEST_MEMBERS);
}
if (permittedSubtypeClasses != null) {
if (permittedSubclasses != null) {
++attributesCount;
size += 8 + permittedSubtypeClasses.length;
symbolTable.addConstantUtf8(Constants.PERMITTED_SUBTYPES);
size += 8 + permittedSubclasses.length;
symbolTable.addConstantUtf8(Constants.PERMITTED_SUBCLASSES);
}
int recordComponentCount = 0;
int recordSize = 0;
Expand Down Expand Up @@ -698,12 +691,12 @@ public byte[] toByteArray() {
.putShort(numberOfNestMemberClasses)
.putByteArray(nestMemberClasses.data, 0, nestMemberClasses.length);
}
if (permittedSubtypeClasses != null) {
if (permittedSubclasses != null) {
result
.putShort(symbolTable.addConstantUtf8(Constants.PERMITTED_SUBTYPES))
.putInt(permittedSubtypeClasses.length + 2)
.putShort(numberOfPermittedSubtypeClasses)
.putByteArray(permittedSubtypeClasses.data, 0, permittedSubtypeClasses.length);
.putShort(symbolTable.addConstantUtf8(Constants.PERMITTED_SUBCLASSES))
.putInt(permittedSubclasses.length + 2)
.putShort(numberOfPermittedSubclasses)
.putByteArray(permittedSubclasses.data, 0, permittedSubclasses.length);
}
if ((accessFlags & Opcodes.ACC_RECORD) != 0 || firstRecordComponent != null) {
result
Expand Down Expand Up @@ -752,8 +745,8 @@ private byte[] replaceAsmInstructions(final byte[] classFile, final boolean hasF
nestHostClassIndex = 0;
numberOfNestMemberClasses = 0;
nestMemberClasses = null;
numberOfPermittedSubtypeClasses = 0;
permittedSubtypeClasses = null;
numberOfPermittedSubclasses = 0;
permittedSubclasses = null;
firstRecordComponent = null;
lastRecordComponent = null;
firstAttribute = null;
Expand Down
Expand Up @@ -67,7 +67,7 @@ final class Constants {
static final String MODULE_MAIN_CLASS = "ModuleMainClass";
static final String NEST_HOST = "NestHost";
static final String NEST_MEMBERS = "NestMembers";
static final String PERMITTED_SUBTYPES = "PermittedSubtypes";
static final String PERMITTED_SUBCLASSES = "PermittedSubclasses";
static final String RECORD = "Record";

// ASM specific access flags.
Expand Down
Expand Up @@ -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
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link
* Opcodes#ASM8}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link
* Opcodes#ASM8} or {@link Opcodes#ASM9}.
*/
protected final int api;

Expand All @@ -50,8 +50,8 @@ 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}, {@link Opcodes#ASM7} or {@link
* Opcodes#ASM8}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link
* Opcodes#ASM8} or {@link Opcodes#ASM9}.
*/
public FieldVisitor(final int api) {
this(api, null);
Expand All @@ -67,12 +67,13 @@ public FieldVisitor(final int api) {
* null.
*/
public FieldVisitor(final int api, final FieldVisitor fieldVisitor) {
if (api != Opcodes.ASM8
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7
&& api != Opcodes.ASM6
&& api != Opcodes.ASM5
&& api != Opcodes.ASM4
&& api != Opcodes.ASM9_EXPERIMENTAL) {
&& api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api);
}
// SPRING PATCH: no preview mode check for ASM 9 experimental
Expand Down
Expand Up @@ -124,7 +124,7 @@ final class FieldWriter extends FieldVisitor {
final String descriptor,
final String signature,
final Object constantValue) {
super(/* latest api = */ Opcodes.ASM8);
super(/* latest api = */ Opcodes.ASM9);
this.symbolTable = symbolTable;
this.accessFlags = access;
this.nameIndex = symbolTable.addConstantUtf8(name);
Expand Down

0 comments on commit a1bab14

Please sign in to comment.