Adopt ASM 9.6
Signed-off-by: jansupol <jan.supol@oracle.com>
diff --git a/NOTICE.md b/NOTICE.md
index 41e5742..5ace8c2 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -95,7 +95,7 @@
* 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.
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java
index 21969f0..820a3b8 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java
@@ -188,13 +188,14 @@
* @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));
}
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java
index 7bb6ab0..7588188 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java
@@ -217,6 +217,7 @@
/**
* 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;
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Frame.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Frame.java
index be4364a..30d86e5 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Frame.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Frame.java
@@ -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
@@ -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
@@ -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
@@ -159,8 +162,9 @@
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.
@@ -220,13 +224,13 @@
/**
* 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;
@@ -284,8 +288,12 @@
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);
+ }
}
}
@@ -637,12 +645,14 @@
* @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;
@@ -1253,11 +1263,12 @@
*
* @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.
*/
@@ -1400,7 +1411,8 @@
*
* @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>
@@ -1422,6 +1434,10 @@
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();
}
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Label.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Label.java
index 2933a99..0f9e3c9 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Label.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Label.java
@@ -117,6 +117,13 @@
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 <init> 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,
* as indicated by the {@link #FORWARD_REFERENCE_TYPE_MASK}).
@@ -405,6 +412,20 @@
}
/**
+ * 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
* bytecode offset of the reference can be, and must be, computed and stored directly.
@@ -436,9 +457,12 @@
* 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
@@ -446,7 +470,8 @@
* 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) {
@@ -476,11 +501,14 @@
}
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;
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodWriter.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodWriter.java
index ea2e4e4..918bd71 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodWriter.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodWriter.java
@@ -534,8 +534,9 @@
* 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;
@@ -693,7 +694,7 @@
if (visible) {
if (lastRuntimeVisibleParameterAnnotations == null) {
lastRuntimeVisibleParameterAnnotations =
- new AnnotationWriter[Type.getArgumentTypes(descriptor).length];
+ new AnnotationWriter[Type.getArgumentCount(descriptor)];
}
return lastRuntimeVisibleParameterAnnotations[parameter] =
AnnotationWriter.create(
@@ -701,7 +702,7 @@
} else {
if (lastRuntimeInvisibleParameterAnnotations == null) {
lastRuntimeInvisibleParameterAnnotations =
- new AnnotationWriter[Type.getArgumentTypes(descriptor).length];
+ new AnnotationWriter[Type.getArgumentCount(descriptor)];
}
return lastRuntimeInvisibleParameterAnnotations[parameter] =
AnnotationWriter.create(
@@ -1199,7 +1200,7 @@
@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) {
@@ -1795,7 +1796,7 @@
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;
@@ -1979,9 +1980,8 @@
.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);
}
}
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java
index b577623..4256afa 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java
@@ -287,6 +287,7 @@
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.
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Symbol.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Symbol.java
index adc9391..f161884 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Symbol.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Symbol.java
@@ -103,12 +103,25 @@
static final int TYPE_TAG = 128;
/**
- * The tag value of an {@link Frame#ITEM_UNINITIALIZED} type entry in the type table of a class.
+ * The tag value of an uninitialized type entry in the type table of a class. This type is used
+ * for the normal case where the NEW instruction is before the <init> constructor call (in
+ * bytecode offset order), i.e. when the label of the NEW instruction is resolved when the
+ * constructor call is visited. If the NEW instruction is after the constructor call, use the
+ * {@link #FORWARD_UNINITIALIZED_TYPE_TAG} tag value instead.
*/
static final int UNINITIALIZED_TYPE_TAG = 129;
+ /**
+ * The tag value of an uninitialized type entry in the type table of a class. This type is used
+ * for the unusual case where the NEW instruction is after the <init> constructor call (in
+ * bytecode offset order), i.e. when the label of the NEW instruction is not resolved when the
+ * constructor call is visited. If the NEW instruction is before the constructor call, use the
+ * {@link #UNINITIALIZED_TYPE_TAG} tag value instead.
+ */
+ static final int FORWARD_UNINITIALIZED_TYPE_TAG = 130;
+
/** The tag value of a merged type entry in the (ASM specific) type table of a class. */
- static final int MERGED_TYPE_TAG = 130;
+ static final int MERGED_TYPE_TAG = 131;
// Instance fields.
@@ -151,8 +164,8 @@
* #CONSTANT_INVOKE_DYNAMIC_TAG} symbols,
* <li>an arbitrary string for {@link #CONSTANT_UTF8_TAG} and {@link #CONSTANT_STRING_TAG}
* symbols,
- * <li>an internal class name for {@link #CONSTANT_CLASS_TAG}, {@link #TYPE_TAG} and {@link
- * #UNINITIALIZED_TYPE_TAG} symbols,
+ * <li>an internal class name for {@link #CONSTANT_CLASS_TAG}, {@link #TYPE_TAG}, {@link
+ * #UNINITIALIZED_TYPE_TAG} and {@link #FORWARD_UNINITIALIZED_TYPE_TAG} symbols,
* <li>{@literal null} for the other types of symbol.
* </ul>
*/
@@ -172,6 +185,9 @@
* {@link #CONSTANT_DYNAMIC_TAG} or {@link #BOOTSTRAP_METHOD_TAG} symbols,
* <li>the bytecode offset of the NEW instruction that created an {@link
* Frame#ITEM_UNINITIALIZED} type for {@link #UNINITIALIZED_TYPE_TAG} symbols,
+ * <li>the index of the {@link Label} (in the {@link SymbolTable#labelTable} table) of the NEW
+ * instruction that created an {@link Frame#ITEM_UNINITIALIZED} type for {@link
+ * #FORWARD_UNINITIALIZED_TYPE_TAG} symbols,
* <li>the indices (in the class' type table) of two {@link #TYPE_TAG} source types for {@link
* #MERGED_TYPE_TAG} symbols,
* <li>0 for the other types of symbol.
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/SymbolTable.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/SymbolTable.java
index e52af51..dc601a1 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/SymbolTable.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/SymbolTable.java
@@ -108,12 +108,36 @@
* An ASM specific type table used to temporarily store internal names that will not necessarily
* be stored in the constant pool. This type table is used by the control flow and data flow
* analysis algorithm used to compute stack map frames from scratch. This array stores {@link
- * Symbol#TYPE_TAG} and {@link Symbol#UNINITIALIZED_TYPE_TAG}) Symbol. The type symbol at index
- * {@code i} has its {@link Symbol#index} equal to {@code i} (and vice versa).
+ * Symbol#TYPE_TAG}, {@link Symbol#UNINITIALIZED_TYPE_TAG},{@link
+ * Symbol#FORWARD_UNINITIALIZED_TYPE_TAG} and {@link Symbol#MERGED_TYPE_TAG} entries. The type
+ * symbol at index {@code i} has its {@link Symbol#index} equal to {@code i} (and vice versa).
*/
private Entry[] typeTable;
/**
+ * The actual number of {@link LabelEntry} in {@link #labelTable}. These elements are stored from
+ * index 0 to labelCount (excluded). The other array entries are empty. These label entries are
+ * also stored in the {@link #labelEntries} hash set.
+ */
+ private int labelCount;
+
+ /**
+ * The labels corresponding to the "forward uninitialized" types in the ASM specific {@link
+ * typeTable} (see {@link Symbol#FORWARD_UNINITIALIZED_TYPE_TAG}). The label entry at index {@code
+ * i} has its {@link LabelEntry#index} equal to {@code i} (and vice versa).
+ */
+ private LabelEntry[] labelTable;
+
+ /**
+ * A hash set of all the {@link LabelEntry} elements in the {@link #labelTable}. Each {@link
+ * LabelEntry} instance is stored at the array index given by its hash code modulo the array size.
+ * If several entries must be stored at the same array index, they are linked together via their
+ * {@link LabelEntry#next} field. The {@link #getOrAddLabelEntry(Label)} method ensures that this
+ * table does not contain duplicated entries.
+ */
+ private LabelEntry[] labelEntries;
+
+ /**
* Constructs a new, empty SymbolTable for the given ClassWriter.
*
* @param classWriter a ClassWriter.
@@ -1130,6 +1154,18 @@
}
/**
+ * Returns the label corresponding to the "forward uninitialized" type table element whose index
+ * is given.
+ *
+ * @param typeIndex the type table index of a "forward uninitialized" type table element.
+ * @return the label corresponding of the NEW instruction which created this "forward
+ * uninitialized" type.
+ */
+ Label getForwardUninitializedLabel(final int typeIndex) {
+ return labelTable[(int) typeTable[typeIndex].data].label;
+ }
+
+ /**
* Adds a type in the type table of this symbol table. Does nothing if the type table already
* contains a similar type.
*
@@ -1149,13 +1185,13 @@
}
/**
- * Adds an {@link Frame#ITEM_UNINITIALIZED} type in the type table of this symbol table. Does
- * nothing if the type table already contains a similar type.
+ * Adds an uninitialized type in the type table of this symbol table. Does nothing if the type
+ * table already contains a similar type.
*
* @param value an internal class name.
- * @param bytecodeOffset the bytecode offset of the NEW instruction that created this {@link
- * Frame#ITEM_UNINITIALIZED} type value.
- * @return the index of a new or already existing type Symbol with the given value.
+ * @param bytecodeOffset the bytecode offset of the NEW instruction that created this
+ * uninitialized type value.
+ * @return the index of a new or already existing type #@link Symbol} with the given value.
*/
int addUninitializedType(final String value, final int bytecodeOffset) {
int hashCode = hash(Symbol.UNINITIALIZED_TYPE_TAG, value, bytecodeOffset);
@@ -1174,6 +1210,32 @@
}
/**
+ * Adds a "forward uninitialized" type in the type table of this symbol table. Does nothing if the
+ * type table already contains a similar type.
+ *
+ * @param value an internal class name.
+ * @param label the label of the NEW instruction that created this uninitialized type value. If
+ * the label is resolved, use the {@link #addUninitializedType} method instead.
+ * @return the index of a new or already existing type {@link Symbol} with the given value.
+ */
+ int addForwardUninitializedType(final String value, final Label label) {
+ int labelIndex = getOrAddLabelEntry(label).index;
+ int hashCode = hash(Symbol.FORWARD_UNINITIALIZED_TYPE_TAG, value, labelIndex);
+ Entry entry = get(hashCode);
+ while (entry != null) {
+ if (entry.tag == Symbol.FORWARD_UNINITIALIZED_TYPE_TAG
+ && entry.hashCode == hashCode
+ && entry.data == labelIndex
+ && entry.value.equals(value)) {
+ return entry.index;
+ }
+ entry = entry.next;
+ }
+ return addTypeInternal(
+ new Entry(typeCount, Symbol.FORWARD_UNINITIALIZED_TYPE_TAG, value, labelIndex, hashCode));
+ }
+
+ /**
* Adds a merged type in the type table of this symbol table. Does nothing if the type table
* already contains a similar type.
*
@@ -1225,6 +1287,59 @@
return put(entry).index;
}
+ /**
+ * Returns the {@link LabelEntry} corresponding to the given label. Creates a new one if there is
+ * no such entry.
+ *
+ * @param label the {@link Label} of a NEW instruction which created an uninitialized type, in the
+ * case where this NEW instruction is after the <init> constructor call (in bytecode
+ * offset order). See {@link Symbol#FORWARD_UNINITIALIZED_TYPE_TAG}.
+ * @return the {@link LabelEntry} corresponding to {@code label}.
+ */
+ private LabelEntry getOrAddLabelEntry(final Label label) {
+ if (labelEntries == null) {
+ labelEntries = new LabelEntry[16];
+ labelTable = new LabelEntry[16];
+ }
+ int hashCode = System.identityHashCode(label);
+ LabelEntry labelEntry = labelEntries[hashCode % labelEntries.length];
+ while (labelEntry != null && labelEntry.label != label) {
+ labelEntry = labelEntry.next;
+ }
+ if (labelEntry != null) {
+ return labelEntry;
+ }
+
+ if (labelCount > (labelEntries.length * 3) / 4) {
+ int currentCapacity = labelEntries.length;
+ int newCapacity = currentCapacity * 2 + 1;
+ LabelEntry[] newLabelEntries = new LabelEntry[newCapacity];
+ for (int i = currentCapacity - 1; i >= 0; --i) {
+ LabelEntry currentEntry = labelEntries[i];
+ while (currentEntry != null) {
+ int newCurrentEntryIndex = System.identityHashCode(currentEntry.label) % newCapacity;
+ LabelEntry nextEntry = currentEntry.next;
+ currentEntry.next = newLabelEntries[newCurrentEntryIndex];
+ newLabelEntries[newCurrentEntryIndex] = currentEntry;
+ currentEntry = nextEntry;
+ }
+ }
+ labelEntries = newLabelEntries;
+ }
+ if (labelCount == labelTable.length) {
+ LabelEntry[] newLabelTable = new LabelEntry[2 * labelTable.length];
+ System.arraycopy(labelTable, 0, newLabelTable, 0, labelTable.length);
+ labelTable = newLabelTable;
+ }
+
+ labelEntry = new LabelEntry(labelCount, label);
+ int index = hashCode % labelEntries.length;
+ labelEntry.next = labelEntries[index];
+ labelEntries[index] = labelEntry;
+ labelTable[labelCount++] = labelEntry;
+ return labelEntry;
+ }
+
// -----------------------------------------------------------------------------------------------
// Static helper methods to compute hash codes.
// -----------------------------------------------------------------------------------------------
@@ -1275,7 +1390,7 @@
*
* @author Eric Bruneton
*/
- private static class Entry extends Symbol {
+ private static final class Entry extends Symbol {
/** The hash code of this entry. */
final int hashCode;
@@ -1319,4 +1434,30 @@
this.hashCode = hashCode;
}
}
+
+ /**
+ * A label corresponding to a "forward uninitialized" type in the ASM specific {@link
+ * SymbolTable#typeTable} (see {@link Symbol#FORWARD_UNINITIALIZED_TYPE_TAG}).
+ *
+ * @author Eric Bruneton
+ */
+ private static final class LabelEntry {
+
+ /** The index of this label entry in the {@link SymbolTable#labelTable} array. */
+ final int index;
+
+ /** The value of this label entry. */
+ final Label label;
+
+ /**
+ * Another entry (and so on recursively) having the same hash code (modulo the size of {@link
+ * SymbolTable#labelEntries}}) as this one.
+ */
+ LabelEntry next;
+
+ LabelEntry(final int index, final Label label) {
+ this.index = index;
+ this.label = label;
+ }
+ }
}
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Type.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Type.java
index 6808aba..e43b7a9 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Type.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Type.java
@@ -295,26 +295,12 @@
*/
public static Type[] getArgumentTypes(final String methodDescriptor) {
// First step: compute the number of argument types in methodDescriptor.
- int numArgumentTypes = 0;
- // Skip the first character, which is always a '('.
- int currentOffset = 1;
- // Parse the argument types, one at a each loop iteration.
- while (methodDescriptor.charAt(currentOffset) != ')') {
- while (methodDescriptor.charAt(currentOffset) == '[') {
- currentOffset++;
- }
- if (methodDescriptor.charAt(currentOffset++) == 'L') {
- // Skip the argument descriptor content.
- int semiColumnOffset = methodDescriptor.indexOf(';', currentOffset);
- currentOffset = Math.max(currentOffset, semiColumnOffset + 1);
- }
- ++numArgumentTypes;
- }
+ int numArgumentTypes = getArgumentCount(methodDescriptor);
// Second step: create a Type instance for each argument type.
Type[] argumentTypes = new Type[numArgumentTypes];
// Skip the first character, which is always a '('.
- currentOffset = 1;
+ int currentOffset = 1;
// Parse and create the argument types, one at each loop iteration.
int currentArgumentTypeIndex = 0;
while (methodDescriptor.charAt(currentOffset) != ')') {
@@ -703,13 +689,51 @@
}
/**
+ * Returns the number of arguments of this method type. This method should only be used for method
+ * types.
+ *
+ * @return the number of arguments of this method type. Each argument counts for 1, even long and
+ * double ones. The implicit @literal{this} argument is not counted.
+ */
+ public int getArgumentCount() {
+ return getArgumentCount(getDescriptor());
+ }
+
+ /**
+ * Returns the number of arguments in the given method descriptor.
+ *
+ * @param methodDescriptor a method descriptor.
+ * @return the number of arguments in the given method descriptor. Each argument counts for 1,
+ * even long and double ones. The implicit @literal{this} argument is not counted.
+ */
+ public static int getArgumentCount(final String methodDescriptor) {
+ int argumentCount = 0;
+ // Skip the first character, which is always a '('.
+ int currentOffset = 1;
+ // Parse the argument types, one at a each loop iteration.
+ while (methodDescriptor.charAt(currentOffset) != ')') {
+ while (methodDescriptor.charAt(currentOffset) == '[') {
+ currentOffset++;
+ }
+ if (methodDescriptor.charAt(currentOffset++) == 'L') {
+ // Skip the argument descriptor content.
+ int semiColumnOffset = methodDescriptor.indexOf(';', currentOffset);
+ currentOffset = Math.max(currentOffset, semiColumnOffset + 1);
+ }
+ ++argumentCount;
+ }
+ return argumentCount;
+ }
+
+ /**
* Returns the size of the arguments and of the return value of methods of this type. This method
* should only be used for method types.
*
* @return the size of the arguments of the method (plus one for the implicit this argument),
* argumentsSize, and the size of its return value, returnSize, packed into a single int i =
* {@code (argumentsSize << 2) | returnSize} (argumentsSize is therefore equal to {@code
- * i >> 2}, and returnSize to {@code i & 0x03}).
+ * i >> 2}, and returnSize to {@code i & 0x03}). Long and double values have size 2,
+ * the others have size 1.
*/
public int getArgumentsAndReturnSizes() {
return getArgumentsAndReturnSizes(getDescriptor());
@@ -722,7 +746,8 @@
* @return the size of the arguments of the method (plus one for the implicit this argument),
* argumentsSize, and the size of its return value, returnSize, packed into a single int i =
* {@code (argumentsSize << 2) | returnSize} (argumentsSize is therefore equal to {@code
- * i >> 2}, and returnSize to {@code i & 0x03}).
+ * i >> 2}, and returnSize to {@code i & 0x03}). Long and double values have size 2,
+ * the others have size 1.
*/
public static int getArgumentsAndReturnSizes(final String methodDescriptor) {
int argumentsSize = 1;
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/AnnotationAcceptingListener.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/AnnotationAcceptingListener.java
index b137db9..52e2db2 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/AnnotationAcceptingListener.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/AnnotationAcceptingListener.java
@@ -309,7 +309,7 @@
private static class ClassReaderWrapper {
private static final Logger LOGGER = Logger.getLogger(ClassReader.class.getName());
- private static final int WARN_VERSION = Opcodes.V21;
+ private static final int WARN_VERSION = Opcodes.V22;
private static final int INPUT_STREAM_DATA_CHUNK_SIZE = 4096;
private final byte[] b;
diff --git a/core-server/src/main/resources/META-INF/NOTICE.markdown b/core-server/src/main/resources/META-INF/NOTICE.markdown
index 00b8fa0..92d64be 100644
--- a/core-server/src/main/resources/META-INF/NOTICE.markdown
+++ b/core-server/src/main/resources/META-INF/NOTICE.markdown
@@ -36,7 +36,7 @@
* Copyright (c) 2015-2018 Oracle and/or its affiliates. All rights reserved.
* Copyright 2010-2013 Coda Hale and Yammer, Inc.
-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.
diff --git a/examples/NOTICE.md b/examples/NOTICE.md
index f05837c..dc73677 100644
--- a/examples/NOTICE.md
+++ b/examples/NOTICE.md
@@ -91,7 +91,7 @@
* 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.
diff --git a/pom.xml b/pom.xml
index e0c676a..576f8c6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2226,7 +2226,7 @@
<arquillian.weld.version>2.1.0.Final</arquillian.weld.version>
<!-- asm is now source integrated - keeping this property to see the version -->
<!-- see core-server/src/main/java/jersey/repackaged/asm/.. -->
- <asm.version>9.5</asm.version>
+ <asm.version>9.6</asm.version>
<!--required for spring (ext) modules integration -->
<aspectj.weaver.version>1.6.11</aspectj.weaver.version>
<!-- <bnd.plugin.version>2.3.6</bnd.plugin.version>-->