diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java index 474d3b7f0d7ef..87f18538697b8 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java @@ -105,13 +105,28 @@ protected AnnotationVisitor(final int api, final AnnotationVisitor annotationVis && api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 - && api != Opcodes.ASM4) { + && api != Opcodes.ASM4 + && api != Opcodes.ASM10_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } + if (api == Opcodes.ASM10_EXPERIMENTAL) { + Constants.checkAsmExperimental(this); + } this.api = api; this.av = annotationVisitor; } + /** + * The annotation visitor to which this visitor must delegate method calls. May be {@literal + * null}. + * + * @return the annotation visitor to which this visitor must delegate method calls, or {@literal + * null}. + */ + public AnnotationVisitor getDelegate() { + return av; + } + /** * Visits a primitive value of the annotation. * diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ByteVector.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ByteVector.java index 4c04bff410c8c..33a66b2c12ee8 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ByteVector.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ByteVector.java @@ -403,4 +403,3 @@ private void enlarge(final int size) { data = newData; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java index a3c7084690272..59dd3c0fc6ee1 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java @@ -220,13 +220,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.V23) { + if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V22) { throw new IllegalArgumentException( "Unsupported class file major version " + readShort(classFileOffset + 6)); } @@ -407,7 +408,7 @@ public String getClassName() { } /** - * Returns the internal of name of the super class (see {@link Type#getInternalName()}). For + * Returns the internal name of the super class (see {@link Type#getInternalName()}). For * interfaces, the super class is {@link Object}. * * @return the internal name of the super class, or {@literal null} for {@link Object} class. @@ -2082,6 +2083,7 @@ private void readCode( currentOffset = bytecodeStartOffset; while (currentOffset < bytecodeEndOffset) { final int currentBytecodeOffset = currentOffset - bytecodeStartOffset; + readBytecodeInstructionOffset(currentBytecodeOffset); // Visit the label and the line number(s) for this bytecode offset, if any. Label currentLabel = labels[currentBytecodeOffset]; @@ -2697,6 +2699,20 @@ private void readCode( methodVisitor.visitMaxs(maxStack, maxLocals); } + /** + * Handles the bytecode offset of the next instruction to be visited in {@link + * #accept(ClassVisitor,int)}. This method is called just before the instruction and before its + * associated label and stack map frame, if any. The default implementation of this method does + * nothing. Subclasses can override this method to store the argument in a mutable field, for + * instance, so that {@link MethodVisitor} instances can get the bytecode offset of each visited + * instruction (if so, the usual concurrency issues related to mutable data should be addressed). + * + * @param bytecodeOffset the bytecode offset of the next instruction to be visited. + */ + protected void readBytecodeInstructionOffset(final int bytecodeOffset) { + // Do nothing by default. + } + /** * Returns the label corresponding to the given bytecode offset. The default implementation of * this method creates a label for the given offset if it has not been already created. @@ -3882,4 +3898,3 @@ public Object readConst(final int constantPoolEntryIndex, final char[] charBuffe } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassTooLargeException.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassTooLargeException.java index fe94f7446d497..c110ec34c7433 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassTooLargeException.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassTooLargeException.java @@ -74,7 +74,8 @@ public final class ClassTooLargeException extends IndexOutOfBoundsException { /** * Constructs a new {@link ClassTooLargeException}. * - * @param className the internal name of the class. + * @param className the internal name of the class (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). * @param constantPoolCount the number of constant pool items of the class. */ public ClassTooLargeException(final String className, final int constantPoolCount) { @@ -84,7 +85,7 @@ public ClassTooLargeException(final String className, final int constantPoolCoun } /** - * Returns the internal name of the class. + * Returns the internal name of the class (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName()}). * * @return the internal name of the class. */ @@ -101,4 +102,3 @@ public int getConstantPoolCount() { return constantPoolCount; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java index 1b4fa6daaebe8..4de2154dd0813 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java @@ -104,13 +104,26 @@ protected ClassVisitor(final int api, final ClassVisitor classVisitor) { && api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 - && api != Opcodes.ASM4) { + && api != Opcodes.ASM4 + && api != Opcodes.ASM10_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } + if (api == Opcodes.ASM10_EXPERIMENTAL) { + Constants.checkAsmExperimental(this); + } this.api = api; this.cv = classVisitor; } + /** + * The class visitor to which this visitor must delegate method calls. May be {@literal null}. + * + * @return the class visitor to which this visitor must delegate method calls, or {@literal null}. + */ + public ClassVisitor getDelegate() { + return cv; + } + /** * Visits the header of the class. * @@ -185,7 +198,8 @@ public ModuleVisitor visitModule(final String name, final int access, final Stri * implicitly its own nest, so it's invalid to call this method with the visited class name as * argument. * - * @param nestHost the internal name of the host class of the nest. + * @param nestHost the internal name of the host class of the nest (see {@link + * Type#getInternalName()}). */ public void visitNestHost(final String nestHost) { if (api < Opcodes.ASM7) { @@ -197,14 +211,19 @@ public void visitNestHost(final String nestHost) { } /** - * Visits the enclosing class of the class. This method must be called only if the class has an - * enclosing class. + * Visits the enclosing class of the class. This method must be called only if this class is a + * local or anonymous class. See the JVMS 4.7.7 section for more details. * - * @param owner internal name of the enclosing class of the class. + * @param owner internal name of the enclosing class of the class (see {@link + * Type#getInternalName()}). * @param name the name of the method that contains the class, or {@literal null} if the class is - * not enclosed in a method of its enclosing class. + * not enclosed in a method or constructor of its enclosing class (e.g. if it is enclosed in + * an instance initializer, static initializer, instance variable initializer, or class + * variable initializer). * @param descriptor the descriptor of the method that contains the class, or {@literal null} if - * the class is not enclosed in a method of its enclosing class. + * the class is not enclosed in a method or constructor of its enclosing class (e.g. if it is + * enclosed in an instance initializer, static initializer, instance variable initializer, or + * class variable initializer). */ public void visitOuterClass(final String owner, final String name, final String descriptor) { if (cv != null) { @@ -271,7 +290,7 @@ public void visitAttribute(final Attribute attribute) { * the visited class is the host of a nest. A nest host is implicitly a member of its own nest, so * it's invalid to call this method with the visited class name as argument. * - * @param nestMember the internal name of a nest member. + * @param nestMember the internal name of a nest member (see {@link Type#getInternalName()}). */ public void visitNestMember(final String nestMember) { if (api < Opcodes.ASM7) { @@ -286,7 +305,8 @@ public void visitNestMember(final String nestMember) { * Visits a permitted subclasses. A permitted subclass is one of the allowed subclasses of the * current class. * - * @param permittedSubclass the internal name of a permitted subclass. + * @param permittedSubclass the internal name of a permitted subclass (see {@link + * Type#getInternalName()}). */ public void visitPermittedSubclass(final String permittedSubclass) { if (api < Opcodes.ASM9) { @@ -299,15 +319,18 @@ public void visitPermittedSubclass(final String permittedSubclass) { /** * Visits information about an inner class. This inner class is not necessarily a member of the - * class being visited. + * class being visited. More precisely, every class or interface C which is referenced by this + * class and which is not a package member must be visited with this method. This class must + * reference its nested class or interface members, and its enclosing class, if any. See the JVMS + * 4.7.6 section for more details. * - * @param name the internal name of an inner class (see {@link Type#getInternalName()}). - * @param outerName the internal name of the class to which the inner class belongs (see {@link - * Type#getInternalName()}). May be {@literal null} for not member classes. - * @param innerName the (simple) name of the inner class inside its enclosing class. May be - * {@literal null} for anonymous inner classes. - * @param access the access flags of the inner class as originally declared in the enclosing - * class. + * @param name the internal name of C (see {@link Type#getInternalName()}). + * @param outerName the internal name of the class or interface C is a member of (see {@link + * Type#getInternalName()}). Must be {@literal null} if C is not the member of a class or + * interface (e.g. for local or anonymous classes). + * @param innerName the (simple) name of C. Must be {@literal null} for anonymous inner classes. + * @param access the access flags of C originally declared in the source code from which this + * class was compiled. */ public void visitInnerClass( final String name, final String outerName, final String innerName, final int access) { @@ -405,4 +428,3 @@ public void visitEnd() { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java index bb9f8e36a095f..d868b61c96546 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java @@ -249,6 +249,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; @@ -874,7 +875,7 @@ public int newUTF8(final String value) { * constant pool already contains a similar item. This method is intended for {@link Attribute} * sub classes, and is normally not needed by class generators or adapters. * - * @param value the internal name of the class. + * @param value the internal name of the class (see {@link Type#getInternalName()}). * @return the index of a new or already existing class reference item. */ public int newClass(final String value) { @@ -926,7 +927,8 @@ public int newPackage(final String packageName) { * Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link * Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. - * @param owner the internal name of the field or method owner class. + * @param owner the internal name of the field or method owner class (see {@link + * Type#getInternalName()}). * @param name the name of the field or method. * @param descriptor the descriptor of the field or method. * @return the index of a new or already existing method type reference item. @@ -948,7 +950,8 @@ public int newHandle( * Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link * Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. - * @param owner the internal name of the field or method owner class. + * @param owner the internal name of the field or method owner class (see {@link + * Type#getInternalName()}). * @param name the name of the field or method. * @param descriptor the descriptor of the field or method. * @param isInterface true if the owner is an interface. @@ -1010,7 +1013,7 @@ public int newInvokeDynamic( * constant pool already contains a similar item. This method is intended for {@link Attribute} * sub classes, and is normally not needed by class generators or adapters. * - * @param owner the internal name of the field's owner class. + * @param owner the internal name of the field's owner class (see {@link Type#getInternalName()}). * @param name the field's name. * @param descriptor the field's descriptor. * @return the index of a new or already existing field reference item. @@ -1024,7 +1027,8 @@ public int newField(final String owner, final String name, final String descript * constant pool already contains a similar item. This method is intended for {@link Attribute} * sub classes, and is normally not needed by class generators or adapters. * - * @param owner the internal name of the method's owner class. + * @param owner the internal name of the method's owner class (see {@link + * Type#getInternalName()}). * @param name the method's name. * @param descriptor the method's descriptor. * @param isInterface {@literal true} if {@code owner} is an interface. @@ -1060,9 +1064,10 @@ public int newNameType(final String name, final String descriptor) { * currently being generated by this ClassWriter, which can of course not be loaded since it is * under construction. * - * @param type1 the internal name of a class. - * @param type2 the internal name of another class. - * @return the internal name of the common super class of the two given classes. + * @param type1 the internal name of a class (see {@link Type#getInternalName()}). + * @param type2 the internal name of another class (see {@link Type#getInternalName()}). + * @return the internal name of the common super class of the two given classes (see {@link + * Type#getInternalName()}). */ protected String getCommonSuperClass(final String type1, final String type2) { ClassLoader classLoader = getClassLoader(); @@ -1105,4 +1110,3 @@ protected ClassLoader getClassLoader() { return getClass().getClassLoader(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ConstantDynamic.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ConstantDynamic.java index 457bec9c94a0f..cb992f839ef2d 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ConstantDynamic.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ConstantDynamic.java @@ -208,4 +208,3 @@ public String toString() { + Arrays.toString(bootstrapMethodArguments); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Constants.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Constants.java index cc10a3cee72af..9e097c2d03e7c 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Constants.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Constants.java @@ -223,15 +223,15 @@ static void checkAsmExperimental(final Object caller) { } static boolean isWhitelisted(final String internalName) { - if (!internalName.startsWith("jdk/internal/org/objectweb/asm/")) { + if (!internalName.startsWith("org/objectweb/asm/")) { return false; } String member = "(Annotation|Class|Field|Method|Module|RecordComponent|Signature)"; return internalName.contains("Test$") || Pattern.matches( - "jdk/internal/org/objectweb/asm/util/Trace" + member + "Visitor(\\$.*)?", internalName) + "org/objectweb/asm/util/Trace" + member + "Visitor(\\$.*)?", internalName) || Pattern.matches( - "jdk/internal/org/objectweb/asm/util/Check" + member + "Adapter(\\$.*)?", internalName); + "org/objectweb/asm/util/Check" + member + "Adapter(\\$.*)?", internalName); } static void checkIsPreview(final InputStream classInputStream) { @@ -251,4 +251,3 @@ static void checkIsPreview(final InputStream classInputStream) { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Context.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Context.java index 9b64452a096aa..bec67f5333b76 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Context.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Context.java @@ -166,4 +166,3 @@ final class Context { */ Object[] currentFrameStackTypes; } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/CurrentFrame.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/CurrentFrame.java index 32a4544dfd7e0..580b9a954156a 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/CurrentFrame.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/CurrentFrame.java @@ -85,4 +85,3 @@ void execute( copyFrom(successor); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Edge.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Edge.java index 3da370335ffe9..59a7ee83fdb41 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Edge.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Edge.java @@ -121,4 +121,3 @@ final class Edge { this.nextEdge = nextEdge; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java index 9cfe475150b7d..746cd00f0b35a 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java @@ -101,13 +101,26 @@ protected FieldVisitor(final int api, final FieldVisitor fieldVisitor) { && api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 - && api != Opcodes.ASM4) { + && api != Opcodes.ASM4 + && api != Opcodes.ASM10_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } + if (api == Opcodes.ASM10_EXPERIMENTAL) { + Constants.checkAsmExperimental(this); + } this.api = api; this.fv = fieldVisitor; } + /** + * The field visitor to which this visitor must delegate method calls. May be {@literal null}. + * + * @return the field visitor to which this visitor must delegate method calls, or {@literal null}. + */ + public FieldVisitor getDelegate() { + return fv; + } + /** * Visits an annotation of the field. * @@ -168,4 +181,3 @@ public void visitEnd() { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java index dd3b445056d80..c3e78d04cd69b 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java @@ -314,4 +314,3 @@ final void collectAttributePrototypes(final Attribute.Set attributePrototypes) { attributePrototypes.addAttributes(firstAttribute); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Frame.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Frame.java index 53cef11394334..358f9f6439c2f 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Frame.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Frame.java @@ -96,8 +96,8 @@ * right shift of {@link #DIM_SHIFT}. *
  • 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}. *
  • 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}. *
  • the VALUE field, stored in the remaining 20 bits, contains either @@ -110,7 +110,10 @@ *
  • 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}. *
  • 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}. + *
  • 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}. *
  • the index of a local variable in the input stack frame, if KIND is equal to {@link * #LOCAL_KIND}. *
  • a position relatively to the top of the stack of the input stack frame, if KIND is @@ -120,10 +123,10 @@ * *

    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). * *

    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 @@ -191,8 +194,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. @@ -252,13 +256,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 every occurrence 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 every + * occurrence 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; @@ -316,8 +320,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); + } } } @@ -399,11 +407,12 @@ private static int getAbstractTypeFromDescriptor( typeValue = REFERENCE_KIND | symbolTable.addType(internalName); break; default: - throw new IllegalArgumentException(); + throw new IllegalArgumentException( + "Invalid descriptor fragment: " + buffer.substring(elementDescriptorOffset)); } return ((elementDescriptorOffset - offset) << DIM_SHIFT) | typeValue; default: - throw new IllegalArgumentException(); + throw new IllegalArgumentException("Invalid descriptor: " + buffer.substring(offset)); } } @@ -611,11 +620,11 @@ private int pop() { */ private void pop(final int elements) { if (outputStackTop >= elements) { - outputStackTop -= (short) elements; + outputStackTop -= elements; } else { // If the number of elements to be popped is greater than the number of elements in the output // stack, clear it, and pop the remaining elements from the input stack. - outputStackStart -= (short) (elements - outputStackTop); + outputStackStart -= elements - outputStackTop; outputStackTop = 0; } } @@ -668,12 +677,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; @@ -1284,11 +1295,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. */ @@ -1431,7 +1443,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 JVMS * 4.7.4 @@ -1453,6 +1466,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(); } diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Handle.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Handle.java index 991fc6aabf588..7e5a9e1a3b36e 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Handle.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Handle.java @@ -96,7 +96,7 @@ public final class Handle { * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or {@link * Opcodes#H_INVOKEINTERFACE}. * @param owner the internal name of the class that owns the field or method designated by this - * handle. + * handle (see {@link Type#getInternalName()}). * @param name the name of the field or method designated by this handle. * @param descriptor the descriptor of the field or method designated by this handle. * @deprecated this constructor has been superseded by {@link #Handle(int, String, String, String, @@ -116,7 +116,7 @@ public Handle(final int tag, final String owner, final String name, final String * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or {@link * Opcodes#H_INVOKEINTERFACE}. * @param owner the internal name of the class that owns the field or method designated by this - * handle. + * handle (see {@link Type#getInternalName()}). * @param name the name of the field or method designated by this handle. * @param descriptor the descriptor of the field or method designated by this handle. * @param isInterface whether the owner is an interface or not. @@ -149,7 +149,8 @@ public int getTag() { /** * Returns the internal name of the class that owns the field or method designated by this handle. * - * @return the internal name of the class that owns the field or method designated by this handle. + * @return the internal name of the class that owns the field or method designated by this handle + * (see {@link Type#getInternalName()}). */ public String getOwner() { return owner; @@ -218,4 +219,3 @@ public String toString() { return owner + '.' + name + descriptor + " (" + tag + (isInterface ? " itf" : "") + ')'; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Handler.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Handler.java index 848a6d1e14c37..3d86e222ab8f3 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Handler.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Handler.java @@ -228,4 +228,3 @@ static void putExceptionTable(final Handler firstHandler, final ByteVector outpu } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Label.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Label.java index a24413f76635c..c321fc8a200be 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Label.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Label.java @@ -113,6 +113,9 @@ public class Label { /** A flag indicating that the basic block corresponding to a label is the end of a subroutine. */ static final int FLAG_SUBROUTINE_END = 64; + /** A flag indicating that this label has at least one associated line number. */ + static final int FLAG_LINE_NUMBER = 128; + /** * The number of elements to add to the {@link #otherLineNumbers} array when it needs to be * resized to store a new source line number. @@ -145,6 +148,13 @@ public class Label { */ static final int FORWARD_REFERENCE_TYPE_WIDE = 0x20000000; + /** + * The type of forward references stored in two bytes in the stack map table. 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, @@ -177,9 +187,9 @@ public class Label { short flags; /** - * The source line number corresponding to this label, or 0. If there are several source line - * numbers corresponding to this label, the first one is stored in this field, and the remaining - * ones are stored in {@link #otherLineNumbers}. + * The source line number corresponding to this label, if {@link #FLAG_LINE_NUMBER} is set. If + * there are several source line numbers corresponding to this label, the first one is stored in + * this field, and the remaining ones are stored in {@link #otherLineNumbers}. */ private short lineNumber; @@ -364,7 +374,8 @@ final Label getCanonicalInstance() { * @param lineNumber a source line number (which should be strictly positive). */ final void addLineNumber(final int lineNumber) { - if (this.lineNumber == 0) { + if ((flags & FLAG_LINE_NUMBER) == 0) { + flags |= FLAG_LINE_NUMBER; this.lineNumber = (short) lineNumber; } else { if (otherLineNumbers == null) { @@ -388,7 +399,7 @@ final void addLineNumber(final int lineNumber) { */ final void accept(final MethodVisitor methodVisitor, final boolean visitLineNumbers) { methodVisitor.visitLabel(this); - if (visitLineNumbers && lineNumber != 0) { + if (visitLineNumbers && (flags & FLAG_LINE_NUMBER) != 0) { methodVisitor.visitLineNumber(lineNumber & 0xFFFF, this); if (otherLineNumbers != null) { for (int i = 1; i <= otherLineNumbers[0]; ++i) { @@ -432,6 +443,20 @@ final void put( } } + /** + * Puts a reference to this label in the stack map table 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 @@ -464,9 +489,12 @@ 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 @@ -474,7 +502,8 @@ private void addForwardReference( * 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) { @@ -504,11 +533,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; @@ -652,4 +684,3 @@ public String toString() { return "L" + System.identityHashCode(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodTooLargeException.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodTooLargeException.java index 6c7252e35fb3d..a2c9cee1836da 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodTooLargeException.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodTooLargeException.java @@ -76,7 +76,7 @@ public final class MethodTooLargeException extends IndexOutOfBoundsException { /** * Constructs a new {@link MethodTooLargeException}. * - * @param className the internal name of the owner class. + * @param className the internal name of the owner class (see {@link Type#getInternalName()}). * @param methodName the name of the method. * @param descriptor the descriptor of the method. * @param codeSize the size of the method's Code attribute, in bytes. @@ -96,7 +96,7 @@ public MethodTooLargeException( /** * Returns the internal name of the owner class. * - * @return the internal name of the owner class. + * @return the internal name of the owner class (see {@link Type#getInternalName()}). */ public String getClassName() { return className; @@ -129,4 +129,3 @@ public int getCodeSize() { return codeSize; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java index 481592676e411..72ab34c7d63d6 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java @@ -62,7 +62,7 @@ /** * A visitor to visit a Java method. The methods of this class must be called in the following * order: ( {@code visitParameter} )* [ {@code visitAnnotationDefault} ] ( {@code visitAnnotation} | - * {@code visitAnnotableParameterCount} | {@code visitParameterAnnotation} {@code + * {@code visitAnnotableParameterCount} | {@code visitParameterAnnotation} | {@code * visitTypeAnnotation} | {@code visitAttribute} )* [ {@code visitCode} ( {@code visitFrame} | * {@code visitXInsn} | {@code visitLabel} | {@code visitInsnAnnotation} | {@code * visitTryCatchBlock} | {@code visitTryCatchAnnotation} | {@code visitLocalVariable} | {@code @@ -117,13 +117,27 @@ protected MethodVisitor(final int api, final MethodVisitor methodVisitor) { && api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 - && api != Opcodes.ASM4) { + && api != Opcodes.ASM4 + && api != Opcodes.ASM10_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } + if (api == Opcodes.ASM10_EXPERIMENTAL) { + Constants.checkAsmExperimental(this); + } this.api = api; this.mv = methodVisitor; } + /** + * The method visitor to which this visitor must delegate method calls. May be {@literal null}. + * + * @return the method visitor to which this visitor must delegate method calls, or {@literal + * null}. + */ + public MethodVisitor getDelegate() { + return mv; + } + // ----------------------------------------------------------------------------------------------- // Parameters, annotations and non standard attributes // ----------------------------------------------------------------------------------------------- @@ -150,7 +164,7 @@ public void visitParameter(final String name, final int access) { * @return a visitor to the visit the actual default value of this annotation interface method, or * {@literal null} if this visitor is not interested in visiting this default value. The * 'name' parameters passed to the methods of this annotation visitor are ignored. Moreover, - * exacly one visit method must be called on this annotation visitor, followed by visitEnd. + * exactly one visit method must be called on this annotation visitor, followed by visitEnd. */ public AnnotationVisitor visitAnnotationDefault() { if (mv != null) { @@ -303,15 +317,17 @@ public void visitCode() { * @param type the type of this stack map frame. Must be {@link Opcodes#F_NEW} for expanded * frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, {@link * Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames. - * @param numLocal the number of local variables in the visited frame. + * @param numLocal the number of local variables in the visited frame. Long and double values + * count for one variable. * @param local the local variable types in this frame. This array must not be modified. Primitive * types are represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link * Opcodes#FLOAT}, {@link Opcodes#LONG}, {@link Opcodes#DOUBLE}, {@link Opcodes#NULL} or * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a single element). - * Reference types are represented by String objects (representing internal names), and - * uninitialized types by Label objects (this label designates the NEW instruction that - * created this uninitialized value). - * @param numStack the number of operand stack elements in the visited frame. + * Reference types are represented by String objects (representing internal names, see {@link + * Type#getInternalName()}), and uninitialized types by Label objects (this label designates + * the NEW instruction that created this uninitialized value). + * @param numStack the number of operand stack elements in the visited frame. Long and double + * values count for one stack element. * @param stack the operand stack types in this frame. This array must not be modified. Its * content has the same format as the "local" array. * @throws IllegalStateException if a frame is visited just after another one, without any @@ -390,7 +406,7 @@ public void visitVarInsn(final int opcode, final int varIndex) { /** * Visits a type instruction. A type instruction is an instruction that takes the internal name of - * a class as parameter. + * a class as parameter (see {@link Type#getInternalName()}). * * @param opcode the opcode of the type instruction to be visited. This opcode is either NEW, * ANEWARRAY, CHECKCAST or INSTANCEOF. @@ -673,8 +689,9 @@ public AnnotationVisitor visitInsnAnnotation( * @param start the beginning of the exception handler's scope (inclusive). * @param end the end of the exception handler's scope (exclusive). * @param handler the beginning of the exception handler's code. - * @param type the internal name of the type of exceptions handled by the handler, or {@literal - * null} to catch any exceptions (for "finally" blocks). + * @param type the internal name of the type of exceptions handled by the handler (see {@link + * Type#getInternalName()}), or {@literal null} to catch any exceptions (for "finally" + * blocks). * @throws IllegalArgumentException if one of the labels has already been visited by this visitor * (by the {@link #visitLabel} method). */ @@ -812,4 +829,3 @@ public void visitEnd() { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java index 4260b9ae515a6..0b75f8bcb60bb 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java @@ -566,8 +566,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; @@ -725,7 +726,7 @@ 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( @@ -733,7 +734,7 @@ public AnnotationVisitor visitParameterAnnotation( } else { if (lastRuntimeInvisibleParameterAnnotations == null) { lastRuntimeInvisibleParameterAnnotations = - new AnnotationWriter[Type.getArgumentTypes(descriptor).length]; + new AnnotationWriter[Type.getArgumentCount(descriptor)]; } return lastRuntimeInvisibleParameterAnnotations[parameter] = AnnotationWriter.create( @@ -1231,7 +1232,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) { @@ -1244,7 +1245,7 @@ public void visitLabel(final Label label) { // one place, but this does not work for labels which have not been visited yet. // Therefore, when we detect here two labels having the same bytecode offset, we need to // - consolidate the state scattered in these two instances into the canonical instance: - currentBasicBlock.flags |= (short) (label.flags & Label.FLAG_JUMP_TARGET); + currentBasicBlock.flags |= (label.flags & Label.FLAG_JUMP_TARGET); // - make sure the two instances share the same Frame instance (the implementation of // {@link Label#getCanonicalInstance} relies on this property; here label.frame should be // null): @@ -1260,7 +1261,7 @@ public void visitLabel(final Label label) { if (lastBasicBlock != null) { if (label.bytecodeOffset == lastBasicBlock.bytecodeOffset) { // Same comment as above. - lastBasicBlock.flags |= (short) (label.flags & Label.FLAG_JUMP_TARGET); + lastBasicBlock.flags |= (label.flags & Label.FLAG_JUMP_TARGET); // Here label.frame should be null. label.frame = lastBasicBlock.frame; currentBasicBlock = lastBasicBlock; @@ -1827,7 +1828,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; @@ -2011,9 +2012,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); } } diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleVisitor.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleVisitor.java index 7a3cbf016149d..e623362e5e7c8 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleVisitor.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleVisitor.java @@ -103,17 +103,32 @@ protected ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) { && api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 - && api != Opcodes.ASM4) { + && api != Opcodes.ASM4 + && api != Opcodes.ASM10_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } + if (api == Opcodes.ASM10_EXPERIMENTAL) { + Constants.checkAsmExperimental(this); + } this.api = api; this.mv = moduleVisitor; } + /** + * The module visitor to which this visitor must delegate method calls. May be {@literal null}. + * + * @return the module visitor to which this visitor must delegate method calls, or {@literal + * null}. + */ + public ModuleVisitor getDelegate() { + return mv; + } + /** * Visit the main class of the current module. * - * @param mainClass the internal name of the main class of the current module. + * @param mainClass the internal name of the main class of the current module (see {@link + * Type#getInternalName()}). */ public void visitMainClass(final String mainClass) { if (mv != null) { @@ -124,7 +139,7 @@ public void visitMainClass(final String mainClass) { /** * Visit a package of the current module. * - * @param packaze the internal name of a package. + * @param packaze the internal name of a package (see {@link Type#getInternalName()}). */ public void visitPackage(final String packaze) { if (mv != null) { @@ -149,7 +164,7 @@ public void visitRequire(final String module, final int access, final String ver /** * Visit an exported package of the current module. * - * @param packaze the internal name of the exported package. + * @param packaze the internal name of the exported package (see {@link Type#getInternalName()}). * @param access the access flag of the exported package, valid values are among {@code * ACC_SYNTHETIC} and {@code ACC_MANDATED}. * @param modules the fully qualified names (using dots) of the modules that can access the public @@ -164,7 +179,7 @@ public void visitExport(final String packaze, final int access, final String... /** * Visit an open package of the current module. * - * @param packaze the internal name of the opened package. + * @param packaze the internal name of the opened package (see {@link Type#getInternalName()}). * @param access the access flag of the opened package, valid values are among {@code * ACC_SYNTHETIC} and {@code ACC_MANDATED}. * @param modules the fully qualified names (using dots) of the modules that can use deep @@ -180,7 +195,7 @@ public void visitOpen(final String packaze, final int access, final String... mo * Visit a service used by the current module. The name must be the internal name of an interface * or a class. * - * @param service the internal name of the service. + * @param service the internal name of the service (see {@link Type#getInternalName()}). */ public void visitUse(final String service) { if (mv != null) { @@ -191,9 +206,9 @@ public void visitUse(final String service) { /** * Visit an implementation of a service. * - * @param service the internal name of the service. - * @param providers the internal names of the implementations of the service (there is at least - * one provider). + * @param service the internal name of the service (see {@link Type#getInternalName()}). + * @param providers the internal names (see {@link Type#getInternalName()}) of the implementations + * of the service (there is at least one provider). */ public void visitProvide(final String service, final String... providers) { if (mv != null) { @@ -211,4 +226,3 @@ public void visitEnd() { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleWriter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleWriter.java index 8680488d7a0e0..18b1a22fb36ae 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleWriter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleWriter.java @@ -283,4 +283,3 @@ void putAttributes(final ByteVector output) { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java index edb118cfce427..b9d4d83b042c2 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java @@ -82,6 +82,14 @@ public interface Opcodes { int ASM8 = 8 << 16 | 0 << 8; int ASM9 = 9 << 16 | 0 << 8; + /** + * 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. + * + * @deprecated This API is experimental. + */ + @Deprecated int ASM10_EXPERIMENTAL = 1 << 24 | 10 << 16 | 0 << 8; + /* * Internal flags used to redirect calls to deprecated methods. For instance, if a visitOldStuff * method in API_OLD is deprecated and replaced with visitNewStuff in API_NEW, then the @@ -312,7 +320,6 @@ public interface Opcodes { int V20 = 0 << 16 | 64; int V21 = 0 << 16 | 65; int V22 = 0 << 16 | 66; - int V23 = 0 << 16 | 67; /** * Version flag indicating that the class is using 'preview' features. @@ -588,4 +595,3 @@ public interface Opcodes { int IFNULL = 198; // visitJumpInsn int IFNONNULL = 199; // - } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/RecordComponentVisitor.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/RecordComponentVisitor.java index e0e55462f3705..1f4fed219c175 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/RecordComponentVisitor.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/RecordComponentVisitor.java @@ -77,7 +77,7 @@ public abstract class RecordComponentVisitor { /** * The record visitor to which this visitor must delegate method calls. May be {@literal null}. */ - /*package-private*/ RecordComponentVisitor delegate; + protected RecordComponentVisitor delegate; /** * Constructs a new {@link RecordComponentVisitor}. @@ -103,9 +103,13 @@ protected RecordComponentVisitor( && api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 - && api != Opcodes.ASM4) { + && api != Opcodes.ASM4 + && api != Opcodes.ASM10_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } + if (api == Opcodes.ASM10_EXPERIMENTAL) { + Constants.checkAsmExperimental(this); + } this.api = api; this.delegate = recordComponentVisitor; } @@ -113,7 +117,8 @@ protected RecordComponentVisitor( /** * The record visitor to which this visitor must delegate method calls. May be {@literal null}. * - * @return the record visitor to which this visitor must delegate method calls or {@literal null}. + * @return the record visitor to which this visitor must delegate method calls, or {@literal + * null}. */ public RecordComponentVisitor getDelegate() { return delegate; @@ -178,4 +183,3 @@ public void visitEnd() { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/RecordComponentWriter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/RecordComponentWriter.java index 47a27debd655f..3098cf70c8dd6 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/RecordComponentWriter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/RecordComponentWriter.java @@ -255,4 +255,3 @@ final void collectAttributePrototypes(final Attribute.Set attributePrototypes) { attributePrototypes.addAttributes(firstAttribute); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Symbol.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Symbol.java index a6b17c650afb1..a45f75a03017e 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Symbol.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Symbol.java @@ -135,12 +135,25 @@ abstract class Symbol { 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. @@ -183,8 +196,8 @@ abstract class Symbol { * #CONSTANT_INVOKE_DYNAMIC_TAG} symbols, *

  • an arbitrary string for {@link #CONSTANT_UTF8_TAG} and {@link #CONSTANT_STRING_TAG} * symbols, - *
  • an internal class name for {@link #CONSTANT_CLASS_TAG}, {@link #TYPE_TAG} and {@link - * #UNINITIALIZED_TYPE_TAG} symbols, + *
  • an internal class name for {@link #CONSTANT_CLASS_TAG}, {@link #TYPE_TAG}, {@link + * #UNINITIALIZED_TYPE_TAG} and {@link #FORWARD_UNINITIALIZED_TYPE_TAG} symbols, *
  • {@literal null} for the other types of symbol. * */ @@ -204,6 +217,9 @@ abstract class Symbol { * {@link #CONSTANT_DYNAMIC_TAG} or {@link #BOOTSTRAP_METHOD_TAG} symbols, *
  • the bytecode offset of the NEW instruction that created an {@link * Frame#ITEM_UNINITIALIZED} type for {@link #UNINITIALIZED_TYPE_TAG} symbols, + *
  • 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, *
  • the indices (in the class' type table) of two {@link #TYPE_TAG} source types for {@link * #MERGED_TYPE_TAG} symbols, *
  • 0 for the other types of symbol. @@ -273,4 +289,3 @@ int getArgumentsAndReturnSizes() { return info; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/SymbolTable.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/SymbolTable.java index 2ca923859f4a1..5fc629d680970 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/SymbolTable.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/SymbolTable.java @@ -140,11 +140,35 @@ final class SymbolTable { * 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. * @@ -1161,6 +1185,18 @@ Symbol getType(final int typeIndex) { return typeTable[typeIndex]; } + /** + * 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. @@ -1181,13 +1217,13 @@ int addType(final String value) { } /** - * 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); @@ -1205,6 +1241,32 @@ int addUninitializedType(final String value, final int bytecodeOffset) { new Entry(typeCount, Symbol.UNINITIALIZED_TYPE_TAG, value, bytecodeOffset, hashCode)); } + /** + * 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. @@ -1257,6 +1319,59 @@ private int addTypeInternal(final Entry entry) { 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. // ----------------------------------------------------------------------------------------------- @@ -1307,7 +1422,7 @@ private static int hash( * * @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; @@ -1351,5 +1466,30 @@ private static class Entry extends Symbol { 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/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java index 801b88033248f..739b9444d2ee5 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java @@ -277,7 +277,7 @@ public Type getElementType() { /** * Returns the {@link Type} corresponding to the given internal name. * - * @param internalName an internal name. + * @param internalName an internal name (see {@link Type#getInternalName()}). * @return the {@link Type} corresponding to the given internal name. */ public static Type getObjectType(final String internalName) { @@ -327,26 +327,12 @@ public Type[] getArgumentTypes() { */ 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) != ')') { @@ -734,6 +720,43 @@ public int getSize() { } } + /** + * 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. @@ -741,7 +764,8 @@ public int getSize() { * @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()); @@ -754,7 +778,8 @@ public int getArgumentsAndReturnSizes() { * @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; @@ -925,4 +950,3 @@ public String toString() { return getDescriptor(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/TypePath.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/TypePath.java index 9725e5b04488e..ea1025dd172b4 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/TypePath.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/TypePath.java @@ -230,4 +230,3 @@ static void put(final TypePath typePath, final ByteVector output) { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/TypeReference.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/TypeReference.java index 92a1c94eb0fe9..512dc8fc8ac75 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/TypeReference.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/TypeReference.java @@ -465,4 +465,3 @@ static void putTarget(final int targetTypeAndInfo, final ByteVector output) { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java index 8f321f2ec77ca..0d57c484f0509 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java @@ -700,4 +700,3 @@ protected void onMethodEnter() {} */ protected void onMethodExit(final int opcode) {} } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java index 32d47d1a67ca6..36a5a06d44102 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java @@ -92,9 +92,10 @@ public class AnalyzerAdapter extends MethodVisitor { * {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or {@link Opcodes#UNINITIALIZED_THIS} (long and * double are represented by two elements, the second one being TOP). Reference types are - * represented by String objects (representing internal names), and uninitialized types by Label - * objects (this label designates the NEW instruction that created this uninitialized value). This - * field is {@literal null} for unreachable instructions. + * represented by String objects (representing internal names, see {@link + * Type#getInternalName()}), and uninitialized types by Label objects (this label designates the + * NEW instruction that created this uninitialized value). This field is {@literal null} for + * unreachable instructions. */ public List locals; @@ -103,9 +104,10 @@ public class AnalyzerAdapter extends MethodVisitor { * {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or {@link Opcodes#UNINITIALIZED_THIS} (long and * double are represented by two elements, the second one being TOP). Reference types are - * represented by String objects (representing internal names), and uninitialized types by Label - * objects (this label designates the NEW instruction that created this uninitialized value). This - * field is {@literal null} for unreachable instructions. + * represented by String objects (representing internal names, see {@link + * Type#getInternalName()}), and uninitialized types by Label objects (this label designates the + * NEW instruction that created this uninitialized value). This field is {@literal null} for + * unreachable instructions. */ public List stack; @@ -114,9 +116,9 @@ public class AnalyzerAdapter extends MethodVisitor { /** * The uninitialized types in the current execution frame. This map associates internal names to - * Label objects. Each label designates a NEW instruction that created the currently uninitialized - * types, and the associated internal name represents the NEW operand, i.e. the final, initialized - * type value. + * Label objects (see {@link Type#getInternalName()}). Each label designates a NEW instruction + * that created the currently uninitialized types, and the associated internal name represents the + * NEW operand, i.e. the final, initialized type value. */ public Map uninitializedTypes; @@ -338,7 +340,7 @@ public void visitMethodInsn( if (value == Opcodes.UNINITIALIZED_THIS) { initializedValue = this.owner; } else { - initializedValue = uninitializedTypes.get(value); + initializedValue = owner; } for (int i = 0; i < locals.size(); ++i) { if (locals.get(i) == value) { @@ -938,4 +940,3 @@ private void execute(final int opcode, final int intArg, final String stringArg) labels = null; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnnotationRemapper.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnnotationRemapper.java index 68535046acf04..4fdfbccc06b01 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnnotationRemapper.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnnotationRemapper.java @@ -227,7 +227,7 @@ final AnnotationVisitor orDeprecatedValue(final AnnotationVisitor deprecatedAnno /** * Maps an annotation attribute name with the remapper. Returns the original name unchanged if the - * internal name of the annotation is {@literal null}. + * descriptor of the annotation is {@literal null}. * * @param name the name of the annotation attribute. * @return the new name of the annotation attribute. @@ -239,4 +239,3 @@ private String mapAnnotationAttributeName(final String name) { return remapper.mapAnnotationAttributeName(descriptor, name); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java index 519f488b1bf69..03a576189d42f 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java @@ -329,4 +329,3 @@ protected RecordComponentVisitor createRecordComponentRemapper( return new RecordComponentRemapper(api, recordComponentVisitor, remapper); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java index 5d7bb2cc91244..2392cdcd0bee5 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java @@ -237,4 +237,3 @@ public void visitMultiANewArrayInsn(final String descriptor, final int numDimens super.visitMultiANewArrayInsn(descriptor, numDimensions); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/FieldRemapper.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/FieldRemapper.java index 2e8a1ad4debdc..205f985d87e46 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/FieldRemapper.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/FieldRemapper.java @@ -144,4 +144,3 @@ protected AnnotationVisitor createAnnotationRemapper( .orDeprecatedValue(createAnnotationRemapper(annotationVisitor)); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java index 6dd35ba2a2c9a..ecf4ac10dfbca 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java @@ -308,7 +308,7 @@ public GeneratorAdapter( * Returns the internal names of the given types. * * @param types a set of types. - * @return the internal names of the given types. + * @return the internal names of the given types (see {@link Type#getInternalName()}). */ private static String[] getInternalNames(final Type[] types) { String[] names = new String[types.length]; @@ -1386,7 +1386,8 @@ public void endMethod() { * * @param start beginning of the exception handler's scope (inclusive). * @param end end of the exception handler's scope (exclusive). - * @param exception internal name of the type of exceptions handled by the handler. + * @param exception internal name of the type of exceptions handled by the handler (see {@link + * Type#getInternalName()}). */ public void catchException(final Label start, final Label end, final Type exception) { Label catchLabel = new Label(); @@ -1398,4 +1399,3 @@ public void catchException(final Label start, final Label end, final Type except mark(catchLabel); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java index 033956f1c7e9b..e449c310b3b14 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java @@ -1094,7 +1094,8 @@ public void putfield(final String owner, final String name, final String descrip /** * Deprecated. * - * @param owner the internal name of the method's owner class. + * @param owner the internal name of the method's owner class (see {@link + * Type#getInternalName()}). * @param name the method's name. * @param descriptor the method's descriptor (see {@link Type}). * @deprecated use {@link #invokevirtual(String, String, String, boolean)} instead. @@ -1132,7 +1133,8 @@ public void invokevirtual( /** * Deprecated. * - * @param owner the internal name of the method's owner class. + * @param owner the internal name of the method's owner class (see {@link + * Type#getInternalName()}). * @param name the method's name. * @param descriptor the method's descriptor (see {@link Type}). * @deprecated use {@link #invokespecial(String, String, String, boolean)} instead. @@ -1170,7 +1172,8 @@ public void invokespecial( /** * Deprecated. * - * @param owner the internal name of the method's owner class. + * @param owner the internal name of the method's owner class (see {@link + * Type#getInternalName()}). * @param name the method's name. * @param descriptor the method's descriptor (see {@link Type}). * @deprecated use {@link #invokestatic(String, String, String, boolean)} instead. @@ -1329,4 +1332,3 @@ public void mark(final Label label) { mv.visitLabel(label); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java index 2e2a42c3d7c57..2f1565222ec97 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java @@ -120,7 +120,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes { * @param name the method's name. * @param descriptor the method's descriptor. * @param signature the method's signature. May be {@literal null}. - * @param exceptions the internal names of the method's exception classes. May be {@literal null}. + * @param exceptions the internal names of the method's exception classes (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. * @throws IllegalStateException if a subclass calls this constructor. */ public JSRInlinerAdapter( @@ -155,7 +156,8 @@ public JSRInlinerAdapter( * @param name the method's name. * @param descriptor the method's descriptor. * @param signature the method's signature. May be {@literal null}. - * @param exceptions the internal names of the method's exception classes. May be {@literal null}. + * @param exceptions the internal names of the method's exception classes (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. */ protected JSRInlinerAdapter( final int api, @@ -455,7 +457,7 @@ private void emitInstantiation( } /** An instantiation of a subroutine. */ - private class Instantiation extends AbstractMap { + private final class Instantiation extends AbstractMap { /** * The instantiation from which this one was created (or {@literal null} for the instantiation @@ -600,4 +602,3 @@ public int hashCode() { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java index aadef75577853..c406334094322 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java @@ -381,4 +381,3 @@ protected int newLocalMapping(final Type type) { return local; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java index 1fcab96f1813c..96b1885308ccf 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java @@ -292,4 +292,3 @@ public int hashCode() { return name.hashCode() ^ descriptor.hashCode(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/MethodRemapper.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/MethodRemapper.java index 7b27a52e0757e..c2335077e8b3a 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/MethodRemapper.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/MethodRemapper.java @@ -319,4 +319,3 @@ protected AnnotationVisitor createAnnotationRemapper( .orDeprecatedValue(createAnnotationRemapper(annotationVisitor)); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleHashesAttribute.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleHashesAttribute.java index 5b4cc253c39e8..7bf0934ab2ea9 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleHashesAttribute.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleHashesAttribute.java @@ -168,4 +168,3 @@ protected ByteVector write( return byteVector; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleRemapper.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleRemapper.java index 135ae6d31d6fa..d843a715451d8 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleRemapper.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleRemapper.java @@ -150,4 +150,3 @@ public void visitProvide(final String service, final String... providers) { super.visitProvide(remapper.mapType(service), remappedProviders); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleResolutionAttribute.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleResolutionAttribute.java index 8187ad30e0cc7..5ccee829a902e 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleResolutionAttribute.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleResolutionAttribute.java @@ -142,4 +142,3 @@ protected ByteVector write( return byteVector; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleTargetAttribute.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleTargetAttribute.java index 4d92734a972e4..8d61baadd2e08 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleTargetAttribute.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleTargetAttribute.java @@ -116,4 +116,3 @@ protected ByteVector write( return byteVector; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RecordComponentRemapper.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RecordComponentRemapper.java index 6974b05d71e8e..017f24a74405b 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RecordComponentRemapper.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RecordComponentRemapper.java @@ -147,4 +147,3 @@ protected AnnotationVisitor createAnnotationRemapper( .orDeprecatedValue(createAnnotationRemapper(annotationVisitor)); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java index 41fe75e41436c..aba7f0f21ff17 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java @@ -80,7 +80,7 @@ public abstract class Remapper { * @param descriptor a type descriptor. * @return the given descriptor, with its [array element type] internal name remapped with {@link * #map(String)} (if the descriptor corresponds to an array or object type, otherwise the - * descriptor is returned as is). + * descriptor is returned as is). See {@link Type#getInternalName()}. */ public String mapDesc(final String descriptor) { return mapType(Type.getType(descriptor)).getDescriptor(); @@ -94,7 +94,7 @@ public String mapDesc(final String descriptor) { * @return the given type, with its [array element type] internal name remapped with {@link * #map(String)} (if the type is an array or object type, otherwise the type is returned as * is) or, of the type is a method type, with its descriptor remapped with {@link - * #mapMethodDesc(String)}. + * #mapMethodDesc(String)}. See {@link Type#getInternalName()}. */ private Type mapType(final Type type) { switch (type.getSort()) { @@ -118,8 +118,10 @@ private Type mapType(final Type type) { /** * Returns the given internal name, remapped with {@link #map(String)}. * - * @param internalName the internal name (or array type descriptor) of some (array) class. - * @return the given internal name, remapped with {@link #map(String)}. + * @param internalName the internal name (or array type descriptor) of some (array) class (see + * {@link Type#getInternalName()}). + * @return the given internal name, remapped with {@link #map(String)} (see {@link + * Type#getInternalName()}). */ public String mapType(final String internalName) { if (internalName == null) { @@ -131,8 +133,10 @@ public String mapType(final String internalName) { /** * Returns the given internal names, remapped with {@link #map(String)}. * - * @param internalNames the internal names (or array type descriptors) of some (array) classes. - * @return the given internal name, remapped with {@link #map(String)}. + * @param internalNames the internal names (or array type descriptors) of some (array) classes + * (see {@link Type#getInternalName()}). + * @return the given internal name, remapped with {@link #map(String)} (see {@link + * Type#getInternalName()}). */ public String[] mapTypes(final String[] internalNames) { String[] remappedInternalNames = null; @@ -286,14 +290,30 @@ public String mapAnnotationAttributeName(final String descriptor, final String n * strategy that will work for inner classes produced by Java, but not necessarily other * languages. Subclasses can override. * - * @param name the fully-qualified internal name of the inner class. - * @param ownerName the internal name of the owner class of the inner class. - * @param innerName the internal name of the inner class. + * @param name the fully-qualified internal name of the inner class (see {@link + * Type#getInternalName()}). + * @param ownerName the internal name of the owner class of the inner class (see {@link + * Type#getInternalName()}). + * @param innerName the internal name of the inner class (see {@link Type#getInternalName()}). * @return the new inner name of the inner class. */ public String mapInnerClassName( final String name, final String ownerName, final String innerName) { final String remappedInnerName = this.mapType(name); + + if (remappedInnerName.equals(name)) { + return innerName; + } else { + int originSplit = name.lastIndexOf('/'); + int remappedSplit = remappedInnerName.lastIndexOf('/'); + if (originSplit != -1 && remappedSplit != -1) { + if (name.substring(originSplit).equals(remappedInnerName.substring(remappedSplit))) { + // class name not changed + return innerName; + } + } + } + if (remappedInnerName.contains("$")) { int index = remappedInnerName.lastIndexOf('$') + 1; while (index < remappedInnerName.length() @@ -310,7 +330,8 @@ public String mapInnerClassName( * Maps a method name to its new name. The default implementation of this method returns the given * name, unchanged. Subclasses can override. * - * @param owner the internal name of the owner class of the method. + * @param owner the internal name of the owner class of the method (see {@link + * Type#getInternalName()}). * @param name the name of the method. * @param descriptor the descriptor of the method. * @return the new name of the method. @@ -335,7 +356,8 @@ public String mapInvokeDynamicMethodName(final String name, final String descrip * Maps a record component name to its new name. The default implementation of this method returns * the given name, unchanged. Subclasses can override. * - * @param owner the internal name of the owner class of the field. + * @param owner the internal name of the owner class of the field (see {@link + * Type#getInternalName()}). * @param name the name of the field. * @param descriptor the descriptor of the field. * @return the new name of the field. @@ -349,7 +371,8 @@ public String mapRecordComponentName( * Maps a field name to its new name. The default implementation of this method returns the given * name, unchanged. Subclasses can override. * - * @param owner the internal name of the owner class of the field. + * @param owner the internal name of the owner class of the field (see {@link + * Type#getInternalName()}). * @param name the name of the field. * @param descriptor the descriptor of the field. * @return the new name of the field. @@ -384,11 +407,10 @@ public String mapModuleName(final String name) { * Maps the internal name of a class to its new name. The default implementation of this method * returns the given name, unchanged. Subclasses can override. * - * @param internalName the internal name of a class. - * @return the new internal name. + * @param internalName the internal name of a class (see {@link Type#getInternalName()}). + * @return the new internal name (see {@link Type#getInternalName()}). */ public String map(final String internalName) { return internalName; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java deleted file mode 100644 index 0f41cff5354c1..0000000000000 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * This file is available under and governed by the GNU General Public - * License version 2 only, as published by the Free Software Foundation. - * However, the following notice accompanied the original version of this - * file: - * - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package jdk.internal.org.objectweb.asm.commons; - -import jdk.internal.org.objectweb.asm.AnnotationVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; - -/** - * An {@link AnnotationVisitor} adapter for type remapping. - * - * @deprecated use {@link AnnotationRemapper} instead. - * @author Eugene Kuleshov - */ -@Deprecated -public class RemappingAnnotationAdapter extends AnnotationVisitor { - - protected final Remapper remapper; - - public RemappingAnnotationAdapter( - final AnnotationVisitor annotationVisitor, final Remapper remapper) { - this(Opcodes.ASM9, annotationVisitor, remapper); - } - - protected RemappingAnnotationAdapter( - final int api, final AnnotationVisitor annotationVisitor, final Remapper remapper) { - super(api, annotationVisitor); - this.remapper = remapper; - } - - @Override - public void visit(final String name, final Object value) { - av.visit(name, remapper.mapValue(value)); - } - - @Override - public void visitEnum(final String name, final String descriptor, final String value) { - av.visitEnum(name, remapper.mapDesc(descriptor), value); - } - - @Override - public AnnotationVisitor visitAnnotation(final String name, final String descriptor) { - AnnotationVisitor annotationVisitor = av.visitAnnotation(name, remapper.mapDesc(descriptor)); - return annotationVisitor == null - ? null - : (annotationVisitor == av - ? this - : new RemappingAnnotationAdapter(annotationVisitor, remapper)); - } - - @Override - public AnnotationVisitor visitArray(final String name) { - AnnotationVisitor annotationVisitor = av.visitArray(name); - return annotationVisitor == null - ? null - : (annotationVisitor == av - ? this - : new RemappingAnnotationAdapter(annotationVisitor, remapper)); - } -} - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java deleted file mode 100644 index 68ad22a479320..0000000000000 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * This file is available under and governed by the GNU General Public - * License version 2 only, as published by the Free Software Foundation. - * However, the following notice accompanied the original version of this - * file: - * - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package jdk.internal.org.objectweb.asm.commons; - -import jdk.internal.org.objectweb.asm.AnnotationVisitor; -import jdk.internal.org.objectweb.asm.Handle; -import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.TypePath; - -/** - * A {@link LocalVariablesSorter} for type mapping. - * - * @deprecated use {@link MethodRemapper} instead. - * @author Eugene Kuleshov - */ -@Deprecated -public class RemappingMethodAdapter extends LocalVariablesSorter { - - protected final Remapper remapper; - - public RemappingMethodAdapter( - final int access, - final String descriptor, - final MethodVisitor methodVisitor, - final Remapper remapper) { - this(Opcodes.ASM9, access, descriptor, methodVisitor, remapper); - } - - protected RemappingMethodAdapter( - final int api, - final int access, - final String descriptor, - final MethodVisitor methodVisitor, - final Remapper remapper) { - super(api, access, descriptor, methodVisitor); - this.remapper = remapper; - } - - @Override - public AnnotationVisitor visitAnnotationDefault() { - AnnotationVisitor annotationVisitor = super.visitAnnotationDefault(); - return annotationVisitor == null - ? annotationVisitor - : new RemappingAnnotationAdapter(annotationVisitor, remapper); - } - - @Override - public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { - AnnotationVisitor annotationVisitor = - super.visitAnnotation(remapper.mapDesc(descriptor), visible); - return annotationVisitor == null - ? annotationVisitor - : new RemappingAnnotationAdapter(annotationVisitor, remapper); - } - - @Override - public AnnotationVisitor visitTypeAnnotation( - final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { - AnnotationVisitor annotationVisitor = - super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); - return annotationVisitor == null - ? annotationVisitor - : new RemappingAnnotationAdapter(annotationVisitor, remapper); - } - - @Override - public AnnotationVisitor visitParameterAnnotation( - final int parameter, final String descriptor, final boolean visible) { - AnnotationVisitor annotationVisitor = - super.visitParameterAnnotation(parameter, remapper.mapDesc(descriptor), visible); - return annotationVisitor == null - ? annotationVisitor - : new RemappingAnnotationAdapter(annotationVisitor, remapper); - } - - @Override - public void visitFrame( - final int type, - final int numLocal, - final Object[] local, - final int numStack, - final Object[] stack) { - super.visitFrame( - type, numLocal, remapEntries(numLocal, local), numStack, remapEntries(numStack, stack)); - } - - private Object[] remapEntries(final int numTypes, final Object[] entries) { - if (entries == null) { - return entries; - } - Object[] remappedEntries = null; - for (int i = 0; i < numTypes; ++i) { - if (entries[i] instanceof String) { - if (remappedEntries == null) { - remappedEntries = new Object[numTypes]; - System.arraycopy(entries, 0, remappedEntries, 0, numTypes); - } - remappedEntries[i] = remapper.mapType((String) entries[i]); - } - } - return remappedEntries == null ? entries : remappedEntries; - } - - @Override - public void visitFieldInsn( - final int opcode, final String owner, final String name, final String descriptor) { - super.visitFieldInsn( - opcode, - remapper.mapType(owner), - remapper.mapFieldName(owner, name, descriptor), - remapper.mapDesc(descriptor)); - } - - @Deprecated - @Override - public void visitMethodInsn( - final int opcode, final String owner, final String name, final String descriptor) { - if (api >= Opcodes.ASM5) { - super.visitMethodInsn(opcode, owner, name, descriptor); - return; - } - doVisitMethodInsn(opcode, owner, name, descriptor, opcode == Opcodes.INVOKEINTERFACE); - } - - @Override - public void visitMethodInsn( - final int opcode, - final String owner, - final String name, - final String descriptor, - final boolean isInterface) { - if (api < Opcodes.ASM5) { - super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); - return; - } - doVisitMethodInsn(opcode, owner, name, descriptor, isInterface); - } - - private void doVisitMethodInsn( - final int opcode, - final String owner, - final String name, - final String descriptor, - final boolean isInterface) { - // Calling super.visitMethodInsn requires to call the correct version - // depending on this.api (otherwise infinite loops can occur). To - // simplify and to make it easier to automatically remove the backward - // compatibility code, we inline the code of the overridden method here. - // IMPORTANT: THIS ASSUMES THAT visitMethodInsn IS NOT OVERRIDDEN IN - // LocalVariableSorter. - if (mv != null) { - mv.visitMethodInsn( - opcode, - remapper.mapType(owner), - remapper.mapMethodName(owner, name, descriptor), - remapper.mapMethodDesc(descriptor), - isInterface); - } - } - - @Override - public void visitInvokeDynamicInsn( - final String name, - final String descriptor, - final Handle bootstrapMethodHandle, - final Object... bootstrapMethodArguments) { - for (int i = 0; i < bootstrapMethodArguments.length; i++) { - bootstrapMethodArguments[i] = remapper.mapValue(bootstrapMethodArguments[i]); - } - super.visitInvokeDynamicInsn( - remapper.mapInvokeDynamicMethodName(name, descriptor), - remapper.mapMethodDesc(descriptor), - (Handle) remapper.mapValue(bootstrapMethodHandle), - bootstrapMethodArguments); - } - - @Override - public void visitTypeInsn(final int opcode, final String type) { - super.visitTypeInsn(opcode, remapper.mapType(type)); - } - - @Override - public void visitLdcInsn(final Object value) { - super.visitLdcInsn(remapper.mapValue(value)); - } - - @Override - public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) { - super.visitMultiANewArrayInsn(remapper.mapDesc(descriptor), numDimensions); - } - - @Override - public AnnotationVisitor visitInsnAnnotation( - final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { - AnnotationVisitor annotationVisitor = - super.visitInsnAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); - return annotationVisitor == null - ? annotationVisitor - : new RemappingAnnotationAdapter(annotationVisitor, remapper); - } - - @Override - public void visitTryCatchBlock( - final Label start, final Label end, final Label handler, final String type) { - super.visitTryCatchBlock(start, end, handler, type == null ? null : remapper.mapType(type)); - } - - @Override - public AnnotationVisitor visitTryCatchAnnotation( - final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { - AnnotationVisitor annotationVisitor = - super.visitTryCatchAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); - return annotationVisitor == null - ? annotationVisitor - : new RemappingAnnotationAdapter(annotationVisitor, remapper); - } - - @Override - public void visitLocalVariable( - final String name, - final String descriptor, - final String signature, - final Label start, - final Label end, - final int index) { - super.visitLocalVariable( - name, - remapper.mapDesc(descriptor), - remapper.mapSignature(signature, true), - start, - end, - index); - } - - @Override - public AnnotationVisitor visitLocalVariableAnnotation( - final int typeRef, - final TypePath typePath, - final Label[] start, - final Label[] end, - final int[] index, - final String descriptor, - final boolean visible) { - AnnotationVisitor annotationVisitor = - super.visitLocalVariableAnnotation( - typeRef, typePath, start, end, index, remapper.mapDesc(descriptor), visible); - return annotationVisitor == null - ? annotationVisitor - : new RemappingAnnotationAdapter(annotationVisitor, remapper); - } -} - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java index a453500143bb6..58173483b191b 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java @@ -522,4 +522,3 @@ public int hashCode() { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SignatureRemapper.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SignatureRemapper.java index 1d9d4d87f821e..5fb41c84ccac3 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SignatureRemapper.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SignatureRemapper.java @@ -202,4 +202,3 @@ public void visitEnd() { classNames.remove(classNames.size() - 1); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SimpleRemapper.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SimpleRemapper.java index 314738e3b2e94..9b298b15e398b 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SimpleRemapper.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SimpleRemapper.java @@ -85,7 +85,7 @@ public class SimpleRemapper extends Remapper { * attribute (in the form <owner>.<name>), and the value is the new field * name. *
  • for internal names, the key is the old internal name, and the value is the new - * internal name. + * internal name (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName()}). * */ public SimpleRemapper(final Map mapping) { @@ -97,7 +97,8 @@ public SimpleRemapper(final Map mapping) { * * @param oldName the key corresponding to a method, field or internal name (see {@link * #SimpleRemapper(Map)} for the format of these keys). - * @param newName the new method, field or internal name. + * @param newName the new method, field or internal name (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). */ public SimpleRemapper(final String oldName, final String newName) { this.mapping = Collections.singletonMap(oldName, newName); @@ -132,4 +133,3 @@ public String map(final String key) { return mapping.get(key); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java index 25d4fbcb5d9ad..1a03a9e0923f4 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java @@ -154,4 +154,3 @@ public void visitEnd() { super.visitEnd(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TableSwitchGenerator.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TableSwitchGenerator.java index 69db3287c4096..0f8ada93b3993 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TableSwitchGenerator.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TableSwitchGenerator.java @@ -81,4 +81,3 @@ public interface TableSwitchGenerator { /** Generates the code for the default switch case. */ void generateDefault(); } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java index f64766572d221..6cd6b1ec08b93 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java @@ -155,4 +155,3 @@ private int blockLength(final TryCatchBlockNode tryCatchBlockNode) { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureReader.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureReader.java index 9870ea5f72bde..76901452a4c21 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureReader.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureReader.java @@ -282,4 +282,3 @@ private static int parseType( } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java index 09b11f5f912f0..d5c4a7de2ba48 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java @@ -109,7 +109,8 @@ protected SignatureVisitor(final int api) { && api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 - && api != Opcodes.ASM4) { + && api != Opcodes.ASM4 + && api != Opcodes.ASM10_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } this.api = api; @@ -211,7 +212,8 @@ public SignatureVisitor visitArrayType() { /** * Starts the visit of a signature corresponding to a class or interface type. * - * @param name the internal name of the class or interface. + * @param name the internal name of the class or interface (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). */ public void visitClassType(final String name) {} @@ -238,4 +240,3 @@ public SignatureVisitor visitTypeArgument(final char wildcard) { /** Ends the visit of a signature corresponding to a class or interface type. */ public void visitEnd() {} } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java index eceaaee424c57..077a9292955f9 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java @@ -73,7 +73,7 @@ public class SignatureWriter extends SignatureVisitor { /** The builder used to construct the visited signature. */ - private final StringBuilder stringBuilder = new StringBuilder(); + private final StringBuilder stringBuilder; /** Whether the visited signature contains formal type parameters. */ private boolean hasFormals; @@ -83,8 +83,9 @@ public class SignatureWriter extends SignatureVisitor { /** * The stack used to keep track of class types that have arguments. Each element of this stack is - * a boolean encoded in one bit. The top of the stack is the least significant bit. Pushing false - * = *2, pushing true = *2+1, popping = /2. + * a boolean encoded in one bit. The top of the stack is the least significant bit. The bottom of + * the stack is a sentinel element always equal to 1 (used to detect when the stack is full). + * Pushing false = {@code <<= 1}, pushing true = {@code ( <<= 1) | 1}, popping = {@code >>>= 1}. * *

    Class type arguments must be surrounded with '<' and '>' and, because * @@ -94,15 +95,20 @@ public class SignatureWriter extends SignatureVisitor { * SignatureWriter instances), * * - *

    we need a stack to properly balance these 'parentheses'. A new element is pushed on this - * stack for each new visited type, and popped when the visit of this type ends (either is + *

    we need a stack to properly balance these angle brackets. A new element is pushed on this + * stack for each new visited type, and popped when the visit of this type ends (either in * visitEnd, or because visitInnerClassType is called). */ - private int argumentStack; + private int argumentStack = 1; /** Constructs a new {@link SignatureWriter}. */ public SignatureWriter() { + this(new StringBuilder()); + } + + private SignatureWriter(final StringBuilder stringBuilder) { super(/* latest api =*/ Opcodes.ASM9); + this.stringBuilder = stringBuilder; } // ----------------------------------------------------------------------------------------------- @@ -191,7 +197,7 @@ public void visitClassType(final String name) { stringBuilder.append(name); // Pushes 'false' on the stack, meaning that this type does not have type arguments (as far as // we can tell at this point). - argumentStack *= 2; + argumentStack <<= 1; } @Override @@ -201,7 +207,7 @@ public void visitInnerClassType(final String name) { stringBuilder.append(name); // Pushes 'false' on the stack, meaning that this type does not have type arguments (as far as // we can tell at this point). - argumentStack *= 2; + argumentStack <<= 1; } @Override @@ -209,7 +215,7 @@ public void visitTypeArgument() { // If the top of the stack is 'false', this means we are visiting the first type argument of the // currently visited type. We therefore need to append a '<', and to replace the top stack // element with 'true' (meaning that the current type does have type arguments). - if (argumentStack % 2 == 0) { + if ((argumentStack & 1) == 0) { argumentStack |= 1; stringBuilder.append('<'); } @@ -221,14 +227,15 @@ public SignatureVisitor visitTypeArgument(final char wildcard) { // If the top of the stack is 'false', this means we are visiting the first type argument of the // currently visited type. We therefore need to append a '<', and to replace the top stack // element with 'true' (meaning that the current type does have type arguments). - if (argumentStack % 2 == 0) { + if ((argumentStack & 1) == 0) { argumentStack |= 1; stringBuilder.append('<'); } if (wildcard != '=') { stringBuilder.append(wildcard); } - return this; + // If the stack is full, start a nested one by returning a new SignatureWriter. + return (argumentStack & (1 << 31)) == 0 ? this : new SignatureWriter(stringBuilder); } @Override @@ -264,10 +271,9 @@ private void endArguments() { // If the top of the stack is 'true', this means that some type arguments have been visited for // the type whose visit is now ending. We therefore need to append a '>', and to pop one element // from the stack. - if (argumentStack % 2 == 1) { + if ((argumentStack & 1) == 1) { stringBuilder.append('>'); } - argumentStack /= 2; + argumentStack >>>= 1; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AbstractInsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AbstractInsnNode.java index 28b17cecc2b7f..1b22e023abcee 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AbstractInsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AbstractInsnNode.java @@ -120,7 +120,10 @@ public abstract class AbstractInsnNode { /** The type of {@link LineNumberNode} "instructions". */ public static final int LINE = 15; - /** The opcode of this instruction. */ + /** + * The opcode of this instruction, or -1 if this is not a JVM instruction (e.g. a label or a line + * number). + */ protected int opcode; /** @@ -163,7 +166,8 @@ protected AbstractInsnNode(final int opcode) { /** * Returns the opcode of this instruction. * - * @return the opcode of this instruction. + * @return the opcode of this instruction, or -1 if this is not a JVM instruction (e.g. a label or + * a line number). */ public int getOpcode() { return opcode; @@ -295,4 +299,3 @@ protected final AbstractInsnNode cloneAnnotations(final AbstractInsnNode insnNod return this; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java index e9c1e184c9018..2ef0bcfb62463 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java @@ -260,4 +260,3 @@ static void accept( } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java index dd8d1070fc7c2..0e271d6a159c1 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java @@ -90,14 +90,14 @@ public class ClassNode extends ClassVisitor { */ public int access; - /** The internal name of this class (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName}). */ + /** The internal name of this class (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName()}). */ public String name; /** The signature of this class. May be {@literal null}. */ public String signature; /** - * The internal of name of the super class (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName}). + * The internal of name of the super class (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName()}). * For interfaces, the super class is {@link Object}. May be {@literal null}, but only for the * {@link Object} class. */ @@ -105,7 +105,7 @@ public class ClassNode extends ClassVisitor { /** * The internal names of the interfaces directly implemented by this class (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName}). + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). */ public List interfaces; @@ -120,18 +120,26 @@ public class ClassNode extends ClassVisitor { /** The module stored in this class. May be {@literal null}. */ public ModuleNode module; - /** The internal name of the enclosing class of this class. May be {@literal null}. */ + /** + * The internal name of the enclosing class of this class (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). Must be {@literal null} if this class has no + * enclosing class, or if it is a local or anonymous class. + */ public String outerClass; /** - * The name of the method that contains this class, or {@literal null} if this class is not - * enclosed in a method. + * The name of the method that contains the class, or {@literal null} if the class has no + * enclosing class, or is not enclosed in a method or constructor of its enclosing class (e.g. if + * it is enclosed in an instance initializer, static initializer, instance variable initializer, + * or class variable initializer). */ public String outerMethod; /** - * The descriptor of the method that contains this class, or {@literal null} if this class is not - * enclosed in a method. + * The descriptor of the method that contains the class, or {@literal null} if the class has no + * enclosing class, or is not enclosed in a method or constructor of its enclosing class (e.g. if + * it is enclosed in an instance initializer, static initializer, instance variable initializer, + * or class variable initializer). */ public String outerMethodDesc; @@ -153,13 +161,22 @@ public class ClassNode extends ClassVisitor { /** The inner classes of this class. */ public List innerClasses; - /** The internal name of the nest host class of this class. May be {@literal null}. */ + /** + * The internal name of the nest host class of this class (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. + */ public String nestHostClass; - /** The internal names of the nest members of this class. May be {@literal null}. */ + /** + * The internal names of the nest members of this class (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. + */ public List nestMembers; - /** The internal names of the permitted subclasses of this class. May be {@literal null}. */ + /** + * The internal names of the permitted subclasses of this class (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. + */ public List permittedSubclasses; /** The record components of this class. May be {@literal null}. */ @@ -485,4 +502,3 @@ public void accept(final ClassVisitor classVisitor) { classVisitor.visitEnd(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldInsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldInsnNode.java index 8dd491246e8ca..ce450f9107b30 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldInsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldInsnNode.java @@ -72,7 +72,7 @@ public class FieldInsnNode extends AbstractInsnNode { /** * The internal name of the field's owner class (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName}). + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). */ public String owner; @@ -88,7 +88,7 @@ public class FieldInsnNode extends AbstractInsnNode { * @param opcode the opcode of the type instruction to be constructed. This opcode must be * GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. * @param owner the internal name of the field's owner class (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName}). + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). * @param name the field's name. * @param descriptor the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}). */ @@ -126,4 +126,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { return new FieldInsnNode(opcode, owner, name, desc).cloneAnnotations(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java index b5bec8d5cc856..2bf3682b669f8 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java @@ -274,4 +274,3 @@ public void accept(final ClassVisitor classVisitor) { fieldVisitor.visitEnd(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FrameNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FrameNode.java index cd4cc5c57adc0..cb8c8fb05ab6a 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FrameNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FrameNode.java @@ -111,14 +111,18 @@ private FrameNode() { * @param type the type of this frame. Must be {@link Opcodes#F_NEW} for expanded frames, or * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, {@link * Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames. - * @param numLocal number of local variables of this stack map frame. + * @param numLocal number of local variables of this stack map frame. Long and double values count + * for one variable. * @param local the types of the local variables of this stack map frame. Elements of this list * can be Integer, String or LabelNode objects (for primitive, reference and uninitialized - * types respectively - see {@link MethodVisitor}). - * @param numStack number of operand stack elements of this stack map frame. + * types respectively - see {@link MethodVisitor}). Long and double values are represented by + * a single element. + * @param numStack number of operand stack elements of this stack map frame. Long and double + * values count for one stack element. * @param stack the types of the operand stack elements of this stack map frame. Elements of this * list can be Integer, String or LabelNode objects (for primitive, reference and - * uninitialized types respectively - see {@link MethodVisitor}). + * uninitialized types respectively - see {@link MethodVisitor}). Long and double values are + * represented by a single element. */ public FrameNode( final int type, @@ -218,4 +222,3 @@ private static Object[] asArray(final List list) { return array; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/IincInsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/IincInsnNode.java index 71fe001c70517..864d540cd8c76 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/IincInsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/IincInsnNode.java @@ -104,4 +104,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { return new IincInsnNode(var, incr).cloneAnnotations(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InnerClassNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InnerClassNode.java index 7ab29379ca822..a2e103ae6d23c 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InnerClassNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InnerClassNode.java @@ -62,7 +62,11 @@ import jdk.internal.org.objectweb.asm.ClassVisitor; /** - * A node that represents an inner class. + * A node that represents an inner class. This inner class is not necessarily a member of the {@link + * ClassNode} containing this object. More precisely, every class or interface C which is referenced + * by a {@link ClassNode} and which is not a package member must be represented with an {@link + * InnerClassNode}. The {@link ClassNode} must reference its nested class or interface members, and + * its enclosing class, if any. See the JVMS 4.7.6 section for more details. * * @author Eric Bruneton */ @@ -78,25 +82,27 @@ public class InnerClassNode { public String outerName; /** - * The (simple) name of the inner class inside its enclosing class. May be {@literal null} for - * anonymous inner classes. + * The (simple) name of the inner class inside its enclosing class. Must be {@literal null} if the + * inner class is not the member of a class or interface (e.g. for local or anonymous classes). */ public String innerName; - /** The access flags of the inner class as originally declared in the enclosing class. */ + /** + * The access flags of the inner class as originally declared in the source code from which the + * class was compiled. + */ public int access; /** - * Constructs a new {@link InnerClassNode}. + * Constructs a new {@link InnerClassNode} for an inner class C. * - * @param name the internal name of an inner class (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName()}). - * @param outerName the internal name of the class to which the inner class belongs (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. - * @param innerName the (simple) name of the inner class inside its enclosing class. May be - * {@literal null} for anonymous inner classes. - * @param access the access flags of the inner class as originally declared in the enclosing - * class. + * @param name the internal name of C (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName()}). + * @param outerName the internal name of the class or interface C is a member of (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). Must be {@literal null} if C is not the member + * of a class or interface (e.g. for local or anonymous classes). + * @param innerName the (simple) name of C. Must be {@literal null} for anonymous inner classes. + * @param access the access flags of C originally declared in the source code from which this + * class was compiled. */ public InnerClassNode( final String name, final String outerName, final String innerName, final int access) { @@ -115,4 +121,3 @@ public void accept(final ClassVisitor classVisitor) { classVisitor.visitInnerClass(name, outerName, innerName, access); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java index a375eb0ce8849..a63c80d76035c 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java @@ -634,4 +634,3 @@ public void set(final Object o) { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnNode.java index 8fed9db1949e6..94e043ca9c404 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnNode.java @@ -103,4 +103,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { return new InsnNode(opcode).cloneAnnotations(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/IntInsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/IntInsnNode.java index 5da8824ea995b..0c044886f9002 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/IntInsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/IntInsnNode.java @@ -109,4 +109,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { return new IntInsnNode(opcode, operand).cloneAnnotations(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InvokeDynamicInsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InvokeDynamicInsnNode.java index 0d934f2ab7378..087d3f5acd45a 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InvokeDynamicInsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InvokeDynamicInsnNode.java @@ -98,12 +98,12 @@ public InvokeDynamicInsnNode( final String name, final String descriptor, final Handle bootstrapMethodHandle, - final Object... bootstrapMethodArguments) { // NOPMD(ArrayIsStoredDirectly): public field. + final Object... bootstrapMethodArguments) { super(Opcodes.INVOKEDYNAMIC); this.name = name; this.desc = descriptor; this.bsm = bootstrapMethodHandle; - this.bsmArgs = bootstrapMethodArguments; + this.bsmArgs = bootstrapMethodArguments; // NOPMD(ArrayIsStoredDirectly): public field. } @Override @@ -122,4 +122,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs).cloneAnnotations(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/JumpInsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/JumpInsnNode.java index 8790ff322465a..23891297e450d 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/JumpInsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/JumpInsnNode.java @@ -117,4 +117,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { return new JumpInsnNode(opcode, clone(label, clonedLabels)).cloneAnnotations(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LabelNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LabelNode.java index 6edcc0d99d10b..935382ad543b1 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LabelNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LabelNode.java @@ -109,4 +109,3 @@ public void resetLabel() { value = null; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LdcInsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LdcInsnNode.java index 20eafcaa65631..1dac0b7aa8511 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LdcInsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LdcInsnNode.java @@ -113,4 +113,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { return new LdcInsnNode(cst).cloneAnnotations(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LineNumberNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LineNumberNode.java index ac882ed778356..4feb13072b5d7 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LineNumberNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LineNumberNode.java @@ -104,4 +104,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { return new LineNumberNode(line, clone(start, clonedLabels)); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java index 2753e06b06e07..2a593ca16996d 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java @@ -169,4 +169,3 @@ public void accept(final MethodVisitor methodVisitor, final boolean visible) { typeRef, typePath, startLabels, endLabels, indices, desc, visible)); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableNode.java index 142c5915a06cd..7bfb121b88a04 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableNode.java @@ -122,4 +122,3 @@ public void accept(final MethodVisitor methodVisitor) { name, desc, signature, start.getLabel(), end.getLabel(), index); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LookupSwitchInsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LookupSwitchInsnNode.java index 513f2c06cfa6c..31d3c79b1629c 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LookupSwitchInsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LookupSwitchInsnNode.java @@ -123,4 +123,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { return clone.cloneAnnotations(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodInsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodInsnNode.java index 9c5f40d6517bd..77e720b69b93b 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodInsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodInsnNode.java @@ -153,4 +153,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { return new MethodInsnNode(opcode, owner, name, desc, itf).cloneAnnotations(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java index 365ffa005c1b3..3ec2ac6d1fc3d 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java @@ -326,14 +326,14 @@ public AnnotationVisitor visitParameterAnnotation( AnnotationNode annotation = new AnnotationNode(descriptor); if (visible) { if (visibleParameterAnnotations == null) { - int params = Type.getArgumentTypes(desc).length; + int params = Type.getArgumentCount(desc); visibleParameterAnnotations = (List[]) new List[params]; } visibleParameterAnnotations[parameter] = Util.add(visibleParameterAnnotations[parameter], annotation); } else { if (invisibleParameterAnnotations == null) { - int params = Type.getArgumentTypes(desc).length; + int params = Type.getArgumentCount(desc); invisibleParameterAnnotations = (List[]) new List[params]; } invisibleParameterAnnotations[parameter] = @@ -802,4 +802,3 @@ public void accept(final MethodVisitor methodVisitor) { methodVisitor.visitEnd(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleExportNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleExportNode.java index 094c2e19300b1..b845ebe662e04 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleExportNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleExportNode.java @@ -69,7 +69,10 @@ */ public class ModuleExportNode { - /** The internal name of the exported package. */ + /** + * The internal name of the exported package (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). + */ public String packaze; /** @@ -87,7 +90,8 @@ public class ModuleExportNode { /** * Constructs a new {@link ModuleExportNode}. * - * @param packaze the internal name of the exported package. + * @param packaze the internal name of the exported package (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). * @param access the package access flags, one or more of {@code ACC_SYNTHETIC} and {@code * ACC_MANDATED}. * @param modules a list of modules that can access this exported package, specified with fully @@ -109,4 +113,3 @@ public void accept(final ModuleVisitor moduleVisitor) { packaze, access, modules == null ? null : modules.toArray(new String[0])); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleNode.java index fcb9db550f03f..66baee92e1be2 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleNode.java @@ -84,10 +84,16 @@ public class ModuleNode extends ModuleVisitor { /** The version of this module. May be {@literal null}. */ public String version; - /** The internal name of the main class of this module. May be {@literal null}. */ + /** + * The internal name of the main class of this module (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. + */ public String mainClass; - /** The internal name of the packages declared by this module. May be {@literal null}. */ + /** + * The internal name of the packages declared by this module (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. + */ public List packages; /** The dependencies of this module. May be {@literal null}. */ @@ -99,7 +105,10 @@ public class ModuleNode extends ModuleVisitor { /** The packages opened by this module. May be {@literal null}. */ public List opens; - /** The internal names of the services used by this module. May be {@literal null}. */ + /** + * The internal names of the services used by this module (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. + */ public List uses; /** The services provided by this module. May be {@literal null}. */ @@ -138,7 +147,8 @@ public ModuleNode(final String name, final int access, final String version) { * @param requires The dependencies of this module. May be {@literal null}. * @param exports The packages exported by this module. May be {@literal null}. * @param opens The packages opened by this module. May be {@literal null}. - * @param uses The internal names of the services used by this module. May be {@literal null}. + * @param uses The internal names of the services used by this module (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. * @param provides The services provided by this module. May be {@literal null}. */ public ModuleNode( @@ -265,4 +275,3 @@ public void accept(final ClassVisitor classVisitor) { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleOpenNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleOpenNode.java index afc453ef3b105..abe48f598db21 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleOpenNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleOpenNode.java @@ -69,7 +69,9 @@ */ public class ModuleOpenNode { - /** The internal name of the opened package. */ + /** + * The internal name of the opened package (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName()}). + */ public String packaze; /** @@ -87,7 +89,8 @@ public class ModuleOpenNode { /** * Constructs a new {@link ModuleOpenNode}. * - * @param packaze the internal name of the opened package. + * @param packaze the internal name of the opened package (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}). * @param access the access flag of the opened package, valid values are among {@code * ACC_SYNTHETIC} and {@code ACC_MANDATED}. * @param modules the fully qualified names (using dots) of the modules that can use deep @@ -109,4 +112,3 @@ public void accept(final ModuleVisitor moduleVisitor) { packaze, access, modules == null ? null : modules.toArray(new String[0])); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleProvideNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleProvideNode.java index 3370aafe5f2cc..d48239f55b2d2 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleProvideNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleProvideNode.java @@ -69,10 +69,13 @@ */ public class ModuleProvideNode { - /** The internal name of the service. */ + /** The internal name of the service (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName()}). */ public String service; - /** The internal names of the implementations of the service (there is at least one provider). */ + /** + * The internal names of the implementations of the service (there is at least one provider). See + * {@link jdk.internal.org.objectweb.asm.Type#getInternalName()}. + */ public List providers; /** @@ -80,7 +83,7 @@ public class ModuleProvideNode { * * @param service the internal name of the service. * @param providers the internal names of the implementations of the service (there is at least - * one provider). + * one provider). See {@link jdk.internal.org.objectweb.asm.Type#getInternalName()}. */ public ModuleProvideNode(final String service, final List providers) { this.service = service; @@ -96,4 +99,3 @@ public void accept(final ModuleVisitor moduleVisitor) { moduleVisitor.visitProvide(service, providers.toArray(new String[0])); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleRequireNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleRequireNode.java index cec5ebcdbd23c..319d7af23e358 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleRequireNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleRequireNode.java @@ -103,4 +103,3 @@ public void accept(final ModuleVisitor moduleVisitor) { moduleVisitor.visitRequire(module, access, version); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MultiANewArrayInsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MultiANewArrayInsnNode.java index 201fb7652d635..87a00b69021f5 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MultiANewArrayInsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MultiANewArrayInsnNode.java @@ -104,4 +104,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { return new MultiANewArrayInsnNode(desc, dims).cloneAnnotations(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ParameterNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ParameterNode.java index cb90eb6db5e8b..a2223c8c367f9 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ParameterNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ParameterNode.java @@ -98,4 +98,3 @@ public void accept(final MethodVisitor methodVisitor) { methodVisitor.visitParameter(name, access); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/RecordComponentNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/RecordComponentNode.java index 7eb919b7bbb5d..7cc87a7776e0a 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/RecordComponentNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/RecordComponentNode.java @@ -234,4 +234,3 @@ public void accept(final ClassVisitor classVisitor) { recordComponentVisitor.visitEnd(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TableSwitchInsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TableSwitchInsnNode.java index cabc1553c695d..94287b55c1c2e 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TableSwitchInsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TableSwitchInsnNode.java @@ -123,4 +123,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { .cloneAnnotations(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TryCatchBlockNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TryCatchBlockNode.java index fe033a5bc7c27..2095218ab0bcb 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TryCatchBlockNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TryCatchBlockNode.java @@ -98,8 +98,9 @@ public class TryCatchBlockNode { * @param start the beginning of the exception handler's scope (inclusive). * @param end the end of the exception handler's scope (exclusive). * @param handler the beginning of the exception handler's code. - * @param type the internal name of the type of exceptions handled by the handler, or {@literal - * null} to catch any exceptions (for "finally" blocks). + * @param type the internal name of the type of exceptions handled by the handler (see {@link + * jdk.internal.org.objectweb.asm.Type#getInternalName()}), or {@literal null} to catch any exceptions (for + * "finally" blocks). */ public TryCatchBlockNode( final LabelNode start, final LabelNode end, final LabelNode handler, final String type) { @@ -156,4 +157,3 @@ public void accept(final MethodVisitor methodVisitor) { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java index 938b977c7bab6..7a6bbb201f363 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java @@ -115,4 +115,3 @@ public TypeAnnotationNode( this.typePath = typePath; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeInsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeInsnNode.java index 3ebdfab6ceedb..ba01f50efc167 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeInsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeInsnNode.java @@ -63,16 +63,16 @@ import jdk.internal.org.objectweb.asm.MethodVisitor; /** - * A node that represents a type instruction. A type instruction is an instruction that takes a type - * descriptor as parameter. + * A node that represents a type instruction. A type instruction is an instruction which takes an + * internal name as parameter (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName()}). * * @author Eric Bruneton */ public class TypeInsnNode extends AbstractInsnNode { /** - * The operand of this instruction. This operand is an internal name (see {@link - * jdk.internal.org.objectweb.asm.Type}). + * The operand of this instruction. Despite its name (due to historical reasons), this operand is + * an internal name (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName()}). */ public String desc; @@ -81,12 +81,12 @@ public class TypeInsnNode extends AbstractInsnNode { * * @param opcode the opcode of the type instruction to be constructed. This opcode must be NEW, * ANEWARRAY, CHECKCAST or INSTANCEOF. - * @param descriptor the operand of the instruction to be constructed. This operand is an internal - * name (see {@link jdk.internal.org.objectweb.asm.Type}). + * @param type the operand of the instruction to be constructed. This operand is an internal name + * (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName()}). */ - public TypeInsnNode(final int opcode, final String descriptor) { + public TypeInsnNode(final int opcode, final String type) { super(opcode); - this.desc = descriptor; + this.desc = type; } /** @@ -115,4 +115,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { return new TypeInsnNode(opcode, desc).cloneAnnotations(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/UnsupportedClassVersionException.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/UnsupportedClassVersionException.java index 17f9ebb2e35c7..ec9c9d04bb661 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/UnsupportedClassVersionException.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/UnsupportedClassVersionException.java @@ -70,4 +70,3 @@ public class UnsupportedClassVersionException extends RuntimeException { private static final long serialVersionUID = -3502347765891805831L; } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/Util.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/Util.java index ac747f4cec27d..ae09e55a2d6f4 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/Util.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/Util.java @@ -193,4 +193,3 @@ static List asArrayList(final int length, final T[] array) { return list; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/VarInsnNode.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/VarInsnNode.java index c04bda399a37a..8e0ddfe8b40ba 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/VarInsnNode.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/VarInsnNode.java @@ -112,4 +112,3 @@ public AbstractInsnNode clone(final Map clonedLabels) { return new VarInsnNode(opcode, var).cloneAnnotations(this); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Analyzer.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Analyzer.java index 222965b8b2fd7..a3c277e69f15f 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Analyzer.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Analyzer.java @@ -80,7 +80,7 @@ * A semantic bytecode analyzer. This class does not fully check that JSR and RET instructions * are valid. * - * @param type of the Value used for the analysis. + * @param type of the {@link Value} used for the analysis. * @author Eric Bruneton */ public class Analyzer implements Opcodes { @@ -124,7 +124,8 @@ public Analyzer(final Interpreter interpreter) { /** * Analyzes the given method. * - * @param owner the internal name of the class to which 'method' belongs. + * @param owner the internal name of the class to which 'method' belongs (see {@link + * Type#getInternalName()}). * @param method the method to be analyzed. The maxStack and maxLocals fields must have correct * values. * @return the symbolic state of the execution stack frame at each bytecode instruction of the @@ -154,7 +155,7 @@ public Frame[] analyze(final String owner, final MethodNode method) throws An TryCatchBlockNode tryCatchBlock = method.tryCatchBlocks.get(i); int startIndex = insnList.indexOf(tryCatchBlock.start); int endIndex = insnList.indexOf(tryCatchBlock.end); - for (int j = startIndex; j < endIndex; ++j) { + for (int j = startIndex; j <= endIndex; ++j) { List insnHandlers = handlers[j]; if (insnHandlers == null) { insnHandlers = new ArrayList<>(); @@ -164,37 +165,19 @@ public Frame[] analyze(final String owner, final MethodNode method) throws An } } - // For each instruction, compute the subroutine to which it belongs. - // Follow the main 'subroutine', and collect the jsr instructions to nested subroutines. - Subroutine main = new Subroutine(null, method.maxLocals, null); - List jsrInsns = new ArrayList<>(); - findSubroutine(0, main, jsrInsns); - // Follow the nested subroutines, and collect their own nested subroutines, until all - // subroutines are found. - Map jsrSubroutines = new HashMap<>(); - while (!jsrInsns.isEmpty()) { - JumpInsnNode jsrInsn = (JumpInsnNode) jsrInsns.remove(0); - Subroutine subroutine = jsrSubroutines.get(jsrInsn.label); - if (subroutine == null) { - subroutine = new Subroutine(jsrInsn.label, method.maxLocals, jsrInsn); - jsrSubroutines.put(jsrInsn.label, subroutine); - findSubroutine(insnList.indexOf(jsrInsn.label), subroutine, jsrInsns); - } else { - subroutine.callers.add(jsrInsn); - } - } - // Clear the main 'subroutine', which is not a real subroutine (and was used only as an - // intermediate step above to find the real ones). - for (int i = 0; i < insnListSize; ++i) { - if (subroutines[i] != null && subroutines[i].start == null) { - subroutines[i] = null; - } - } + // Finds the method's subroutines. + findSubroutines(method.maxLocals); // Initializes the data structures for the control flow analysis. - Frame currentFrame = computeInitialFrame(owner, method); - merge(0, currentFrame, null); - init(owner, method); + Frame currentFrame; + try { + currentFrame = computeInitialFrame(owner, method); + merge(0, currentFrame, null); + init(owner, method); + } catch (RuntimeException e) { + // DontCheck(IllegalCatch): can't be fixed, for backward compatibility. + throw new AnalyzerException(insnList.get(0), "Error at instruction 0: " + e.getMessage(), e); + } // Control flow analysis. while (numInstructionsToProcess > 0) { @@ -336,7 +319,8 @@ public Frame[] analyze(final String owner, final MethodNode method) throws An * Analyzes the given method and computes and sets its maximum stack size and maximum number of * local variables. * - * @param owner the internal name of the class to which 'method' belongs. + * @param owner the internal name of the class to which 'method' belongs (see {@link + * Type#getInternalName()}). * @param method the method to be analyzed. * @return the symbolic state of the execution stack frame at each bytecode instruction of the * method. The size of the returned array is equal to the number of instructions (and labels) @@ -361,6 +345,9 @@ public Frame[] analyzeAndComputeMaxs(final String owner, final MethodNode met */ private static int computeMaxLocals(final MethodNode method) { int maxLocals = Type.getArgumentsAndReturnSizes(method.desc) >> 2; + if ((method.access & Opcodes.ACC_STATIC) != 0) { + maxLocals -= 1; + } for (AbstractInsnNode insnNode : method.instructions) { if (insnNode instanceof VarInsnNode) { int local = ((VarInsnNode) insnNode).var; @@ -400,6 +387,42 @@ private static int computeMaxStack(final Frame[] frames) { return maxStack; } + /** + * Finds the subroutines of the currently analyzed method and stores them in {@link #subroutines}. + * + * @param maxLocals the maximum number of local variables of the currently analyzed method (long + * and double values count for two variables). + * @throws AnalyzerException if the control flow graph can fall off the end of the code. + */ + private void findSubroutines(final int maxLocals) throws AnalyzerException { + // For each instruction, compute the subroutine to which it belongs. + // Follow the main 'subroutine', and collect the jsr instructions to nested subroutines. + Subroutine main = new Subroutine(null, maxLocals, null); + List jsrInsns = new ArrayList<>(); + findSubroutine(0, main, jsrInsns); + // Follow the nested subroutines, and collect their own nested subroutines, until all + // subroutines are found. + Map jsrSubroutines = new HashMap<>(); + while (!jsrInsns.isEmpty()) { + JumpInsnNode jsrInsn = (JumpInsnNode) jsrInsns.remove(0); + Subroutine subroutine = jsrSubroutines.get(jsrInsn.label); + if (subroutine == null) { + subroutine = new Subroutine(jsrInsn.label, maxLocals, jsrInsn); + jsrSubroutines.put(jsrInsn.label, subroutine); + findSubroutine(insnList.indexOf(jsrInsn.label), subroutine, jsrInsns); + } else { + subroutine.callers.add(jsrInsn); + } + } + // Clear the main 'subroutine', which is not a real subroutine (and was used only as an + // intermediate step above to find the real ones). + for (int i = 0; i < insnListSize; ++i) { + if (subroutines[i] != null && subroutines[i].start == null) { + subroutines[i] = null; + } + } + } + /** * Follows the control flow graph of the currently analyzed method, starting at the given * instruction index, and stores a copy of the given subroutine in {@link #subroutines} for each @@ -485,7 +508,8 @@ private void findSubroutine( /** * Computes the initial execution stack frame of the given method. * - * @param owner the internal name of the class to which 'method' belongs. + * @param owner the internal name of the class to which 'method' belongs (see {@link + * Type#getInternalName()}). * @param method the method to be analyzed. * @return the initial execution stack frame of the 'method'. */ @@ -542,9 +566,10 @@ public List getHandlers(final int insnIndex) { /** * Initializes this analyzer. This method is called just before the execution of control flow - * analysis loop in #analyze. The default implementation of this method does nothing. + * analysis loop in {@link #analyze}. The default implementation of this method does nothing. * - * @param owner the internal name of the class to which the method belongs. + * @param owner the internal name of the class to which the method belongs (see {@link + * Type#getInternalName()}). * @param method the method to be analyzed. * @throws AnalyzerException if a problem occurs. */ @@ -702,4 +727,3 @@ private void merge( } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java index e3ea04720bed0..5101b2f534a3b 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java @@ -119,4 +119,3 @@ public AnalyzerException( this.node = insn; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java index c725fd6549910..7dee3af4405fa 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java @@ -405,4 +405,3 @@ public BasicValue merge(final BasicValue value1, final BasicValue value2) { return value1; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicValue.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicValue.java index 58b57120ebd5c..3d854f636869b 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicValue.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicValue.java @@ -159,4 +159,3 @@ public String toString() { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java index a9d08e022aa6e..ebe738fe42034 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java @@ -480,4 +480,3 @@ protected boolean isSubTypeOf(final BasicValue value, final BasicValue expected) return value.equals(expected); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java index 6c8b222ef9252..5940c9ed91a75 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java @@ -704,7 +704,7 @@ private void executeInvokeInsn( final AbstractInsnNode insn, final String methodDescriptor, final Interpreter interpreter) throws AnalyzerException { ArrayList valueList = new ArrayList<>(); - for (int i = Type.getArgumentTypes(methodDescriptor).length; i > 0; --i) { + for (int i = Type.getArgumentCount(methodDescriptor); i > 0; --i) { valueList.add(0, pop()); } if (insn.getOpcode() != Opcodes.INVOKESTATIC && insn.getOpcode() != Opcodes.INVOKEDYNAMIC) { @@ -782,4 +782,3 @@ public String toString() { return stringBuilder.toString(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Interpreter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Interpreter.java index 7b28e68a1ea84..d2c6103b77e8f 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Interpreter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Interpreter.java @@ -297,4 +297,3 @@ public abstract void returnOperation(AbstractInsnNode insn, V value, V expected) */ public abstract V merge(V value1, V value2); } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java index 7f611cde57a22..6f2f124ab31f4 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java @@ -411,4 +411,3 @@ protected Class getClass(final Type type) { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SmallSet.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SmallSet.java index 099a73779444c..3c85d565ef878 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SmallSet.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SmallSet.java @@ -228,4 +228,3 @@ public void remove() { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java index 3078081e5a957..d92ffce0a59b8 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java @@ -250,4 +250,3 @@ private static boolean containsAll(final Set self, final Set other) { return self.containsAll(other); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceValue.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceValue.java index 885ba47bcf0e1..5403130af8cc4 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceValue.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceValue.java @@ -149,4 +149,3 @@ public int hashCode() { return insns.hashCode(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Subroutine.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Subroutine.java index f59644795d715..67267e0119e2a 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Subroutine.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Subroutine.java @@ -136,4 +136,3 @@ public boolean merge(final Subroutine subroutine) { return changed; } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Value.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Value.java index 450120c741a80..7058c959783f9 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Value.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Value.java @@ -74,4 +74,3 @@ public interface Value { */ int getSize(); } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java index a1563bee95bc7..ba51a3fe752a7 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java @@ -75,7 +75,7 @@ import jdk.internal.org.objectweb.asm.TypePath; /** - * A {@link Printer} that prints the ASM code to generate the classes if visits. + * A {@link Printer} that prints the ASM code to generate the classes it visits. * * @author Eric Bruneton */ @@ -141,6 +141,9 @@ public class ASMifier extends Printer { classVersions.put(Opcodes.V17, "V17"); classVersions.put(Opcodes.V18, "V18"); classVersions.put(Opcodes.V19, "V19"); + classVersions.put(Opcodes.V20, "V20"); + classVersions.put(Opcodes.V21, "V21"); + classVersions.put(Opcodes.V22, "V22"); CLASS_VERSIONS = Collections.unmodifiableMap(classVersions); } @@ -1641,4 +1644,3 @@ protected void appendLabel(final Label label) { stringBuilder.append(labelNames.get(label)); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifierSupport.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifierSupport.java index 956938394a4d7..b592281332fc2 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifierSupport.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifierSupport.java @@ -81,4 +81,3 @@ public interface ASMifierSupport { void asmify( StringBuilder outputBuilder, String visitorVariableName, Map labelNames); } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java index b3d21f5ae997d..1133c5ee3611b 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java @@ -165,4 +165,3 @@ private void checkVisitEndNotCalled() { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java index 3aa26bed646c4..e8ccad6fadf29 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java @@ -496,7 +496,8 @@ public MethodVisitor visitMethod( if (checkDataFlow) { if (cv instanceof ClassWriter) { methodVisitor = - new CheckMethodAdapter.MethodWriterWrapper(api, (ClassWriter) cv, methodVisitor); + new CheckMethodAdapter.MethodWriterWrapper( + api, version, (ClassWriter) cv, methodVisitor); } checkMethodAdapter = new CheckMethodAdapter(api, access, name, descriptor, methodVisitor, labelInsnIndices); @@ -1079,7 +1080,7 @@ public static void verify( final PrintWriter printWriter) { ClassNode classNode = new ClassNode(); classReader.accept( - new CheckClassAdapter(/*latest*/ Opcodes.ASM9, classNode, false) {}, + new CheckClassAdapter(/*latest*/ Opcodes.ASM10_EXPERIMENTAL, classNode, false) {}, ClassReader.SKIP_DEBUG); Type syperType = classNode.superName == null ? null : Type.getObjectType(classNode.superName); @@ -1166,4 +1167,3 @@ private static String getUnqualifiedName(final String name) { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java index 790faf1dde007..16b0ea8d7d6f4 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java @@ -146,4 +146,3 @@ private void checkVisitEndNotCalled() { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFrameAnalyzer.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFrameAnalyzer.java new file mode 100644 index 0000000000000..f2f07c26178ec --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFrameAnalyzer.java @@ -0,0 +1,512 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +package jdk.internal.org.objectweb.asm.util; + +import java.util.Collections; +import java.util.List; +import jdk.internal.org.objectweb.asm.Opcodes; +import jdk.internal.org.objectweb.asm.Type; +import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode; +import jdk.internal.org.objectweb.asm.tree.FrameNode; +import jdk.internal.org.objectweb.asm.tree.InsnList; +import jdk.internal.org.objectweb.asm.tree.InsnNode; +import jdk.internal.org.objectweb.asm.tree.JumpInsnNode; +import jdk.internal.org.objectweb.asm.tree.LabelNode; +import jdk.internal.org.objectweb.asm.tree.LookupSwitchInsnNode; +import jdk.internal.org.objectweb.asm.tree.MethodNode; +import jdk.internal.org.objectweb.asm.tree.TableSwitchInsnNode; +import jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode; +import jdk.internal.org.objectweb.asm.tree.TypeInsnNode; +import jdk.internal.org.objectweb.asm.tree.analysis.Analyzer; +import jdk.internal.org.objectweb.asm.tree.analysis.AnalyzerException; +import jdk.internal.org.objectweb.asm.tree.analysis.Frame; +import jdk.internal.org.objectweb.asm.tree.analysis.Interpreter; +import jdk.internal.org.objectweb.asm.tree.analysis.Value; + +/** + * An {@link Analyzer} subclass which checks that methods provide stack map frames where expected + * (i.e. at jump target and after instructions without immediate successor), and that these stack + * map frames are valid (for the provided interpreter; they may still be invalid for the JVM, if the + * {@link Interpreter} uses a simplified type system compared to the JVM verifier). This is done in + * two steps: + * + *
      + *
    • First, the stack map frames in {@link FrameNode}s are expanded, and stored at their + * respective instruction offsets. The expansion process uncompresses the APPEND, CHOP and + * SAME frames to FULL frames. It also converts the stack map frame verification types to + * {@link Value}s, via the provided {@link Interpreter}. The expansion is done in {@link + * #expandFrames}, by looking at each {@link FrameNode} in sequence (compressed frames are + * defined relatively to the previous {@link FrameNode}, or the implicit first frame). The + * actual decompression is done in {@link #expandFrame}, and the type conversion in {@link + * #newFrameValue}. + *
    • Next, the method instructions are checked in sequence. Starting from the implicit initial + * frame, the execution of each instruction i is simulated on the current stack map + * frame, with the {@link Frame#execute} method. This gives a new stack map frame f, + * representing the stack map frame state after the execution of i. Then: + *
        + *
      • If there is a next instruction and if the control flow cannot continue to it (e.g. if + * i is a RETURN or an ATHROW, for instance): an existing stack map frame + * f0 (coming from the first step) is expected after i. + *
      • If there is a next instruction and if the control flow can continue to it (e.g. if + * i is a ALOAD, for instance): either there an existing stack map frame + * f0 (coming from the first step) after i, or there is none. In the + * first case f and f0 must be compatible: the types in + * f must be sub types of the corresponding types in the existing frame + * f0 (otherwise an exception is thrown). In the second case, f0 is + * simply set to the value of f. + *
      • If the control flow can continue to some instruction j (e.g. if i + * is an IF_EQ, for instance): an existing stack map frame f0 (coming from the + * first step) is expected at j, which must be compatible with f (as + * defined previously). + *
      + * The sequential loop over the instructions is done in {@link #init}, which is called from + * the {@link Analyzer#analyze} method. Cases where the control flow cannot continue to the + * next instruction are handled in {@link #endControlFlow}. Cases where the control flow can + * continue to the next instruction, or jump to another instruction, are handled in {@link + * #checkFrame}. This method checks that an existing stack map frame is present when required, + * and checks the stack map frames compatibility with {@link #checkMerge}. + *
    + * + * @author Eric Bruneton + * @param type of the {@link Value} used for the analysis. + */ +class CheckFrameAnalyzer extends Analyzer { + + /** The interpreter to use to symbolically interpret the bytecode instructions. */ + private final Interpreter interpreter; + + /** The instructions of the currently analyzed method. */ + private InsnList insnList; + + /** + * The number of locals in the last stack map frame processed by {@link expandFrame}. Long and + * double values are represented with two elements. + */ + private int currentLocals; + + CheckFrameAnalyzer(final Interpreter interpreter) { + super(interpreter); + this.interpreter = interpreter; + } + + @Override + protected void init(final String owner, final MethodNode method) throws AnalyzerException { + insnList = method.instructions; + currentLocals = Type.getArgumentsAndReturnSizes(method.desc) >> 2; + if ((method.access & Opcodes.ACC_STATIC) != 0) { + currentLocals -= 1; + } + + Frame[] frames = getFrames(); + Frame currentFrame = frames[0]; + expandFrames(owner, method, currentFrame); + for (int insnIndex = 0; insnIndex < insnList.size(); ++insnIndex) { + Frame oldFrame = frames[insnIndex]; + + // Simulate the execution of this instruction. + AbstractInsnNode insnNode = null; + try { + insnNode = method.instructions.get(insnIndex); + int insnOpcode = insnNode.getOpcode(); + int insnType = insnNode.getType(); + + if (insnType == AbstractInsnNode.LABEL + || insnType == AbstractInsnNode.LINE + || insnType == AbstractInsnNode.FRAME) { + checkFrame(insnIndex + 1, oldFrame, /* requireFrame = */ false); + } else { + currentFrame.init(oldFrame).execute(insnNode, interpreter); + + if (insnNode instanceof JumpInsnNode) { + if (insnOpcode == JSR) { + throw new AnalyzerException(insnNode, "JSR instructions are unsupported"); + } + JumpInsnNode jumpInsn = (JumpInsnNode) insnNode; + int targetInsnIndex = insnList.indexOf(jumpInsn.label); + checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true); + if (insnOpcode == GOTO) { + endControlFlow(insnIndex); + } else { + checkFrame(insnIndex + 1, currentFrame, /* requireFrame = */ false); + } + } else if (insnNode instanceof LookupSwitchInsnNode) { + LookupSwitchInsnNode lookupSwitchInsn = (LookupSwitchInsnNode) insnNode; + int targetInsnIndex = insnList.indexOf(lookupSwitchInsn.dflt); + checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true); + for (int i = 0; i < lookupSwitchInsn.labels.size(); ++i) { + LabelNode label = lookupSwitchInsn.labels.get(i); + targetInsnIndex = insnList.indexOf(label); + currentFrame.initJumpTarget(insnOpcode, label); + checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true); + } + endControlFlow(insnIndex); + } else if (insnNode instanceof TableSwitchInsnNode) { + TableSwitchInsnNode tableSwitchInsn = (TableSwitchInsnNode) insnNode; + int targetInsnIndex = insnList.indexOf(tableSwitchInsn.dflt); + currentFrame.initJumpTarget(insnOpcode, tableSwitchInsn.dflt); + checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true); + newControlFlowEdge(insnIndex, targetInsnIndex); + for (int i = 0; i < tableSwitchInsn.labels.size(); ++i) { + LabelNode label = tableSwitchInsn.labels.get(i); + currentFrame.initJumpTarget(insnOpcode, label); + targetInsnIndex = insnList.indexOf(label); + checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true); + } + endControlFlow(insnIndex); + } else if (insnOpcode == RET) { + throw new AnalyzerException(insnNode, "RET instructions are unsupported"); + } else if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) { + checkFrame(insnIndex + 1, currentFrame, /* requireFrame = */ false); + } else { + endControlFlow(insnIndex); + } + } + + List insnHandlers = getHandlers(insnIndex); + if (insnHandlers != null) { + for (TryCatchBlockNode tryCatchBlock : insnHandlers) { + Type catchType; + if (tryCatchBlock.type == null) { + catchType = Type.getObjectType("java/lang/Throwable"); + } else { + catchType = Type.getObjectType(tryCatchBlock.type); + } + Frame handler = newFrame(oldFrame); + handler.clearStack(); + handler.push(interpreter.newExceptionValue(tryCatchBlock, handler, catchType)); + checkFrame(insnList.indexOf(tryCatchBlock.handler), handler, /* requireFrame = */ true); + } + } + + if (!hasNextJvmInsnOrFrame(insnIndex)) { + break; + } + } catch (AnalyzerException e) { + throw new AnalyzerException( + e.node, "Error at instruction " + insnIndex + ": " + e.getMessage(), e); + } catch (RuntimeException e) { + // DontCheck(IllegalCatch): can't be fixed, for backward compatibility. + throw new AnalyzerException( + insnNode, "Error at instruction " + insnIndex + ": " + e.getMessage(), e); + } + } + } + + /** + * Expands the {@link FrameNode} "instructions" of the given method into {@link Frame} objects and + * stores them at the corresponding indices of the {@link #frames} array. The expanded frames are + * also associated with the label and line number nodes immediately preceding each frame node. + * + * @param owner the internal name of the class to which 'method' belongs. + * @param method the method whose frames must be expanded. + * @param initialFrame the implicit initial frame of 'method'. + * @throws AnalyzerException if the stack map frames of 'method', i.e. its FrameNode + * "instructions", are invalid. + */ + private void expandFrames( + final String owner, final MethodNode method, final Frame initialFrame) + throws AnalyzerException { + int lastJvmOrFrameInsnIndex = -1; + Frame currentFrame = initialFrame; + int currentInsnIndex = 0; + for (AbstractInsnNode insnNode : method.instructions) { + if (insnNode instanceof FrameNode) { + try { + currentFrame = expandFrame(owner, currentFrame, (FrameNode) insnNode); + } catch (AnalyzerException e) { + throw new AnalyzerException( + e.node, "Error at instruction " + currentInsnIndex + ": " + e.getMessage(), e); + } + for (int index = lastJvmOrFrameInsnIndex + 1; index <= currentInsnIndex; ++index) { + getFrames()[index] = currentFrame; + } + } + if (isJvmInsnNode(insnNode) || insnNode instanceof FrameNode) { + lastJvmOrFrameInsnIndex = currentInsnIndex; + } + currentInsnIndex += 1; + } + } + + /** + * Returns the expanded representation of the given {@link FrameNode}. + * + * @param owner the internal name of the class to which 'frameNode' belongs. + * @param previousFrame the frame before 'frameNode', in expanded form. + * @param frameNode a possibly compressed stack map frame. + * @return the expanded version of 'frameNode'. + * @throws AnalyzerException if 'frameNode' is invalid. + */ + private Frame expandFrame( + final String owner, final Frame previousFrame, final FrameNode frameNode) + throws AnalyzerException { + Frame frame = newFrame(previousFrame); + List locals = frameNode.local == null ? Collections.emptyList() : frameNode.local; + int currentLocal = currentLocals; + switch (frameNode.type) { + case Opcodes.F_NEW: + case Opcodes.F_FULL: + currentLocal = 0; + // fall through + case Opcodes.F_APPEND: + for (Object type : locals) { + V value = newFrameValue(owner, frameNode, type); + if (currentLocal + value.getSize() > frame.getLocals()) { + throw new AnalyzerException(frameNode, "Cannot append more locals than maxLocals"); + } + frame.setLocal(currentLocal++, value); + if (value.getSize() == 2) { + frame.setLocal(currentLocal++, interpreter.newValue(null)); + } + } + break; + case Opcodes.F_CHOP: + for (Object unusedType : locals) { + if (currentLocal <= 0) { + throw new AnalyzerException(frameNode, "Cannot chop more locals than defined"); + } + if (currentLocal > 1 && frame.getLocal(currentLocal - 2).getSize() == 2) { + currentLocal -= 2; + } else { + currentLocal -= 1; + } + } + break; + case Opcodes.F_SAME: + case Opcodes.F_SAME1: + break; + default: + throw new AnalyzerException(frameNode, "Illegal frame type " + frameNode.type); + } + currentLocals = currentLocal; + while (currentLocal < frame.getLocals()) { + frame.setLocal(currentLocal++, interpreter.newValue(null)); + } + + List stack = frameNode.stack == null ? Collections.emptyList() : frameNode.stack; + frame.clearStack(); + for (Object type : stack) { + frame.push(newFrameValue(owner, frameNode, type)); + } + return frame; + } + + /** + * Creates a new {@link Value} that represents the given stack map frame type. + * + * @param owner the internal name of the class to which 'frameNode' belongs. + * @param frameNode the stack map frame to which 'type' belongs. + * @param type an Integer, String or LabelNode object representing a primitive, reference or + * uninitialized a stack map frame type, respectively. See {@link FrameNode}. + * @return a value that represents the given type. + * @throws AnalyzerException if 'type' is an invalid stack map frame type. + */ + private V newFrameValue(final String owner, final FrameNode frameNode, final Object type) + throws AnalyzerException { + if (type == Opcodes.TOP) { + return interpreter.newValue(null); + } else if (type == Opcodes.INTEGER) { + return interpreter.newValue(Type.INT_TYPE); + } else if (type == Opcodes.FLOAT) { + return interpreter.newValue(Type.FLOAT_TYPE); + } else if (type == Opcodes.LONG) { + return interpreter.newValue(Type.LONG_TYPE); + } else if (type == Opcodes.DOUBLE) { + return interpreter.newValue(Type.DOUBLE_TYPE); + } else if (type == Opcodes.NULL) { + return interpreter.newOperation(new InsnNode(Opcodes.ACONST_NULL)); + } else if (type == Opcodes.UNINITIALIZED_THIS) { + return interpreter.newValue(Type.getObjectType(owner)); + } else if (type instanceof String) { + return interpreter.newValue(Type.getObjectType((String) type)); + } else if (type instanceof LabelNode) { + AbstractInsnNode referencedNode = (LabelNode) type; + while (referencedNode != null && !isJvmInsnNode(referencedNode)) { + referencedNode = referencedNode.getNext(); + } + if (referencedNode == null || referencedNode.getOpcode() != Opcodes.NEW) { + throw new AnalyzerException(frameNode, "LabelNode does not designate a NEW instruction"); + } + return interpreter.newValue(Type.getObjectType(((TypeInsnNode) referencedNode).desc)); + } + throw new AnalyzerException(frameNode, "Illegal stack map frame value " + type); + } + + /** + * Checks that the given frame is compatible with the frame at the given instruction index, if + * any. If there is no frame at this instruction index and none is required, the frame at + * 'insnIndex' is set to the given frame. Otherwise, if the merge of the two frames is not equal + * to the current frame at 'insnIndex', an exception is thrown. + * + * @param insnIndex an instruction index. + * @param frame a frame. This frame is left unchanged by this method. + * @param requireFrame whether a frame must already exist or not in {@link #frames} at + * 'insnIndex'. + * @throws AnalyzerException if the frames have incompatible sizes or if the frame at 'insnIndex' + * is missing (if required) or not compatible with 'frame'. + */ + private void checkFrame(final int insnIndex, final Frame frame, final boolean requireFrame) + throws AnalyzerException { + Frame oldFrame = getFrames()[insnIndex]; + if (oldFrame == null) { + if (requireFrame) { + throw new AnalyzerException(null, "Expected stack map frame at instruction " + insnIndex); + } + getFrames()[insnIndex] = newFrame(frame); + } else { + String error = checkMerge(frame, oldFrame); + if (error != null) { + throw new AnalyzerException( + null, + "Stack map frame incompatible with frame at instruction " + + insnIndex + + " (" + + error + + ")"); + } + } + } + + /** + * Checks that merging the two given frames would not produce any change, i.e. that the types in + * the source frame are sub types of the corresponding types in the destination frame. + * + * @param srcFrame a source frame. This frame is left unchanged by this method. + * @param dstFrame a destination frame. This frame is left unchanged by this method. + * @return an error message if the frames have incompatible sizes, or if a type in the source + * frame is not a sub type of the corresponding type in the destination frame. Returns + * {@literal null} otherwise. + */ + private String checkMerge(final Frame srcFrame, final Frame dstFrame) { + int numLocals = srcFrame.getLocals(); + if (numLocals != dstFrame.getLocals()) { + throw new AssertionError(); + } + for (int i = 0; i < numLocals; ++i) { + V v = interpreter.merge(srcFrame.getLocal(i), dstFrame.getLocal(i)); + if (!v.equals(dstFrame.getLocal(i))) { + return "incompatible types at local " + + i + + ": " + + srcFrame.getLocal(i) + + " and " + + dstFrame.getLocal(i); + } + } + int numStack = srcFrame.getStackSize(); + if (numStack != dstFrame.getStackSize()) { + return "incompatible stack heights"; + } + for (int i = 0; i < numStack; ++i) { + V v = interpreter.merge(srcFrame.getStack(i), dstFrame.getStack(i)); + if (!v.equals(dstFrame.getStack(i))) { + return "incompatible types at stack item " + + i + + ": " + + srcFrame.getStack(i) + + " and " + + dstFrame.getStack(i); + } + } + return null; + } + + /** + * Ends the control flow graph at the given instruction. This method checks that there is an + * existing frame for the next instruction, if any. + * + * @param insnIndex an instruction index. + * @throws AnalyzerException if 'insnIndex' is not the last instruction and there is no frame at + * 'insnIndex' + 1 in {@link #getFrames}. + */ + private void endControlFlow(final int insnIndex) throws AnalyzerException { + if (hasNextJvmInsnOrFrame(insnIndex) && getFrames()[insnIndex + 1] == null) { + throw new AnalyzerException( + null, "Expected stack map frame at instruction " + (insnIndex + 1)); + } + } + + /** + * Returns true if the given instruction is followed by a JVM instruction or a by stack map frame. + * + * @param insnIndex an instruction index. + * @return true if 'insnIndex' is followed by a JVM instruction or a by stack map frame. + */ + private boolean hasNextJvmInsnOrFrame(final int insnIndex) { + AbstractInsnNode insn = insnList.get(insnIndex).getNext(); + while (insn != null) { + if (isJvmInsnNode(insn) || insn instanceof FrameNode) { + return true; + } + insn = insn.getNext(); + } + return false; + } + + /** + * Returns true if the given instruction node corresponds to a real JVM instruction. + * + * @param insnNode an instruction node. + * @return true except for label, line number and stack map frame nodes. + */ + private static boolean isJvmInsnNode(final AbstractInsnNode insnNode) { + return insnNode.getOpcode() >= 0; + } +} diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java index 6cc0a19e10aa9..59c41108628e9 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java @@ -62,7 +62,6 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -479,16 +478,26 @@ protected CheckMethodAdapter( new MethodNode(api, access, name, descriptor, null, null) { @Override public void visitEnd() { - Analyzer analyzer = new Analyzer<>(new BasicVerifier()); - try { + int originalMaxLocals = maxLocals; + int originalMaxStack = maxStack; + boolean checkMaxStackAndLocals = false; + boolean checkFrames = false; + if (methodVisitor instanceof MethodWriterWrapper) { + MethodWriterWrapper methodWriter = (MethodWriterWrapper) methodVisitor; // If 'methodVisitor' is a MethodWriter of a ClassWriter with no flags to compute the // max stack and locals nor the stack map frames, we know that valid max stack and // locals must be provided. Otherwise we assume they are not needed at this stage. - // TODO(ebruneton): similarly, check that valid stack map frames are provided if the - // class writer has no flags to compute them, and the class version is V1_7 or more. - boolean checkMaxStackAndLocals = - (methodVisitor instanceof MethodWriterWrapper) - && !((MethodWriterWrapper) methodVisitor).computesMaxs(); + checkMaxStackAndLocals = !methodWriter.computesMaxs(); + // If 'methodVisitor' is a MethodWriter of a ClassWriter with no flags to compute the + // stack map frames, we know that valid frames must be provided. Otherwise we assume + // they are not needed at this stage. + checkFrames = methodWriter.requiresFrames() && !methodWriter.computesFrames(); + } + Analyzer analyzer = + checkFrames + ? new CheckFrameAnalyzer<>(new BasicVerifier()) + : new Analyzer<>(new BasicVerifier()); + try { if (checkMaxStackAndLocals) { analyzer.analyze("dummy", this); } else { @@ -498,6 +507,8 @@ public void visitEnd() { throwError(analyzer, e); } if (methodVisitor != null) { + maxLocals = originalMaxLocals; + maxStack = originalMaxStack; accept(methodVisitor); } } @@ -808,9 +819,8 @@ public void visitJumpInsn(final int opcode, final Label label) { checkVisitCodeCalled(); checkVisitMaxsNotCalled(); checkOpcodeMethod(opcode, Method.VISIT_JUMP_INSN); - checkLabel(label, false, "label"); + checkLabel(label, /* checkVisited = */ false, "label"); super.visitJumpInsn(opcode, label); - referencedLabels.add(label); ++insnCount; } @@ -818,7 +828,7 @@ public void visitJumpInsn(final int opcode, final Label label) { public void visitLabel(final Label label) { checkVisitCodeCalled(); checkVisitMaxsNotCalled(); - checkLabel(label, false, "label"); + checkLabel(label, /* checkVisited = */ false, "label"); if (labelInsnIndices.get(label) != null) { throw new IllegalStateException("Already visited label"); } @@ -854,15 +864,14 @@ public void visitTableSwitchInsn( throw new IllegalArgumentException( "Max = " + max + " must be greater than or equal to min = " + min); } - checkLabel(dflt, false, "default label"); + checkLabel(dflt, /* checkVisited = */ false, "default label"); if (labels == null || labels.length != max - min + 1) { throw new IllegalArgumentException("There must be max - min + 1 labels"); } for (int i = 0; i < labels.length; ++i) { - checkLabel(labels[i], false, "label at index " + i); + checkLabel(labels[i], /* checkVisited = */ false, "label at index " + i); } super.visitTableSwitchInsn(min, max, dflt, labels); - Collections.addAll(referencedLabels, labels); ++insnCount; } @@ -870,16 +879,14 @@ public void visitTableSwitchInsn( public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { checkVisitMaxsNotCalled(); checkVisitCodeCalled(); - checkLabel(dflt, false, "default label"); + checkLabel(dflt, /* checkVisited = */ false, "default label"); if (keys == null || labels == null || keys.length != labels.length) { throw new IllegalArgumentException("There must be the same number of keys and labels"); } for (int i = 0; i < labels.length; ++i) { - checkLabel(labels[i], false, "label at index " + i); + checkLabel(labels[i], /* checkVisited = */ false, "label at index " + i); } super.visitLookupSwitchInsn(dflt, keys, labels); - referencedLabels.add(dflt); - Collections.addAll(referencedLabels, labels); ++insnCount; } @@ -933,9 +940,9 @@ public void visitTryCatchBlock( final Label start, final Label end, final Label handler, final String type) { checkVisitCodeCalled(); checkVisitMaxsNotCalled(); - checkLabel(start, false, START_LABEL); - checkLabel(end, false, END_LABEL); - checkLabel(handler, false, "handler label"); + checkLabel(start, /* checkVisited = */ false, START_LABEL); + checkLabel(end, /* checkVisited = */ false, END_LABEL); + checkLabel(handler, /* checkVisited = */ false, "handler label"); if (labelInsnIndices.get(start) != null || labelInsnIndices.get(end) != null || labelInsnIndices.get(handler) != null) { @@ -979,8 +986,8 @@ public void visitLocalVariable( if (signature != null) { CheckClassAdapter.checkFieldSignature(signature); } - checkLabel(start, true, START_LABEL); - checkLabel(end, true, END_LABEL); + checkLabel(start, /* checkVisited = */ true, START_LABEL); + checkLabel(end, /* checkVisited = */ true, END_LABEL); checkUnsignedShort(index, INVALID_LOCAL_VARIABLE_INDEX); int startInsnIndex = labelInsnIndices.get(start).intValue(); int endInsnIndex = labelInsnIndices.get(end).intValue(); @@ -1017,8 +1024,8 @@ public AnnotationVisitor visitLocalVariableAnnotation( "Invalid start, end and index arrays (must be non null and of identical length"); } for (int i = 0; i < start.length; ++i) { - checkLabel(start[i], true, START_LABEL); - checkLabel(end[i], true, END_LABEL); + checkLabel(start[i], /* checkVisited = */ true, START_LABEL); + checkLabel(end[i], /* checkVisited = */ true, END_LABEL); checkUnsignedShort(index[i], INVALID_LOCAL_VARIABLE_INDEX); int startInsnIndex = labelInsnIndices.get(start[i]).intValue(); int endInsnIndex = labelInsnIndices.get(end[i]).intValue(); @@ -1036,7 +1043,7 @@ public void visitLineNumber(final int line, final Label start) { checkVisitCodeCalled(); checkVisitMaxsNotCalled(); checkUnsignedShort(line, "Invalid line number"); - checkLabel(start, true, START_LABEL); + checkLabel(start, /* checkVisited = */ true, START_LABEL); super.visitLineNumber(line, start); } @@ -1053,11 +1060,8 @@ public void visitMaxs(final int maxStack, final int maxLocals) { for (int i = 0; i < handlers.size(); i += 2) { Integer startInsnIndex = labelInsnIndices.get(handlers.get(i)); Integer endInsnIndex = labelInsnIndices.get(handlers.get(i + 1)); - if (startInsnIndex == null || endInsnIndex == null) { - throw new IllegalStateException("Undefined try catch block labels"); - } if (endInsnIndex.intValue() <= startInsnIndex.intValue()) { - throw new IllegalStateException("Emty try catch block handler range"); + throw new IllegalStateException("Empty try catch block handler range"); } } checkUnsignedShort(maxStack, "Invalid max stack"); @@ -1116,7 +1120,7 @@ private void checkFrameValue(final Object value) { if (value instanceof String) { checkInternalName(version, (String) value, "Invalid stack frame value"); } else if (value instanceof Label) { - referencedLabels.add((Label) value); + checkLabel((Label) value, /* checkVisited = */ false, "label"); } else { throw new IllegalArgumentException("Invalid stack frame value: " + value); } @@ -1129,9 +1133,13 @@ private void checkFrameValue(final Object value) { * @param method the expected visit method. */ private static void checkOpcodeMethod(final int opcode, final Method method) { - if (opcode < Opcodes.NOP || opcode > Opcodes.IFNONNULL || OPCODE_METHODS[opcode] != method) { + if (opcode < Opcodes.NOP || opcode > Opcodes.IFNONNULL) { throw new IllegalArgumentException("Invalid opcode: " + opcode); } + if (OPCODE_METHODS[opcode] != method) { + throw new IllegalArgumentException( + "Invalid combination of opcode and method: " + opcode + ", " + method); + } } /** @@ -1476,20 +1484,36 @@ private void checkLabel(final Label label, final boolean checkVisited, final Str if (checkVisited && labelInsnIndices.get(label) == null) { throw new IllegalArgumentException(INVALID + message + " (must be visited first)"); } + referencedLabels.add(label); } static class MethodWriterWrapper extends MethodVisitor { + /** The class version number. */ + private final int version; + private final ClassWriter owner; - MethodWriterWrapper(final int api, final ClassWriter owner, final MethodVisitor methodWriter) { + MethodWriterWrapper( + final int api, + final int version, + final ClassWriter owner, + final MethodVisitor methodWriter) { super(api, methodWriter); + this.version = version; this.owner = owner; } boolean computesMaxs() { return owner.hasFlags(ClassWriter.COMPUTE_MAXS) || owner.hasFlags(ClassWriter.COMPUTE_FRAMES); } + + boolean computesFrames() { + return owner.hasFlags(ClassWriter.COMPUTE_FRAMES); + } + + boolean requiresFrames() { + return (version & 0xFFFF) >= Opcodes.V1_7; + } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckModuleAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckModuleAdapter.java index b84545e3a5b27..de94a1d32dddd 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckModuleAdapter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckModuleAdapter.java @@ -242,4 +242,3 @@ void checkNameNotAlreadyDeclared(final String name) { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckRecordComponentAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckRecordComponentAdapter.java index 98cbb9c4e42f4..850f1c8dc3e7a 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckRecordComponentAdapter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckRecordComponentAdapter.java @@ -151,4 +151,3 @@ private void checkVisitEndNotCalled() { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java index 5da63a1d5515c..19a3998f0a212 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java @@ -389,4 +389,3 @@ private void checkIdentifier(final String name, final String message) { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java index 53ec0ab6cb2d8..00378e8dccef5 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java @@ -370,15 +370,14 @@ protected Printer(final int api) { * and the major version in the 16 least significant bits. * @param access the class's access flags (see {@link Opcodes}). This parameter also indicates if * the class is deprecated. - * @param name the internal name of the class (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName()}). + * @param name the internal name of the class (see {@link Type#getInternalName()}). * @param signature the signature of this class. May be {@literal null} if the class is not a * generic one, and does not extend or implement generic classes or interfaces. - * @param superName the internal of name of the super class (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName()}). For interfaces, the super class is {@link - * Object}. May be {@literal null}, but only for the {@link Object} class. + * @param superName the internal of name of the super class (see {@link Type#getInternalName()}). + * For interfaces, the super class is {@link Object}. May be {@literal null}, but only for the + * {@link Object} class. * @param interfaces the internal names of the class's interfaces (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. + * Type#getInternalName()}). May be {@literal null}. */ public abstract void visit( int version, @@ -419,7 +418,8 @@ public Printer visitModule(final String name, final int access, final String ver * implicitly its own nest, so it's invalid to call this method with the visited class name as * argument. * - * @param nestHost the internal name of the host class of the nest. + * @param nestHost the internal name of the host class of the nest (see {@link + * Type#getInternalName()}). */ public void visitNestHost(final String nestHost) { throw new UnsupportedOperationException(UNSUPPORTED_OPERATION); @@ -428,7 +428,8 @@ public void visitNestHost(final String nestHost) { /** * Class outer class. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitOuterClass}. * - * @param owner internal name of the enclosing class of the class. + * @param owner internal name of the enclosing class of the class (see {@link + * Type#getInternalName()}). * @param name the name of the method that contains the class, or {@literal null} if the class is * not enclosed in a method of its enclosing class. * @param descriptor the descriptor of the method that contains the class, or {@literal null} if @@ -449,10 +450,9 @@ public void visitNestHost(final String nestHost) { * Class type annotation. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitTypeAnnotation}. * * @param typeRef a reference to the annotated type. The sort of this type reference must be - * {@link jdk.internal.org.objectweb.asm.TypeReference#CLASS_TYPE_PARAMETER}, {@link - * jdk.internal.org.objectweb.asm.TypeReference#CLASS_TYPE_PARAMETER_BOUND} or {@link - * jdk.internal.org.objectweb.asm.TypeReference#CLASS_EXTENDS}. See {@link - * jdk.internal.org.objectweb.asm.TypeReference}. + * {@link TypeReference#CLASS_TYPE_PARAMETER}, {@link + * TypeReference#CLASS_TYPE_PARAMETER_BOUND} or {@link TypeReference#CLASS_EXTENDS}. See + * {@link TypeReference}. * @param typePath the path to the annotated type argument, wildcard bound, array element type, or * static inner type within 'typeRef'. May be {@literal null} if the annotation targets * 'typeRef' as a whole. @@ -479,7 +479,7 @@ public Printer visitClassTypeAnnotation( * the visited class is the host of a nest. A nest host is implicitly a member of its own nest, so * it's invalid to call this method with the visited class name as argument. * - * @param nestMember the internal name of a nest member. + * @param nestMember the internal name of a nest member (see {@link Type#getInternalName()}). */ public void visitNestMember(final String nestMember) { throw new UnsupportedOperationException(UNSUPPORTED_OPERATION); @@ -489,7 +489,8 @@ public void visitNestMember(final String nestMember) { * Visits a permitted subclasses. A permitted subclass is one of the allowed subclasses of the * current class. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitPermittedSubclass(String)}. * - * @param permittedSubclass the internal name of a permitted subclass. + * @param permittedSubclass the internal name of a permitted subclass (see {@link + * Type#getInternalName()}). */ public void visitPermittedSubclass(final String permittedSubclass) { throw new UnsupportedOperationException(UNSUPPORTED_OPERATION); @@ -498,10 +499,9 @@ public void visitPermittedSubclass(final String permittedSubclass) { /** * Class inner name. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitInnerClass}. * - * @param name the internal name of an inner class (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName()}). + * @param name the internal name of an inner class (see {@link Type#getInternalName()}). * @param outerName the internal name of the class to which the inner class belongs (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName()}). May be {@literal null} for not member classes. + * Type#getInternalName()}). May be {@literal null} for not member classes. * @param innerName the (simple) name of the inner class inside its enclosing class. May be * {@literal null} for anonymous inner classes. * @param access the access flags of the inner class as originally declared in the enclosing @@ -531,7 +531,7 @@ public Printer visitRecordComponent( * @param access the field's access flags (see {@link Opcodes}). This parameter also indicates if * the field is synthetic and/or deprecated. * @param name the field's name. - * @param descriptor the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}). + * @param descriptor the field's descriptor (see {@link Type}). * @param signature the field's signature. May be {@literal null} if the field's type does not use * generic types. * @param value the field's initial value. This parameter, which may be {@literal null} if the @@ -551,11 +551,11 @@ public abstract Printer visitField( * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if * the method is synthetic and/or deprecated. * @param name the method's name. - * @param descriptor the method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}). + * @param descriptor the method's descriptor (see {@link Type}). * @param signature the method's signature. May be {@literal null} if the method parameters, * return type and exceptions do not use generic types. * @param exceptions the internal names of the method's exception classes (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. + * Type#getInternalName()}). May be {@literal null}. * @return the printer. */ public abstract Printer visitMethod( @@ -571,7 +571,8 @@ public abstract Printer visitMethod( /** * Module main class. See {@link jdk.internal.org.objectweb.asm.ModuleVisitor#visitMainClass}. * - * @param mainClass the internal name of the main class of the current module. + * @param mainClass the internal name of the main class of the current module (see {@link + * Type#getInternalName()}). */ public void visitMainClass(final String mainClass) { throw new UnsupportedOperationException(UNSUPPORTED_OPERATION); @@ -580,7 +581,7 @@ public void visitMainClass(final String mainClass) { /** * Module package. See {@link jdk.internal.org.objectweb.asm.ModuleVisitor#visitPackage}. * - * @param packaze the internal name of a package. + * @param packaze the internal name of a package (see {@link Type#getInternalName()}). */ public void visitPackage(final String packaze) { throw new UnsupportedOperationException(UNSUPPORTED_OPERATION); @@ -601,7 +602,7 @@ public void visitRequire(final String module, final int access, final String ver /** * Module export. See {@link jdk.internal.org.objectweb.asm.ModuleVisitor#visitExport}. * - * @param packaze the internal name of the exported package. + * @param packaze the internal name of the exported package (see {@link Type#getInternalName()}). * @param access the access flag of the exported package, valid values are among {@code * ACC_SYNTHETIC} and {@code ACC_MANDATED}. * @param modules the fully qualified names (using dots) of the modules that can access the public @@ -614,7 +615,7 @@ public void visitExport(final String packaze, final int access, final String... /** * Module open. See {@link jdk.internal.org.objectweb.asm.ModuleVisitor#visitOpen}. * - * @param packaze the internal name of the opened package. + * @param packaze the internal name of the opened package (see {@link Type#getInternalName()}). * @param access the access flag of the opened package, valid values are among {@code * ACC_SYNTHETIC} and {@code ACC_MANDATED}. * @param modules the fully qualified names (using dots) of the modules that can use deep @@ -627,7 +628,7 @@ public void visitOpen(final String packaze, final int access, final String... mo /** * Module use. See {@link jdk.internal.org.objectweb.asm.ModuleVisitor#visitUse}. * - * @param service the internal name of the service. + * @param service the internal name of the service (see {@link Type#getInternalName()}). */ public void visitUse(final String service) { throw new UnsupportedOperationException(UNSUPPORTED_OPERATION); @@ -636,7 +637,7 @@ public void visitUse(final String service) { /** * Module provide. See {@link jdk.internal.org.objectweb.asm.ModuleVisitor#visitProvide}. * - * @param service the internal name of the service. + * @param service the internal name of the service (see {@link Type#getInternalName()}). * @param providers the internal names of the implementations of the service (there is at least * one provider). */ @@ -659,10 +660,10 @@ public void visitModuleEnd() { * @param name the value name. * @param value the actual value, whose type must be {@link Byte}, {@link Boolean}, {@link * Character}, {@link Short}, {@link Integer} , {@link Long}, {@link Float}, {@link Double}, - * {@link String} or {@link jdk.internal.org.objectweb.asm.Type} of {@link jdk.internal.org.objectweb.asm.Type#OBJECT} - * or {@link jdk.internal.org.objectweb.asm.Type#ARRAY} sort. This value can also be an array of byte, - * boolean, short, char, int, long, float or double values (this is equivalent to using {@link - * #visitArray} and visiting each array element in turn, but is more convenient). + * {@link String} or {@link Type} of {@link Type#OBJECT} or {@link Type#ARRAY} sort. This + * value can also be an array of byte, boolean, short, char, int, long, float or double values + * (this is equivalent to using {@link #visitArray} and visiting each array element in turn, + * but is more convenient). */ // DontCheck(OverloadMethodsDeclarationOrder): overloads are semantically different. public abstract void visit(String name, Object value); @@ -770,7 +771,7 @@ public void visitRecordComponentEnd() { * Field type annotation. See {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitTypeAnnotation}. * * @param typeRef a reference to the annotated type. The sort of this type reference must be - * {@link jdk.internal.org.objectweb.asm.TypeReference#FIELD}. See {@link jdk.internal.org.objectweb.asm.TypeReference}. + * {@link TypeReference#FIELD}. See {@link TypeReference}. * @param typePath the path to the annotated type argument, wildcard bound, array element type, or * static inner type within 'typeRef'. May be {@literal null} if the annotation targets * 'typeRef' as a whole. @@ -828,12 +829,10 @@ public void visitParameter(final String name, final int access) { * Method type annotation. See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTypeAnnotation}. * * @param typeRef a reference to the annotated type. The sort of this type reference must be - * {@link jdk.internal.org.objectweb.asm.TypeReference#METHOD_TYPE_PARAMETER}, {@link - * jdk.internal.org.objectweb.asm.TypeReference#METHOD_TYPE_PARAMETER_BOUND}, {@link - * jdk.internal.org.objectweb.asm.TypeReference#METHOD_RETURN}, {@link - * jdk.internal.org.objectweb.asm.TypeReference#METHOD_RECEIVER}, {@link - * jdk.internal.org.objectweb.asm.TypeReference#METHOD_FORMAL_PARAMETER} or {@link - * jdk.internal.org.objectweb.asm.TypeReference#THROWS}. See {@link jdk.internal.org.objectweb.asm.TypeReference}. + * {@link TypeReference#METHOD_TYPE_PARAMETER}, {@link + * TypeReference#METHOD_TYPE_PARAMETER_BOUND}, {@link TypeReference#METHOD_RETURN}, {@link + * TypeReference#METHOD_RECEIVER}, {@link TypeReference#METHOD_FORMAL_PARAMETER} or {@link + * TypeReference#THROWS}. See {@link TypeReference}. * @param typePath the path to the annotated type argument, wildcard bound, array element type, or * static inner type within 'typeRef'. May be {@literal null} if the annotation targets * 'typeRef' as a whole. @@ -902,9 +901,9 @@ public abstract Printer visitParameterAnnotation( * types are represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link * Opcodes#FLOAT}, {@link Opcodes#LONG}, {@link Opcodes#DOUBLE}, {@link Opcodes#NULL} or * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a single element). - * Reference types are represented by String objects (representing internal names), and - * uninitialized types by Label objects (this label designates the NEW instruction that - * created this uninitialized value). + * Reference types are represented by String objects (representing internal names, see {@link + * Type#getInternalName()}), and uninitialized types by Label objects (this label designates + * the NEW instruction that created this uninitialized value). * @param numStack the number of operand stack elements in the visited frame. * @param stack the operand stack types in this frame. This array must not be modified. Its * content has the same format as the "local" array. @@ -960,7 +959,7 @@ public abstract void visitFrame( * @param opcode the opcode of the type instruction to be visited. This opcode is either NEW, * ANEWARRAY, CHECKCAST or INSTANCEOF. * @param type the operand of the instruction to be visited. This operand must be the internal - * name of an object or array class (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName()}). + * name of an object or array class (see {@link Type#getInternalName()}). */ public abstract void visitTypeInsn(int opcode, String type); @@ -969,10 +968,9 @@ public abstract void visitFrame( * * @param opcode the opcode of the type instruction to be visited. This opcode is either * GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. - * @param owner the internal name of the field's owner class (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName()}). + * @param owner the internal name of the field's owner class (see {@link Type#getInternalName()}). * @param name the field's name. - * @param descriptor the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}). + * @param descriptor the field's descriptor (see {@link Type}). */ public abstract void visitFieldInsn(int opcode, String owner, String name, String descriptor); @@ -982,9 +980,9 @@ public abstract void visitFrame( * @param opcode the opcode of the type instruction to be visited. This opcode is either * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE. * @param owner the internal name of the method's owner class (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName()}). + * Type#getInternalName()}). * @param name the method's name. - * @param descriptor the method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}). + * @param descriptor the method's descriptor (see {@link Type}). * @deprecated use {@link #visitMethodInsn(int, String, String, String, boolean)} instead. */ @Deprecated @@ -1002,9 +1000,9 @@ public void visitMethodInsn( * @param opcode the opcode of the type instruction to be visited. This opcode is either * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE. * @param owner the internal name of the method's owner class (see {@link - * jdk.internal.org.objectweb.asm.Type#getInternalName()}). + * Type#getInternalName()}). * @param name the method's name. - * @param descriptor the method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}). + * @param descriptor the method's descriptor (see {@link Type}). * @param isInterface if the method's owner class is an interface. */ public void visitMethodInsn( @@ -1020,12 +1018,12 @@ public void visitMethodInsn( * Method instruction. See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInvokeDynamicInsn}. * * @param name the method's name. - * @param descriptor the method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}). + * @param descriptor the method's descriptor (see {@link Type}). * @param bootstrapMethodHandle the bootstrap method. * @param bootstrapMethodArguments the bootstrap method constant arguments. Each argument must be * an {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String}, {@link - * jdk.internal.org.objectweb.asm.Type} or {@link Handle} value. This method is allowed to modify the - * content of the array so a caller should expect that this array may change. + * Type} or {@link Handle} value. This method is allowed to modify the content of the array so + * a caller should expect that this array may change. */ public abstract void visitInvokeDynamicInsn( String name, @@ -1095,7 +1093,7 @@ public abstract void visitInvokeDynamicInsn( /** * Method instruction. See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMultiANewArrayInsn}. * - * @param descriptor an array type descriptor (see {@link jdk.internal.org.objectweb.asm.Type}). + * @param descriptor an array type descriptor (see {@link Type}). * @param numDimensions the number of dimensions of the array to allocate. */ public abstract void visitMultiANewArrayInsn(String descriptor, int numDimensions); @@ -1104,16 +1102,12 @@ public abstract void visitInvokeDynamicInsn( * Instruction type annotation. See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInsnAnnotation}. * * @param typeRef a reference to the annotated type. The sort of this type reference must be - * {@link jdk.internal.org.objectweb.asm.TypeReference#INSTANCEOF}, {@link - * jdk.internal.org.objectweb.asm.TypeReference#NEW}, {@link - * jdk.internal.org.objectweb.asm.TypeReference#CONSTRUCTOR_REFERENCE}, {@link - * jdk.internal.org.objectweb.asm.TypeReference#METHOD_REFERENCE}, {@link - * jdk.internal.org.objectweb.asm.TypeReference#CAST}, {@link - * jdk.internal.org.objectweb.asm.TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link - * jdk.internal.org.objectweb.asm.TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT}, {@link - * jdk.internal.org.objectweb.asm.TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link - * jdk.internal.org.objectweb.asm.TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link - * jdk.internal.org.objectweb.asm.TypeReference}. + * {@link TypeReference#INSTANCEOF}, {@link TypeReference#NEW}, {@link + * TypeReference#CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE}, {@link + * TypeReference#CAST}, {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link + * TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT}, {@link + * TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link + * TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}. * @param typePath the path to the annotated type argument, wildcard bound, array element type, or * static inner type within 'typeRef'. May be {@literal null} if the annotation targets * 'typeRef' as a whole. @@ -1132,8 +1126,9 @@ public Printer visitInsnAnnotation( * @param start the beginning of the exception handler's scope (inclusive). * @param end the end of the exception handler's scope (exclusive). * @param handler the beginning of the exception handler's code. - * @param type the internal name of the type of exceptions handled by the handler, or {@literal - * null} to catch any exceptions (for "finally" blocks). + * @param type the internal name of the type of exceptions handled by the handler (see {@link + * Type#getInternalName()}), or {@literal null} to catch any exceptions (for "finally" + * blocks). */ public abstract void visitTryCatchBlock(Label start, Label end, Label handler, String type); @@ -1142,8 +1137,7 @@ public Printer visitInsnAnnotation( * jdk.internal.org.objectweb.asm.MethodVisitor#visitTryCatchAnnotation}. * * @param typeRef a reference to the annotated type. The sort of this type reference must be - * {@link jdk.internal.org.objectweb.asm.TypeReference#EXCEPTION_PARAMETER}. See {@link - * jdk.internal.org.objectweb.asm.TypeReference}. + * {@link TypeReference#EXCEPTION_PARAMETER}. See {@link TypeReference}. * @param typePath the path to the annotated type argument, wildcard bound, array element type, or * static inner type within 'typeRef'. May be {@literal null} if the annotation targets * 'typeRef' as a whole. @@ -1176,9 +1170,8 @@ public abstract void visitLocalVariable( * jdk.internal.org.objectweb.asm.MethodVisitor#visitTryCatchAnnotation}. * * @param typeRef a reference to the annotated type. The sort of this type reference must be - * {@link jdk.internal.org.objectweb.asm.TypeReference#LOCAL_VARIABLE} or {@link - * jdk.internal.org.objectweb.asm.TypeReference#RESOURCE_VARIABLE}. See {@link - * jdk.internal.org.objectweb.asm.TypeReference}. + * {@link TypeReference#LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE}. See {@link + * TypeReference}. * @param typePath the path to the annotated type argument, wildcard bound, array element type, or * static inner type within 'typeRef'. May be {@literal null} if the annotation targets * 'typeRef' as a whole. @@ -1347,4 +1340,3 @@ static void main( } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java index e6006a3cb48f6..fe8a9c8bf318e 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java @@ -87,7 +87,9 @@ public class Textifier extends Printer { "Prints a disassembled view of the given class.\n" + "Usage: Textifier [-nodebug] "; - /** The type of internal names. See {@link #appendDescriptor}. */ + /** + * The type of internal names (see {@link Type#getInternalName()}). See {@link #appendDescriptor}. + */ public static final int INTERNAL_NAME = 0; /** The type of field descriptors. See {@link #appendDescriptor}. */ @@ -1355,7 +1357,8 @@ private void appendRawAccess(final int accessFlags) { * @param type the type of 'value'. Must be one of {@link #INTERNAL_NAME}, {@link * #FIELD_DESCRIPTOR}, {@link #FIELD_SIGNATURE}, {@link #METHOD_DESCRIPTOR}, {@link * #METHOD_SIGNATURE}, {@link #CLASS_SIGNATURE} or {@link #HANDLE_DESCRIPTOR}. - * @param value an internal name, type descriptor or a type signature. May be {@literal null}. + * @param value an internal name (see {@link Type#getInternalName()}), type descriptor or a type + * signature. May be {@literal null}. */ protected void appendDescriptor(final int type, final String value) { if (type == CLASS_SIGNATURE || type == FIELD_SIGNATURE || type == METHOD_SIGNATURE) { @@ -1631,4 +1634,3 @@ protected Textifier createTextifier() { return new Textifier(api); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TextifierSupport.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TextifierSupport.java index edc3bf0351b16..4ce8fe8031c03 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TextifierSupport.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TextifierSupport.java @@ -77,4 +77,3 @@ public interface TextifierSupport { */ void textify(StringBuilder outputBuilder, Map labelNames); } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java index 9133b45c5639f..f487c69ca6426 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java @@ -123,4 +123,3 @@ public void visitEnd() { super.visitEnd(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java index eade2bc9c479b..0b1338991ff30 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java @@ -151,7 +151,7 @@ public TraceClassVisitor(final ClassVisitor classVisitor, final PrintWriter prin */ public TraceClassVisitor( final ClassVisitor classVisitor, final Printer printer, final PrintWriter printWriter) { - super(/* latest api = */ Opcodes.ASM9, classVisitor); + super(/* latest api = */ Opcodes.ASM10_EXPERIMENTAL, classVisitor); this.printWriter = printWriter; this.p = printer; } @@ -274,4 +274,3 @@ public void visitEnd() { super.visitEnd(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java index 62cc5939f11df..1dd448c640f88 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java @@ -123,4 +123,3 @@ public void visitEnd() { super.visitEnd(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java index 6d8767ce4ddd2..06f96819d3efa 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java @@ -342,4 +342,3 @@ public void visitEnd() { super.visitEnd(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceRecordComponentVisitor.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceRecordComponentVisitor.java index 2069f299d1a29..e40ce8c79cd62 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceRecordComponentVisitor.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceRecordComponentVisitor.java @@ -126,4 +126,3 @@ public void visitEnd() { super.visitEnd(); } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java index a7ba0fb6a0f1a..ba8da75fdc4f7 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java @@ -374,4 +374,3 @@ private void endType() { } } } - diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/version.txt b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/version.txt index d4db13119b1e0..2ffbbcafa5dfb 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/version.txt +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/version.txt @@ -1,2 +1,2 @@ -ASM_9_3 +ASM_9_6 origin http://gitlab.ow2.org/asm/asm.git (fetch) diff --git a/src/java.base/share/legal/asm.md b/src/java.base/share/legal/asm.md index 0a5d1c9b151a3..40edc652e7cca 100644 --- a/src/java.base/share/legal/asm.md +++ b/src/java.base/share/legal/asm.md @@ -1,4 +1,4 @@ -## ASM Bytecode Manipulation Framework v9.3 +## ASM Bytecode Manipulation Framework v9.6 ### ASM License