Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adopt ASM 9.7.1 (JDK 24) #5760

Merged
merged 1 commit into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion NOTICE.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ KineticJS, v4.7.1
* Project: http://www.kineticjs.com, https://github.com/ericdrowell/KineticJS
* Copyright: Eric Rowell

org.objectweb.asm Version 9.7
org.objectweb.asm Version 9.7.1
* License: Modified BSD (https://asm.ow2.io/license.html)
* Copyright (c) 2000-2011 INRIA, France Telecom. All rights reserved.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ public class Attribute {
public final String type;

/**
* The raw content of this attribute, only used for unknown attributes (see {@link #isUnknown()}).
* The 6 header bytes of the attribute (attribute_name_index and attribute_length) are <i>not</i>
* included.
* The raw content of this attribute, as returned by {@link
* #write(ClassWriter,byte[],int,int,int)}. The 6 header bytes of the attribute
* (attribute_name_index and attribute_length) are <i>not</i> included.
*/
private byte[] content;
private ByteVector cachedContent;

/**
* The next attribute in this attribute list (Attribute instances can be linked via this field to
Expand Down Expand Up @@ -93,7 +93,9 @@ public boolean isCodeAttribute() {
*
* @return the labels corresponding to this attribute, or {@literal null} if this attribute is not
* a Code attribute that contains labels.
* @deprecated no longer used by ASM.
*/
@Deprecated
protected Label[] getLabels() {
return new Label[0];
}
Expand All @@ -115,7 +117,9 @@ protected Label[] getLabels() {
* 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 {@literal null} if the attribute to be read
* is not a Code attribute.
* is not a Code attribute. Labels defined in the attribute must be created and added to this
* array, if not already present, by calling the {@link #readLabel} method (do not create
* {@link Label} instances directly).
* @return a <i>new</i> {@link Attribute} object corresponding to the specified bytes.
*/
protected Attribute read(
Expand All @@ -126,16 +130,99 @@ protected Attribute read(
final int codeAttributeOffset,
final Label[] labels) {
Attribute attribute = new Attribute(type);
attribute.content = new byte[length];
System.arraycopy(classReader.classFileBuffer, offset, attribute.content, 0, length);
attribute.cachedContent = new ByteVector(classReader.readBytes(offset, length));
return attribute;
}

/**
* Reads an attribute with the same {@link #type} as the given attribute. This method returns a
* new {@link Attribute} object, corresponding to the 'length' bytes starting at 'offset', in the
* given ClassReader.
*
* @param attribute The attribute prototype that is used for reading.
* @param classReader the class that contains the attribute to be read.
* @param offset index of the first byte of the attribute's content in {@link ClassReader}. The 6
* attribute header bytes (attribute_name_index and attribute_length) are not taken into
* account here.
* @param length the length of the attribute's content (excluding the 6 attribute header bytes).
* @param charBuffer the buffer to be used to call the ClassReader methods requiring a
* 'charBuffer' parameter.
* @param codeAttributeOffset index of the first byte of content of the enclosing Code attribute
* in {@link ClassReader}, 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 {@literal null} if the attribute to be read
* is not a Code attribute. Labels defined in the attribute are added to this array, if not
* already present.
* @return a new {@link Attribute} object corresponding to the specified bytes.
*/
public static Attribute read(
final Attribute attribute,
final ClassReader classReader,
final int offset,
final int length,
final char[] charBuffer,
final int codeAttributeOffset,
final Label[] labels) {
return attribute.read(classReader, offset, length, charBuffer, codeAttributeOffset, labels);
}

/**
* Returns the label corresponding to the given bytecode offset by calling {@link
* ClassReader#readLabel}. This creates and adds the label to the given array if it is not already
* present. Note that this created label may be a {@link Label} subclass instance, if the given
* ClassReader overrides {@link ClassReader#readLabel}. Hence {@link #read(ClassReader, int, int,
* char[], int, Label[])} must not manually create {@link Label} instances.
*
* @param bytecodeOffset a bytecode offset in a method.
* @param labels the already created labels, indexed by their offset. If a label already exists
* for bytecodeOffset this method does not create a new one. Otherwise it stores the new label
* in this array.
* @return a label for the given bytecode offset.
*/
public static Label readLabel(
final ClassReader classReader, final int bytecodeOffset, final Label[] labels) {
return classReader.readLabel(bytecodeOffset, labels);
}

/**
* Calls {@link #write(ClassWriter,byte[],int,int,int)} if it has not already been called and
* returns its result or its (cached) previous result.
*
* @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 {@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
* attribute, or 0 if this attribute is not a Code attribute. Corresponds to the 'code_length'
* field of the Code attribute.
* @param maxStack the maximum stack size of the method corresponding to this Code attribute, or
* -1 if this attribute is not a Code attribute.
* @param maxLocals the maximum number of local variables of the method corresponding to this code
* attribute, or -1 if this attribute is not a Code attribute.
* @return the byte array form of this attribute.
*/
private ByteVector maybeWrite(
final ClassWriter classWriter,
final byte[] code,
final int codeLength,
final int maxStack,
final int maxLocals) {
if (cachedContent == null) {
cachedContent = write(classWriter, code, codeLength, maxStack, maxLocals);
}
return cachedContent;
}

/**
* Returns the byte array form of the content of this attribute. The 6 header bytes
* (attribute_name_index and attribute_length) must <i>not</i> be added in the returned
* ByteVector.
*
* <p>This method is only invoked once to compute the binary form of this attribute. Subsequent
* changes to the attribute after it was written for the first time will not be considered.
*
* @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 {@literal null}
Expand All @@ -156,7 +243,39 @@ protected ByteVector write(
final int codeLength,
final int maxStack,
final int maxLocals) {
return new ByteVector(content);
return cachedContent;
}

/**
* Returns the byte array form of the content of the given attribute. The 6 header bytes
* (attribute_name_index and attribute_length) are <i>not</i> added in the returned byte array.
*
* @param attribute The attribute that should be written.
* @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 {@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
* attribute, or 0 if this attribute is not a Code attribute. Corresponds to the 'code_length'
* field of the Code attribute.
* @param maxStack the maximum stack size of the method corresponding to this Code attribute, or
* -1 if this attribute is not a Code attribute.
* @param maxLocals the maximum number of local variables of the method corresponding to this code
* attribute, or -1 if this attribute is not a Code attribute.
* @return the byte array form of this attribute.
*/
public static byte[] write(
final Attribute attribute,
final ClassWriter classWriter,
final byte[] code,
final int codeLength,
final int maxStack,
final int maxLocals) {
ByteVector content = attribute.maybeWrite(classWriter, code, codeLength, maxStack, maxLocals);
byte[] result = new byte[content.length];
System.arraycopy(content.data, 0, result, 0, content.length);
return result;
}

/**
Expand Down Expand Up @@ -221,7 +340,7 @@ final int computeAttributesSize(
Attribute attribute = this;
while (attribute != null) {
symbolTable.addConstantUtf8(attribute.type);
size += 6 + attribute.write(classWriter, code, codeLength, maxStack, maxLocals).length;
size += 6 + attribute.maybeWrite(classWriter, code, codeLength, maxStack, maxLocals).length;
attribute = attribute.nextAttribute;
}
return size;
Expand Down Expand Up @@ -308,7 +427,7 @@ final void putAttributes(
Attribute attribute = this;
while (attribute != null) {
ByteVector attributeContent =
attribute.write(classWriter, code, codeLength, maxStack, maxLocals);
attribute.maybeWrite(classWriter, code, codeLength, maxStack, maxLocals);
// Put attribute_name_index and attribute_length.
output.putShort(symbolTable.addConstantUtf8(attribute.type)).putInt(attributeContent.length);
output.putByteArray(attributeContent.data, 0, attributeContent.length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,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.V23) {
if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V24) {
throw new IllegalArgumentException(
"Unsupported class file major version " + readShort(classFileOffset + 6));
}
Expand Down Expand Up @@ -3597,6 +3597,20 @@ public int readByte(final int offset) {
return classFileBuffer[offset] & 0xFF;
}

/**
* Reads several bytes in this {@link ClassReader}. <i>This method is intended for {@link
* Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
*
* @param offset the start offset of the bytes to be read in this {@link ClassReader}.
* @param length the number of bytes to read.
* @return the read bytes.
*/
public byte[] readBytes(final int offset, final int length) {
byte[] result = new byte[length];
System.arraycopy(classFileBuffer, offset, result, 0, length);
return result;
}

/**
* Reads an unsigned short value in this {@link ClassReader}. <i>This method is intended for
* {@link Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,7 @@ public ClassWriter(final ClassReader classReader, final int flags) {
super(/* latest api = */ Opcodes.ASM9);
this.flags = flags;
symbolTable = classReader == null ? new SymbolTable(this) : new SymbolTable(this, classReader);
if ((flags & COMPUTE_FRAMES) != 0) {
compute = MethodWriter.COMPUTE_ALL_FRAMES;
} else if ((flags & COMPUTE_MAXS) != 0) {
compute = MethodWriter.COMPUTE_MAX_STACK_AND_LOCAL;
} else {
compute = MethodWriter.COMPUTE_NOTHING;
}
setFlags(flags);
}

// -----------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1020,6 +1014,28 @@ public int newNameType(final String name, final String descriptor) {
return symbolTable.addConstantNameAndType(name, descriptor);
}

/**
* Changes the computation strategy of method properties like max stack size, max number of local
* variables, and frames.
*
* <p><b>WARNING</b>: {@link #setFlags(int)} method changes the behavior of new method visitors
* returned from {@link #visitMethod(int, String, String, String, String[])}. The behavior will be
* changed only after the next method visitor is returned. All the previously returned method
* visitors keep their previous behavior.
*
* @param flags option flags that can be used to modify the default behavior of this class. Must
* be zero or more of {@link #COMPUTE_MAXS} and {@link #COMPUTE_FRAMES}.
*/
public final void setFlags(final int flags) {
if ((flags & ClassWriter.COMPUTE_FRAMES) != 0) {
compute = MethodWriter.COMPUTE_ALL_FRAMES;
} else if ((flags & ClassWriter.COMPUTE_MAXS) != 0) {
compute = MethodWriter.COMPUTE_MAX_STACK_AND_LOCAL;
} else {
compute = MethodWriter.COMPUTE_NOTHING;
}
}

// -----------------------------------------------------------------------------------------------
// Default method to compute common super classes when computing stack map frames
// -----------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ static void checkIsPreview(final InputStream classInputStream) {
}
if (minorVersion != 0xFFFF) {
throw new IllegalStateException(
"ASM9_EXPERIMENTAL can only be used by classes compiled with --enable-preview");
"ASM10_EXPERIMENTAL can only be used by classes compiled with --enable-preview");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@
* 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.
* visitLocalVariableAnnotation} | {@code visitLineNumber} | {@code visitAttribute} )* {@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. Finally, the {@code visitAttribute} method must be
* called before {@code visitCode} for non-code attributes, and after it for code attributes.
*
* @author Eric Bruneton
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1519,14 +1519,14 @@ public AnnotationVisitor visitLocalVariableAnnotation(
return lastCodeRuntimeVisibleTypeAnnotation =
new AnnotationWriter(
symbolTable,
/* useNamedValues = */ true,
/* useNamedValues= */ true,
typeAnnotation,
lastCodeRuntimeVisibleTypeAnnotation);
} else {
return lastCodeRuntimeInvisibleTypeAnnotation =
new AnnotationWriter(
symbolTable,
/* useNamedValues = */ true,
/* useNamedValues= */ true,
typeAnnotation,
lastCodeRuntimeInvisibleTypeAnnotation);
}
Expand Down Expand Up @@ -1642,7 +1642,7 @@ private void computeAllFrames() {
code.data[endOffset] = (byte) Opcodes.ATHROW;
// Emit a frame for this unreachable block, with no local and a Throwable on the stack
// (so that the ATHROW could consume this Throwable if it were reachable).
int frameIndex = visitFrameStart(startOffset, /* numLocal = */ 0, /* numStack = */ 1);
int frameIndex = visitFrameStart(startOffset, /* numLocal= */ 0, /* numStack= */ 1);
currentFrame[frameIndex] =
Frame.getAbstractTypeFromInternalName(symbolTable, "java/lang/Throwable");
visitFrameEnd();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ public interface Opcodes {
int V21 = 0 << 16 | 65;
int V22 = 0 << 16 | 66;
int V23 = 0 << 16 | 67;
int V24 = 0 << 16 | 68;

/**
* Version flag indicating that the class is using 'preview' features.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,9 @@ abstract class Symbol {
* <li>the symbol's value for {@link #CONSTANT_INTEGER_TAG},{@link #CONSTANT_FLOAT_TAG}, {@link
* #CONSTANT_LONG_TAG}, {@link #CONSTANT_DOUBLE_TAG},
* <li>the CONSTANT_MethodHandle_info reference_kind field value for {@link
* #CONSTANT_METHOD_HANDLE_TAG} symbols,
* #CONSTANT_METHOD_HANDLE_TAG} symbols (or this value left shifted by 8 bits for
* reference_kind values larger than or equal to H_INVOKEVIRTUAL and if the method owner is
* an interface),
* <li>the CONSTANT_InvokeDynamic_info bootstrap_method_attr_index field value for {@link
* #CONSTANT_INVOKE_DYNAMIC_TAG} symbols,
* <li>the offset of a bootstrap method in the BootstrapMethods boostrap_methods array, for
Expand Down
Loading