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.6 #5440

Merged
merged 1 commit into from
Oct 18, 2023
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.5
org.objectweb.asm Version 9.6
* 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 @@ -188,13 +188,14 @@ public ClassReader(
* @param classFileOffset the offset in byteBuffer of the first byte of the ClassFile to be read.
* @param checkClassVersion whether to check the class version or not.
*/
@SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
ClassReader(
final byte[] classFileBuffer, final int classFileOffset, final boolean checkClassVersion) {
this.classFileBuffer = classFileBuffer;
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.V21) {
if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V22) {
throw new IllegalArgumentException(
"Unsupported class file major version " + readShort(classFileOffset + 6));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ public class ClassWriter extends ClassVisitor {
/**
* Indicates what must be automatically computed in {@link MethodWriter}. Must be one of {@link
* MethodWriter#COMPUTE_NOTHING}, {@link MethodWriter#COMPUTE_MAX_STACK_AND_LOCAL}, {@link
* MethodWriter#COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES}, {@link
* MethodWriter#COMPUTE_INSERTED_FRAMES}, or {@link MethodWriter#COMPUTE_ALL_FRAMES}.
*/
private int compute;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@
* right shift of {@link #DIM_SHIFT}.
* <li>the KIND field, stored in 4 bits, indicates the kind of VALUE used. These 4 bits can be
* retrieved with {@link #KIND_MASK} and, without any shift, must be equal to {@link
* #CONSTANT_KIND}, {@link #REFERENCE_KIND}, {@link #UNINITIALIZED_KIND}, {@link #LOCAL_KIND}
* or {@link #STACK_KIND}.
* #CONSTANT_KIND}, {@link #REFERENCE_KIND}, {@link #UNINITIALIZED_KIND}, {@link
* #FORWARD_UNINITIALIZED_KIND},{@link #LOCAL_KIND} or {@link #STACK_KIND}.
* <li>the FLAGS field, stored in 2 bits, contains up to 2 boolean flags. Currently only one flag
* is defined, namely {@link #TOP_IF_LONG_OR_DOUBLE_FLAG}.
* <li>the VALUE field, stored in the remaining 20 bits, contains either
Expand All @@ -78,7 +78,10 @@
* <li>the index of a {@link Symbol#TYPE_TAG} {@link Symbol} in the type table of a {@link
* SymbolTable}, if KIND is equal to {@link #REFERENCE_KIND}.
* <li>the index of an {@link Symbol#UNINITIALIZED_TYPE_TAG} {@link Symbol} in the type
* table of a SymbolTable, if KIND is equal to {@link #UNINITIALIZED_KIND}.
* table of a {@link SymbolTable}, if KIND is equal to {@link #UNINITIALIZED_KIND}.
* <li>the index of a {@link Symbol#FORWARD_UNINITIALIZED_TYPE_TAG} {@link Symbol} in the
* type table of a {@link SymbolTable}, if KIND is equal to {@link
* #FORWARD_UNINITIALIZED_KIND}.
* <li>the index of a local variable in the input stack frame, if KIND is equal to {@link
* #LOCAL_KIND}.
* <li>a position relatively to the top of the stack of the input stack frame, if KIND is
Expand All @@ -88,10 +91,10 @@
*
* <p>Output frames can contain abstract types of any kind and with a positive or negative array
* dimension (and even unassigned types, represented by 0 - which does not correspond to any valid
* abstract type value). Input frames can only contain CONSTANT_KIND, REFERENCE_KIND or
* UNINITIALIZED_KIND abstract types of positive or {@literal null} array dimension. In all cases
* the type table contains only internal type names (array type descriptors are forbidden - array
* dimensions must be represented through the DIM field).
* abstract type value). Input frames can only contain CONSTANT_KIND, REFERENCE_KIND,
* UNINITIALIZED_KIND or FORWARD_UNINITIALIZED_KIND abstract types of positive or {@literal null}
* array dimension. In all cases the type table contains only internal type names (array type
* descriptors are forbidden - array dimensions must be represented through the DIM field).
*
* <p>The LONG and DOUBLE types are always represented by using two slots (LONG + TOP or DOUBLE +
* TOP), for local variables as well as in the operand stack. This is necessary to be able to
Expand Down Expand Up @@ -159,8 +162,9 @@ class Frame {
private static final int CONSTANT_KIND = 1 << KIND_SHIFT;
private static final int REFERENCE_KIND = 2 << KIND_SHIFT;
private static final int UNINITIALIZED_KIND = 3 << KIND_SHIFT;
private static final int LOCAL_KIND = 4 << KIND_SHIFT;
private static final int STACK_KIND = 5 << KIND_SHIFT;
private static final int FORWARD_UNINITIALIZED_KIND = 4 << KIND_SHIFT;
private static final int LOCAL_KIND = 5 << KIND_SHIFT;
private static final int STACK_KIND = 6 << KIND_SHIFT;

// Possible flags for the FLAGS field of an abstract type.

Expand Down Expand Up @@ -220,13 +224,13 @@ class Frame {

/**
* The abstract types that are initialized in the basic block. A constructor invocation on an
* UNINITIALIZED or UNINITIALIZED_THIS abstract type must replace <i>every occurrence</i> of this
* type in the local variables and in the operand stack. This cannot be done during the first step
* of the algorithm since, during this step, the local variables and the operand stack types are
* still abstract. It is therefore necessary to store the abstract types of the constructors which
* are invoked in the basic block, in order to do this replacement during the second step of the
* algorithm, where the frames are fully computed. Note that this array can contain abstract types
* that are relative to the input locals or to the input stack.
* UNINITIALIZED, FORWARD_UNINITIALIZED or UNINITIALIZED_THIS abstract type must replace <i>every
* occurrence</i> of this type in the local variables and in the operand stack. This cannot be
* done during the first step of the algorithm since, during this step, the local variables and
* the operand stack types are still abstract. It is therefore necessary to store the abstract
* types of the constructors which are invoked in the basic block, in order to do this replacement
* during the second step of the algorithm, where the frames are fully computed. Note that this
* array can contain abstract types that are relative to the input locals or to the input stack.
*/
private int[] initializations;

Expand Down Expand Up @@ -284,8 +288,12 @@ static int getAbstractTypeFromApiFormat(final SymbolTable symbolTable, final Obj
String descriptor = Type.getObjectType((String) type).getDescriptor();
return getAbstractTypeFromDescriptor(symbolTable, descriptor, 0);
} else {
return UNINITIALIZED_KIND
| symbolTable.addUninitializedType("", ((Label) type).bytecodeOffset);
Label label = (Label) type;
if ((label.flags & Label.FLAG_RESOLVED) != 0) {
return UNINITIALIZED_KIND | symbolTable.addUninitializedType("", label.bytecodeOffset);
} else {
return FORWARD_UNINITIALIZED_KIND | symbolTable.addForwardUninitializedType("", label);
}
}
}

Expand Down Expand Up @@ -637,12 +645,14 @@ private void addInitializedType(final int abstractType) {
* @param symbolTable the type table to use to lookup and store type {@link Symbol}.
* @param abstractType an abstract type.
* @return the REFERENCE_KIND abstract type corresponding to abstractType if it is
* UNINITIALIZED_THIS or an UNINITIALIZED_KIND abstract type for one of the types on which a
* constructor is invoked in the basic block. Otherwise returns abstractType.
* UNINITIALIZED_THIS or an UNINITIALIZED_KIND or FORWARD_UNINITIALIZED_KIND abstract type for
* one of the types on which a constructor is invoked in the basic block. Otherwise returns
* abstractType.
*/
private int getInitializedType(final SymbolTable symbolTable, final int abstractType) {
if (abstractType == UNINITIALIZED_THIS
|| (abstractType & (DIM_MASK | KIND_MASK)) == UNINITIALIZED_KIND) {
|| (abstractType & (DIM_MASK | KIND_MASK)) == UNINITIALIZED_KIND
|| (abstractType & (DIM_MASK | KIND_MASK)) == FORWARD_UNINITIALIZED_KIND) {
for (int i = 0; i < initializationCount; ++i) {
int initializedType = initializations[i];
int dim = initializedType & DIM_MASK;
Expand Down Expand Up @@ -1253,11 +1263,12 @@ final boolean merge(
*
* @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.
* This type should be of {@link #CONSTANT_KIND}, {@link #REFERENCE_KIND} or {@link
* #UNINITIALIZED_KIND} kind, with positive or {@literal null} array dimensions.
* This type should be of {@link #CONSTANT_KIND}, {@link #REFERENCE_KIND}, {@link
* #UNINITIALIZED_KIND} or {@link #FORWARD_UNINITIALIZED_KIND} kind, with positive or
* {@literal null} array dimensions.
* @param dstTypes an array of abstract types. These types should be of {@link #CONSTANT_KIND},
* {@link #REFERENCE_KIND} or {@link #UNINITIALIZED_KIND} kind, with positive or {@literal
* null} array dimensions.
* {@link #REFERENCE_KIND}, {@link #UNINITIALIZED_KIND} or {@link #FORWARD_UNINITIALIZED_KIND}
* kind, with positive or {@literal null} array dimensions.
* @param dstIndex the index of the type that must be merged in dstTypes.
* @return {@literal true} if the type array has been modified by this operation.
*/
Expand Down Expand Up @@ -1400,7 +1411,8 @@ final void accept(final MethodWriter methodWriter) {
*
* @param symbolTable the type table to use to lookup and store type {@link Symbol}.
* @param abstractType an abstract type, restricted to {@link Frame#CONSTANT_KIND}, {@link
* Frame#REFERENCE_KIND} or {@link Frame#UNINITIALIZED_KIND} types.
* Frame#REFERENCE_KIND}, {@link Frame#UNINITIALIZED_KIND} or {@link
* Frame#FORWARD_UNINITIALIZED_KIND} types.
* @param output where the abstract type must be put.
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.4">JVMS
* 4.7.4</a>
Expand All @@ -1422,6 +1434,10 @@ static void putAbstractType(
case UNINITIALIZED_KIND:
output.putByte(ITEM_UNINITIALIZED).putShort((int) symbolTable.getType(typeValue).data);
break;
case FORWARD_UNINITIALIZED_KIND:
output.putByte(ITEM_UNINITIALIZED);
symbolTable.getForwardUninitializedLabel(typeValue).put(output);
break;
default:
throw new AssertionError();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ public class Label {
*/
static final int FORWARD_REFERENCE_TYPE_WIDE = 0x20000000;

/**
* The type of forward references stored in two bytes in the <i>stack map table</i>. This is the
* case of the labels of {@link Frame#ITEM_UNINITIALIZED} stack map frame elements, when the NEW
* instruction is after the &lt;init&gt; constructor call (in bytecode offset order).
*/
static final int FORWARD_REFERENCE_TYPE_STACK_MAP = 0x30000000;

/**
* The bit mask to extract the 'handle' of a forward reference to this label. The extracted handle
* is the bytecode offset where the forward reference value is stored (using either 2 or 4 bytes,
Expand Down Expand Up @@ -404,6 +411,20 @@ final void put(
}
}

/**
* Puts a reference to this label in the <i>stack map table</i> of a method. If the bytecode
* offset of the label is known, it is written directly. Otherwise, a null relative offset is
* written and a new forward reference is declared for this label.
*
* @param stackMapTableEntries the stack map table where the label offset must be added.
*/
final void put(final ByteVector stackMapTableEntries) {
if ((flags & FLAG_RESOLVED) == 0) {
addForwardReference(0, FORWARD_REFERENCE_TYPE_STACK_MAP, stackMapTableEntries.length);
}
stackMapTableEntries.putShort(bytecodeOffset);
}

/**
* Adds a forward reference to this label. This method must be called only for a true forward
* reference, i.e. only if this label is not resolved yet. For backward references, the relative
Expand Down Expand Up @@ -436,17 +457,21 @@ private void addForwardReference(
* Sets the bytecode offset of this label to the given value and resolves the forward references
* to this label, if any. This method must be called when this label is added to the bytecode of
* the method, i.e. when its bytecode offset becomes known. This method fills in the blanks that
* where left in the bytecode by each forward reference previously added to this label.
* where left in the bytecode (and optionally in the stack map table) by each forward reference
* previously added to this label.
*
* @param code the bytecode of the method.
* @param stackMapTableEntries the 'entries' array of the StackMapTable code attribute of the
* method. Maybe {@literal null}.
* @param bytecodeOffset the bytecode offset of this label.
* @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
* bytes instead of 2), in ClassReader.
*/
final boolean resolve(final byte[] code, final int bytecodeOffset) {
final boolean resolve(
final byte[] code, final ByteVector stackMapTableEntries, final int bytecodeOffset) {
this.flags |= FLAG_RESOLVED;
this.bytecodeOffset = bytecodeOffset;
if (forwardReferences == null) {
Expand Down Expand Up @@ -476,11 +501,14 @@ final boolean resolve(final byte[] code, final int bytecodeOffset) {
}
code[handle++] = (byte) (relativeOffset >>> 8);
code[handle] = (byte) relativeOffset;
} else {
} else if ((reference & FORWARD_REFERENCE_TYPE_MASK) == FORWARD_REFERENCE_TYPE_WIDE) {
code[handle++] = (byte) (relativeOffset >>> 24);
code[handle++] = (byte) (relativeOffset >>> 16);
code[handle++] = (byte) (relativeOffset >>> 8);
code[handle] = (byte) relativeOffset;
} else {
stackMapTableEntries.data[handle++] = (byte) (bytecodeOffset >>> 8);
stackMapTableEntries.data[handle] = (byte) bytecodeOffset;
}
}
return hasAsmInstructions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,9 @@ final class MethodWriter extends MethodVisitor {
* the number of stack elements. The local variables start at index 3 and are followed by the
* operand stack elements. In summary frame[0] = offset, frame[1] = numLocal, frame[2] = numStack.
* Local variables and operand stack entries contain abstract types, as defined in {@link Frame},
* but restricted to {@link Frame#CONSTANT_KIND}, {@link Frame#REFERENCE_KIND} or {@link
* Frame#UNINITIALIZED_KIND} abstract types. Long and double types use only one array entry.
* but restricted to {@link Frame#CONSTANT_KIND}, {@link Frame#REFERENCE_KIND}, {@link
* Frame#UNINITIALIZED_KIND} or {@link Frame#FORWARD_UNINITIALIZED_KIND} abstract types. Long and
* double types use only one array entry.
*/
private int[] currentFrame;

Expand Down Expand Up @@ -693,15 +694,15 @@ public AnnotationVisitor visitParameterAnnotation(
if (visible) {
if (lastRuntimeVisibleParameterAnnotations == null) {
lastRuntimeVisibleParameterAnnotations =
new AnnotationWriter[Type.getArgumentTypes(descriptor).length];
new AnnotationWriter[Type.getArgumentCount(descriptor)];
}
return lastRuntimeVisibleParameterAnnotations[parameter] =
AnnotationWriter.create(
symbolTable, annotationDescriptor, lastRuntimeVisibleParameterAnnotations[parameter]);
} else {
if (lastRuntimeInvisibleParameterAnnotations == null) {
lastRuntimeInvisibleParameterAnnotations =
new AnnotationWriter[Type.getArgumentTypes(descriptor).length];
new AnnotationWriter[Type.getArgumentCount(descriptor)];
}
return lastRuntimeInvisibleParameterAnnotations[parameter] =
AnnotationWriter.create(
Expand Down Expand Up @@ -1199,7 +1200,7 @@ public void visitJumpInsn(final int opcode, final Label label) {
@Override
public void visitLabel(final Label label) {
// Resolve the forward references to this label, if any.
hasAsmInstructions |= label.resolve(code.data, code.length);
hasAsmInstructions |= label.resolve(code.data, stackMapTableEntries, code.length);
// visitLabel starts a new basic block (except for debug only labels), so we need to update the
// previous and current block references and list of successors.
if ((label.flags & Label.FLAG_DEBUG_ONLY) != 0) {
Expand Down Expand Up @@ -1795,7 +1796,7 @@ private void endCurrentBasicBlockWithNoSuccessor() {
if (compute == COMPUTE_ALL_FRAMES) {
Label nextBasicBlock = new Label();
nextBasicBlock.frame = new Frame(nextBasicBlock);
nextBasicBlock.resolve(code.data, code.length);
nextBasicBlock.resolve(code.data, stackMapTableEntries, code.length);
lastBasicBlock.nextBasicBlock = nextBasicBlock;
lastBasicBlock = nextBasicBlock;
currentBasicBlock = null;
Expand Down Expand Up @@ -1979,9 +1980,8 @@ private void putFrameType(final Object type) {
.putByte(Frame.ITEM_OBJECT)
.putShort(symbolTable.addConstantClass((String) type).index);
} else {
stackMapTableEntries
.putByte(Frame.ITEM_UNINITIALIZED)
.putShort(((Label) type).bytecodeOffset);
stackMapTableEntries.putByte(Frame.ITEM_UNINITIALIZED);
((Label) type).put(stackMapTableEntries);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ public interface Opcodes {
int V19 = 0 << 16 | 63;
int V20 = 0 << 16 | 64;
int V21 = 0 << 16 | 65;
int V22 = 0 << 16 | 66;

/**
* Version flag indicating that the class is using 'preview' features.
Expand Down
Loading