Upgrade to ASM master (7.0 beta) and CGLIB 3.2.8
Issue: SPR-17267
This commit is contained in:
parent
e47355078c
commit
1da4d504c4
|
|
@ -7,11 +7,11 @@ dependencyManagement {
|
|||
}
|
||||
}
|
||||
|
||||
// As of Spring 5.0.3, spring-core includes asm 6.x and repackages cglib 3.2.6+, inlining
|
||||
// both into the spring-core jar. cglib 3.2.6+ itself depends on asm 6.x and is therefore
|
||||
// As of Spring 5.1, spring-core includes asm 7.0 and repackages cglib 3.2.8, inlining
|
||||
// both into the spring-core jar. cglib 3.2.8 itself depends on asm 6+ and is therefore
|
||||
// further transformed by the JarJar task to depend on org.springframework.asm; this
|
||||
// avoids including two different copies of asm unnecessarily.
|
||||
def cglibVersion = "3.2.7"
|
||||
def cglibVersion = "3.2.8"
|
||||
def objenesisVersion = "2.6"
|
||||
|
||||
configurations {
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ package org.springframework.asm;
|
|||
|
||||
/**
|
||||
* A visitor to visit a Java annotation. The methods of this class must be called in the following
|
||||
* order: ( <tt>visit</tt> | <tt>visitEnum</tt> | <tt>visitAnnotation</tt> | <tt>visitArray</tt> )*
|
||||
* <tt>visitEnd</tt>.
|
||||
* order: ( {@code visit} | {@code visitEnum} | {@code visitAnnotation} | {@code visitArray} )*
|
||||
* {@code visitEnd}.
|
||||
*
|
||||
* @author Eric Bruneton
|
||||
* @author Eugene Kuleshov
|
||||
|
|
@ -39,7 +39,7 @@ public abstract class AnnotationVisitor {
|
|||
|
||||
/**
|
||||
* The ASM API version implemented by this visitor. The value of this field must be one of {@link
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
|
||||
*/
|
||||
protected final int api;
|
||||
|
||||
|
|
@ -50,8 +50,7 @@ public abstract class AnnotationVisitor {
|
|||
* Constructs a new {@link AnnotationVisitor}.
|
||||
*
|
||||
* @param api the ASM API version implemented by this visitor. Must be one of {@link
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link
|
||||
* Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
|
||||
*/
|
||||
public AnnotationVisitor(final int api) {
|
||||
this(api, null);
|
||||
|
|
@ -61,16 +60,12 @@ public abstract class AnnotationVisitor {
|
|||
* Constructs a new {@link AnnotationVisitor}.
|
||||
*
|
||||
* @param api the ASM API version implemented by this visitor. Must be one of {@link
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link
|
||||
* Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
|
||||
* @param annotationVisitor the annotation visitor to which this visitor must delegate method
|
||||
* calls. May be null.
|
||||
*/
|
||||
public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) {
|
||||
if (api != Opcodes.ASM6
|
||||
&& api != Opcodes.ASM5
|
||||
&& api != Opcodes.ASM4
|
||||
&& api != Opcodes.ASM7_EXPERIMENTAL) {
|
||||
if (api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 && api != Opcodes.ASM7) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.api = api;
|
||||
|
|
@ -112,9 +107,9 @@ public abstract class AnnotationVisitor {
|
|||
*
|
||||
* @param name the value name.
|
||||
* @param descriptor the class descriptor of the nested annotation class.
|
||||
* @return a visitor to visit the actual nested annotation value, or <tt>null</tt> if this visitor
|
||||
* is not interested in visiting this nested annotation. <i>The nested annotation value must
|
||||
* be fully visited before calling other methods on this annotation visitor</i>.
|
||||
* @return a visitor to visit the actual nested annotation value, or {@literal null} if this
|
||||
* visitor is not interested in visiting this nested annotation. <i>The nested annotation
|
||||
* value must be fully visited before calling other methods on this annotation visitor</i>.
|
||||
*/
|
||||
public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
|
||||
if (av != null) {
|
||||
|
|
@ -129,8 +124,8 @@ public abstract class AnnotationVisitor {
|
|||
* visit}. This is what {@link ClassReader} does.
|
||||
*
|
||||
* @param name the value name.
|
||||
* @return a visitor to visit the actual array value elements, or <tt>null</tt> if this visitor is
|
||||
* not interested in visiting these values. The 'name' parameters passed to the methods of
|
||||
* @return a visitor to visit the actual array value elements, or {@literal null} if this visitor
|
||||
* is not interested in visiting these values. The 'name' parameters passed to the methods of
|
||||
* this visitor are ignored. <i>All the array values must be visited before calling other
|
||||
* methods on this annotation visitor</i>.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ final class AnnotationWriter extends AnnotationVisitor {
|
|||
final boolean useNamedValues,
|
||||
final ByteVector annotation,
|
||||
final AnnotationWriter previousAnnotation) {
|
||||
super(Opcodes.ASM6);
|
||||
super(Opcodes.ASM7);
|
||||
this.symbolTable = symbolTable;
|
||||
this.useNamedValues = useNamedValues;
|
||||
this.annotation = annotation;
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ package org.springframework.asm;
|
|||
* A non standard class, field, method or code attribute, as defined in the Java Virtual Machine
|
||||
* Specification (JVMS).
|
||||
*
|
||||
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7">JVMS
|
||||
* @see <a href= "https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7">JVMS
|
||||
* 4.7</a>
|
||||
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.3">JVMS
|
||||
* @see <a href= "https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.3">JVMS
|
||||
* 4.7.3</a>
|
||||
* @author Eric Bruneton
|
||||
* @author Eugene Kuleshov
|
||||
|
|
@ -52,7 +52,7 @@ public class Attribute {
|
|||
|
||||
/**
|
||||
* The next attribute in this attribute list (Attribute instances can be linked via this field to
|
||||
* store a list of class, field, method or code attributes). May be <tt>null</tt>.
|
||||
* store a list of class, field, method or code attributes). May be {@literal null}.
|
||||
*/
|
||||
Attribute nextAttribute;
|
||||
|
||||
|
|
@ -66,23 +66,23 @@ public class Attribute {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this type of attribute is unknown. This means that the attribute
|
||||
* Returns {@literal true} if this type of attribute is unknown. This means that the attribute
|
||||
* content can't be parsed to extract constant pool references, labels, etc. Instead, the
|
||||
* attribute content is read as an opaque byte array, and written back as is. This can lead to
|
||||
* invalid attributes, if the content actually contains constant pool references, labels, or other
|
||||
* symbolic references that need to be updated when there are changes to the constant pool, the
|
||||
* method bytecode, etc. The default implementation of this method always returns <tt>true</tt>.
|
||||
* method bytecode, etc. The default implementation of this method always returns {@literal true}.
|
||||
*
|
||||
* @return <tt>true</tt> if this type of attribute is unknown.
|
||||
* @return {@literal true} if this type of attribute is unknown.
|
||||
*/
|
||||
public boolean isUnknown() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this type of attribute is a code attribute.
|
||||
* Returns {@literal true} if this type of attribute is a code attribute.
|
||||
*
|
||||
* @return <tt>true</tt> if this type of attribute is a code attribute.
|
||||
* @return {@literal true} if this type of attribute is a code attribute.
|
||||
*/
|
||||
public boolean isCodeAttribute() {
|
||||
return false;
|
||||
|
|
@ -91,8 +91,8 @@ public class Attribute {
|
|||
/**
|
||||
* Returns the labels corresponding to this attribute.
|
||||
*
|
||||
* @return the labels corresponding to this attribute, or <tt>null</tt> if this attribute is not a
|
||||
* code attribute that contains labels.
|
||||
* @return the labels corresponding to this attribute, or {@literal null} if this attribute is not
|
||||
* a code attribute that contains labels.
|
||||
*/
|
||||
protected Label[] getLabels() {
|
||||
return new Label[0];
|
||||
|
|
@ -114,8 +114,8 @@ public class Attribute {
|
|||
* in {@link ClassReader#b}, or -1 if the attribute to be read is not a code attribute. The 6
|
||||
* attribute header bytes (attribute_name_index and attribute_length) are not taken into
|
||||
* account here.
|
||||
* @param labels the labels of the method's code, or <tt>null</tt> if the attribute to be read is
|
||||
* not a code attribute.
|
||||
* @param labels the labels of the method's code, or {@literal null} if the attribute to be read
|
||||
* is not a code attribute.
|
||||
* @return a <i>new</i> {@link Attribute} object corresponding to the specified bytes.
|
||||
*/
|
||||
protected Attribute read(
|
||||
|
|
@ -138,7 +138,7 @@ public class Attribute {
|
|||
*
|
||||
* @param classWriter the class to which this attribute must be added. This parameter can be used
|
||||
* to add the items that corresponds to this attribute to the constant pool of this class.
|
||||
* @param code the bytecode of the method corresponding to this code attribute, or <tt>null</tt>
|
||||
* @param code the bytecode of the method corresponding to this code attribute, or {@literal null}
|
||||
* if this attribute is not a code attribute. Corresponds to the 'code' field of the Code
|
||||
* attribute.
|
||||
* @param codeLength the length of the bytecode of the method corresponding to this code
|
||||
|
|
@ -197,8 +197,9 @@ public class Attribute {
|
|||
* attribute_length) per attribute. Also adds the attribute type names to the constant pool.
|
||||
*
|
||||
* @param symbolTable where the constants used in the attributes must be stored.
|
||||
* @param code the bytecode of the method corresponding to these code attributes, or <tt>null</tt>
|
||||
* if they are not code attributes. Corresponds to the 'code' field of the Code attribute.
|
||||
* @param code the bytecode of the method corresponding to these code attributes, or {@literal
|
||||
* null} if they are not code attributes. Corresponds to the 'code' field of the Code
|
||||
* attribute.
|
||||
* @param codeLength the length of the bytecode of the method corresponding to these code
|
||||
* attributes, or 0 if they are not code attributes. Corresponds to the 'code_length' field of
|
||||
* the Code attribute.
|
||||
|
|
@ -248,8 +249,9 @@ public class Attribute {
|
|||
* attribute.
|
||||
*
|
||||
* @param symbolTable where the constants used in the attributes must be stored.
|
||||
* @param code the bytecode of the method corresponding to these code attributes, or <tt>null</tt>
|
||||
* if they are not code attributes. Corresponds to the 'code' field of the Code attribute.
|
||||
* @param code the bytecode of the method corresponding to these code attributes, or {@literal
|
||||
* null} if they are not code attributes. Corresponds to the 'code' field of the Code
|
||||
* attribute.
|
||||
* @param codeLength the length of the bytecode of the method corresponding to these code
|
||||
* attributes, or 0 if they are not code attributes. Corresponds to the 'code_length' field of
|
||||
* the Code attribute.
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ public class ByteVector {
|
|||
* Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if
|
||||
* necessary.
|
||||
*
|
||||
* @param byteArrayValue an array of bytes. May be <tt>null</tt> to put <tt>byteLength</tt> null
|
||||
* @param byteArrayValue an array of bytes. May be {@literal null} to put {@code byteLength} null
|
||||
* bytes into this byte vector.
|
||||
* @param byteOffset index of the first byte of byteArrayValue that must be copied.
|
||||
* @param byteLength number of bytes of byteArrayValue that must be copied.
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@ public class ClassReader {
|
|||
int currentCpInfoIndex = 1;
|
||||
int currentCpInfoOffset = classFileOffset + 10;
|
||||
int currentMaxStringLength = 0;
|
||||
boolean hasBootstrapMethods = false;
|
||||
// The offset of the other entries depend on the total size of all the previous entries.
|
||||
while (currentCpInfoIndex < constantPoolCount) {
|
||||
cpInfoOffsets[currentCpInfoIndex++] = currentCpInfoOffset + 1;
|
||||
|
|
@ -198,9 +199,12 @@ public class ClassReader {
|
|||
case Symbol.CONSTANT_INTEGER_TAG:
|
||||
case Symbol.CONSTANT_FLOAT_TAG:
|
||||
case Symbol.CONSTANT_NAME_AND_TYPE_TAG:
|
||||
cpInfoSize = 5;
|
||||
break;
|
||||
case Symbol.CONSTANT_INVOKE_DYNAMIC_TAG:
|
||||
case Symbol.CONSTANT_DYNAMIC_TAG:
|
||||
cpInfoSize = 5;
|
||||
hasBootstrapMethods = true;
|
||||
break;
|
||||
case Symbol.CONSTANT_LONG_TAG:
|
||||
case Symbol.CONSTANT_DOUBLE_TAG:
|
||||
|
|
@ -236,29 +240,8 @@ public class ClassReader {
|
|||
this.header = currentCpInfoOffset;
|
||||
|
||||
// Read the BootstrapMethods attribute, if any (only get the offset of each method).
|
||||
int currentAttributeOffset = getFirstAttributeOffset();
|
||||
int[] currentBootstrapMethodOffsets = null;
|
||||
for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
|
||||
// Read the attribute_info's attribute_name and attribute_length fields.
|
||||
String attributeName = readUTF8(currentAttributeOffset, new char[maxStringLength]);
|
||||
int attributeLength = readInt(currentAttributeOffset + 2);
|
||||
currentAttributeOffset += 6;
|
||||
if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) {
|
||||
// Read the num_bootstrap_methods field and create an array of this size.
|
||||
currentBootstrapMethodOffsets = new int[readUnsignedShort(currentAttributeOffset)];
|
||||
// Compute and store the offset of each 'bootstrap_methods' array field entry.
|
||||
int currentBootstrapMethodOffset = currentAttributeOffset + 2;
|
||||
for (int j = 0; j < currentBootstrapMethodOffsets.length; ++j) {
|
||||
currentBootstrapMethodOffsets[j] = currentBootstrapMethodOffset;
|
||||
// Skip the bootstrap_method_ref and num_bootstrap_arguments fields (2 bytes each),
|
||||
// as well as the bootstrap_arguments array field (of size num_bootstrap_arguments * 2).
|
||||
currentBootstrapMethodOffset +=
|
||||
4 + readUnsignedShort(currentBootstrapMethodOffset + 2) * 2;
|
||||
}
|
||||
}
|
||||
currentAttributeOffset += attributeLength;
|
||||
}
|
||||
this.bootstrapMethodOffsets = currentBootstrapMethodOffsets;
|
||||
this.bootstrapMethodOffsets =
|
||||
hasBootstrapMethods ? readBootstrapMethodsAttribute(currentMaxStringLength) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -345,7 +328,7 @@ public class ClassReader {
|
|||
* Returns the internal of 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 <tt>null</tt> for {@link Object} class.
|
||||
* @return the internal name of the super class, or {@literal null} for {@link Object} class.
|
||||
* @see ClassVisitor#visit(int, int, String, String, String, String[])
|
||||
*/
|
||||
public String getSuperName() {
|
||||
|
|
@ -538,7 +521,7 @@ public class ClassReader {
|
|||
|
||||
// Visit the NestHost attribute.
|
||||
if (nestHostClass != null) {
|
||||
classVisitor.visitNestHostExperimental(nestHostClass);
|
||||
classVisitor.visitNestHost(nestHostClass);
|
||||
}
|
||||
|
||||
// Visit the EnclosingMethod attribute.
|
||||
|
|
@ -648,7 +631,7 @@ public class ClassReader {
|
|||
int numberOfNestMembers = readUnsignedShort(nestMembersOffset);
|
||||
int currentNestMemberOffset = nestMembersOffset + 2;
|
||||
while (numberOfNestMembers-- > 0) {
|
||||
classVisitor.visitNestMemberExperimental(readClass(currentNestMemberOffset, charBuffer));
|
||||
classVisitor.visitNestMember(readClass(currentNestMemberOffset, charBuffer));
|
||||
currentNestMemberOffset += 2;
|
||||
}
|
||||
}
|
||||
|
|
@ -2775,7 +2758,7 @@ public class ClassReader {
|
|||
* @param annotationVisitor the visitor that must visit the element_value structure.
|
||||
* @param elementValueOffset the start offset in {@link #b} of the element_value structure to be
|
||||
* read.
|
||||
* @param elementName the name of the element_value structure to be read, or <tt>null</tt>.
|
||||
* @param elementName the name of the element_value structure to be read, or {@literal null}.
|
||||
* @param charBuffer the buffer used to read strings in the constant pool.
|
||||
* @return the end offset of the JVMS 'element_value' structure.
|
||||
*/
|
||||
|
|
@ -3222,6 +3205,41 @@ public class ClassReader {
|
|||
return currentOffset + 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the BootstrapMethods attribute to compute the offset of each bootstrap method.
|
||||
*
|
||||
* @param maxStringLength a conservative estimate of the maximum length of the strings contained
|
||||
* in the constant pool of the class.
|
||||
* @return the offsets of the bootstrap methods or null.
|
||||
*/
|
||||
private int[] readBootstrapMethodsAttribute(final int maxStringLength) {
|
||||
char[] charBuffer = new char[maxStringLength];
|
||||
int currentAttributeOffset = getFirstAttributeOffset();
|
||||
int[] currentBootstrapMethodOffsets = null;
|
||||
for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
|
||||
// Read the attribute_info's attribute_name and attribute_length fields.
|
||||
String attributeName = readUTF8(currentAttributeOffset, charBuffer);
|
||||
int attributeLength = readInt(currentAttributeOffset + 2);
|
||||
currentAttributeOffset += 6;
|
||||
if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) {
|
||||
// Read the num_bootstrap_methods field and create an array of this size.
|
||||
currentBootstrapMethodOffsets = new int[readUnsignedShort(currentAttributeOffset)];
|
||||
// Compute and store the offset of each 'bootstrap_methods' array field entry.
|
||||
int currentBootstrapMethodOffset = currentAttributeOffset + 2;
|
||||
for (int j = 0; j < currentBootstrapMethodOffsets.length; ++j) {
|
||||
currentBootstrapMethodOffsets[j] = currentBootstrapMethodOffset;
|
||||
// Skip the bootstrap_method_ref and num_bootstrap_arguments fields (2 bytes each),
|
||||
// as well as the bootstrap_arguments array field (of size num_bootstrap_arguments * 2).
|
||||
currentBootstrapMethodOffset +=
|
||||
4 + readUnsignedShort(currentBootstrapMethodOffset + 2) * 2;
|
||||
}
|
||||
return currentBootstrapMethodOffsets;
|
||||
}
|
||||
currentAttributeOffset += attributeLength;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a non standard JVMS 'attribute' structure in {@link #b}.
|
||||
*
|
||||
|
|
@ -3236,8 +3254,8 @@ public class ClassReader {
|
|||
* @param codeAttributeOffset the start offset of the enclosing Code attribute in {@link #b}, or
|
||||
* -1 if the attribute to be read is not a code attribute. The 6 attribute header bytes
|
||||
* (attribute_name_index and attribute_length) are not taken into account here.
|
||||
* @param labels the labels of the method's code, or <tt>null</tt> if the attribute to be read is
|
||||
* not a code attribute.
|
||||
* @param labels the labels of the method's code, or {@literal null} if the attribute to be read
|
||||
* is not a code attribute.
|
||||
* @return the attribute that has been read.
|
||||
*/
|
||||
private Attribute readAttribute(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
// 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 org.springframework.asm;
|
||||
|
||||
/**
|
||||
* Exception thrown when the constant pool of a class produced by a {@link ClassWriter} is too
|
||||
* large.
|
||||
*
|
||||
* @author Jason Zaugg
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public final class ClassTooLargeException extends IndexOutOfBoundsException {
|
||||
|
||||
private final String className;
|
||||
private final int constantPoolCount;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link ClassTooLargeException}.
|
||||
*
|
||||
* @param className the internal name of the class.
|
||||
* @param constantPoolCount the number of constant pool items of the class.
|
||||
*/
|
||||
public ClassTooLargeException(final String className, final int constantPoolCount) {
|
||||
super("Class too large: " + className);
|
||||
this.className = className;
|
||||
this.constantPoolCount = constantPoolCount;
|
||||
}
|
||||
|
||||
/** @return the internal name of the class. */
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
/** @return the number of constant pool items of the class. */
|
||||
public int getConstantPoolCount() {
|
||||
return constantPoolCount;
|
||||
}
|
||||
}
|
||||
|
|
@ -29,10 +29,10 @@ package org.springframework.asm;
|
|||
|
||||
/**
|
||||
* A visitor to visit a Java class. The methods of this class must be called in the following order:
|
||||
* <tt>visit</tt> [ <tt>visitSource</tt> ] [ <tt>visitModule</tt> ][ <tt>visitNestHost</tt> ][
|
||||
* <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> | <tt>visitTypeAnnotation</tt> |
|
||||
* <tt>visitAttribute</tt> )* ( <tt>visitNestMember</tt> | <tt>visitInnerClass</tt> |
|
||||
* <tt>visitField</tt> | <tt>visitMethod</tt> )* <tt>visitEnd</tt>.
|
||||
* {@code visit} [ {@code visitSource} ] [ {@code visitModule} ][ {@code visitNestHost} ][ {@code
|
||||
* visitOuterClass} ] ( {@code visitAnnotation} | {@code visitTypeAnnotation} | {@code
|
||||
* visitAttribute} )* ( {@code visitNestMember} | {@code visitInnerClass} | {@code visitField} |
|
||||
* {@code visitMethod} )* {@code visitEnd}.
|
||||
*
|
||||
* @author Eric Bruneton
|
||||
*/
|
||||
|
|
@ -40,7 +40,7 @@ public abstract class ClassVisitor {
|
|||
|
||||
/**
|
||||
* The ASM API version implemented by this visitor. The value of this field must be one of {@link
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
|
||||
*/
|
||||
protected final int api;
|
||||
|
||||
|
|
@ -51,8 +51,7 @@ public abstract class ClassVisitor {
|
|||
* Constructs a new {@link ClassVisitor}.
|
||||
*
|
||||
* @param api the ASM API version implemented by this visitor. Must be one of {@link
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link
|
||||
* Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
|
||||
*/
|
||||
public ClassVisitor(final int api) {
|
||||
this(api, null);
|
||||
|
|
@ -62,16 +61,12 @@ public abstract class ClassVisitor {
|
|||
* Constructs a new {@link ClassVisitor}.
|
||||
*
|
||||
* @param api the ASM API version implemented by this visitor. Must be one of {@link
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link
|
||||
* Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
|
||||
* @param classVisitor the class visitor to which this visitor must delegate method calls. May be
|
||||
* null.
|
||||
*/
|
||||
public ClassVisitor(final int api, final ClassVisitor classVisitor) {
|
||||
if (api != Opcodes.ASM6
|
||||
&& api != Opcodes.ASM5
|
||||
&& api != Opcodes.ASM4
|
||||
&& api != Opcodes.ASM7_EXPERIMENTAL) {
|
||||
if (api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 && api != Opcodes.ASM7) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.api = api;
|
||||
|
|
@ -86,13 +81,13 @@ public abstract class ClassVisitor {
|
|||
* @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 Type#getInternalName()}).
|
||||
* @param signature the signature of this class. May be <tt>null</tt> if the class is not a
|
||||
* @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 Type#getInternalName()}).
|
||||
* For interfaces, the super class is {@link Object}. May be <tt>null</tt>, but only for the
|
||||
* 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
|
||||
* Type#getInternalName()}). May be <tt>null</tt>.
|
||||
* Type#getInternalName()}). May be {@literal null}.
|
||||
*/
|
||||
public void visit(
|
||||
final int version,
|
||||
|
|
@ -109,10 +104,10 @@ public abstract class ClassVisitor {
|
|||
/**
|
||||
* Visits the source of the class.
|
||||
*
|
||||
* @param source the name of the source file from which the class was compiled. May be
|
||||
* <tt>null</tt>.
|
||||
* @param source the name of the source file from which the class was compiled. May be {@literal
|
||||
* null}.
|
||||
* @param debug additional debug information to compute the correspondence between source and
|
||||
* compiled elements of the class. May be <tt>null</tt>.
|
||||
* compiled elements of the class. May be {@literal null}.
|
||||
*/
|
||||
public void visitSource(final String source, final String debug) {
|
||||
if (cv != null) {
|
||||
|
|
@ -126,13 +121,13 @@ public abstract class ClassVisitor {
|
|||
* @param name the fully qualified name (using dots) of the module.
|
||||
* @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code
|
||||
* ACC_MANDATED}.
|
||||
* @param version the module version, or <tt>null</tt>.
|
||||
* @return a visitor to visit the module values, or <tt>null</tt> if this visitor is not
|
||||
* @param version the module version, or {@literal null}.
|
||||
* @return a visitor to visit the module values, or {@literal null} if this visitor is not
|
||||
* interested in visiting this module.
|
||||
*/
|
||||
public ModuleVisitor visitModule(final String name, final int access, final String version) {
|
||||
if (api < Opcodes.ASM6) {
|
||||
throw new UnsupportedOperationException();
|
||||
throw new UnsupportedOperationException("This feature requires ASM6");
|
||||
}
|
||||
if (cv != null) {
|
||||
return cv.visitModule(name, access, version);
|
||||
|
|
@ -141,22 +136,21 @@ public abstract class ClassVisitor {
|
|||
}
|
||||
|
||||
/**
|
||||
* <b>Experimental, use at your own risk. This method will be renamed when it becomes stable, this
|
||||
* will break existing code using it</b>. Visits the nest host class of the class. A nest is a set
|
||||
* of classes of the same package that share access to their private members. One of these
|
||||
* classes, called the host, lists the other members of the nest, which in turn should link to the
|
||||
* host of their nest. This method must be called only once and only if the visited class is a
|
||||
* non-host member of a nest. A class is implicitly its own nest, so it's invalid to call this
|
||||
* method with the visited class name as argument.
|
||||
* Visits the nest host class of the class. A nest is a set of classes of the same package that
|
||||
* share access to their private members. One of these classes, called the host, lists the other
|
||||
* members of the nest, which in turn should link to the host of their nest. This method must be
|
||||
* called only once and only if the visited class is a non-host member of a nest. A class is
|
||||
* 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.
|
||||
*/
|
||||
public void visitNestHostExperimental(final String nestHost) {
|
||||
if (api < Opcodes.ASM7_EXPERIMENTAL) {
|
||||
throw new UnsupportedOperationException();
|
||||
public void visitNestHost(final String nestHost) {
|
||||
if (api < Opcodes.ASM7) {
|
||||
throw new UnsupportedOperationException("This feature requires ASM7");
|
||||
}
|
||||
if (cv != null) {
|
||||
cv.visitNestHostExperimental(nestHost);
|
||||
cv.visitNestHost(nestHost);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -165,10 +159,10 @@ public abstract class ClassVisitor {
|
|||
* enclosing class.
|
||||
*
|
||||
* @param owner internal name of the enclosing class of the class.
|
||||
* @param name the name of the method that contains the class, or <tt>null</tt> if the class is
|
||||
* @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 <tt>null</tt> 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
|
||||
* the class is not enclosed in a method of its enclosing class.
|
||||
*/
|
||||
public void visitOuterClass(final String owner, final String name, final String descriptor) {
|
||||
if (cv != null) {
|
||||
|
|
@ -180,8 +174,8 @@ public abstract class ClassVisitor {
|
|||
* Visits an annotation of the class.
|
||||
*
|
||||
* @param descriptor the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
|
||||
* @param visible {@literal true} if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
|
||||
* interested in visiting this annotation.
|
||||
*/
|
||||
public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
|
||||
|
|
@ -199,17 +193,17 @@ public abstract class ClassVisitor {
|
|||
* 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 <tt>null</tt> if the annotation targets
|
||||
* static inner type within 'typeRef'. May be {@literal null} if the annotation targets
|
||||
* 'typeRef' as a whole.
|
||||
* @param descriptor the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
|
||||
* @param visible {@literal true} if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
|
||||
* interested in visiting this annotation.
|
||||
*/
|
||||
public AnnotationVisitor visitTypeAnnotation(
|
||||
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
|
||||
if (api < Opcodes.ASM5) {
|
||||
throw new UnsupportedOperationException();
|
||||
throw new UnsupportedOperationException("This feature requires ASM5");
|
||||
}
|
||||
if (cv != null) {
|
||||
return cv.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
|
||||
|
|
@ -229,22 +223,20 @@ public abstract class ClassVisitor {
|
|||
}
|
||||
|
||||
/**
|
||||
* <b>Experimental, use at your own risk. This method will be renamed when it becomes stable, this
|
||||
* will break existing code using it</b>. Visits a member of the nest. A nest is a set of classes
|
||||
* of the same package that share access to their private members. One of these classes, called
|
||||
* the host, lists the other members of the nest, which in turn should link to the host of their
|
||||
* nest. This method must be called only if 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.
|
||||
* Visits a member of the nest. A nest is a set of classes of the same package that share access
|
||||
* to their private members. One of these classes, called the host, lists the other members of the
|
||||
* nest, which in turn should link to the host of their nest. This method must be called only if
|
||||
* 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.
|
||||
*/
|
||||
public void visitNestMemberExperimental(final String nestMember) {
|
||||
if (api < Opcodes.ASM7_EXPERIMENTAL) {
|
||||
throw new UnsupportedOperationException();
|
||||
public void visitNestMember(final String nestMember) {
|
||||
if (api < Opcodes.ASM7) {
|
||||
throw new UnsupportedOperationException("This feature requires ASM7");
|
||||
}
|
||||
if (cv != null) {
|
||||
cv.visitNestMemberExperimental(nestMember);
|
||||
cv.visitNestMember(nestMember);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -254,9 +246,9 @@ public abstract class ClassVisitor {
|
|||
*
|
||||
* @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 <tt>null</tt> 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
|
||||
* <tt>null</tt> for anonymous inner classes.
|
||||
* {@literal null} for anonymous inner classes.
|
||||
* @param access the access flags of the inner class as originally declared in the enclosing
|
||||
* class.
|
||||
*/
|
||||
|
|
@ -274,15 +266,15 @@ public abstract class ClassVisitor {
|
|||
* the field is synthetic and/or deprecated.
|
||||
* @param name the field's name.
|
||||
* @param descriptor the field's descriptor (see {@link Type}).
|
||||
* @param signature the field's signature. May be <tt>null</tt> if the field's type does not use
|
||||
* @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 <tt>null</tt> if the field
|
||||
* does not have an initial value, must be an {@link Integer}, a {@link Float}, a {@link
|
||||
* Long}, a {@link Double} or a {@link String} (for <tt>int</tt>, <tt>float</tt>,
|
||||
* <tt>long</tt> or <tt>String</tt> fields respectively). <i>This parameter is only used for
|
||||
* static fields</i>. Its value is ignored for non static fields, which must be initialized
|
||||
* through bytecode instructions in constructors or methods.
|
||||
* @return a visitor to visit field annotations and attributes, or <tt>null</tt> if this class
|
||||
* @param value the field's initial value. This parameter, which may be {@literal null} if the
|
||||
* field does not have an initial value, must be an {@link Integer}, a {@link Float}, a {@link
|
||||
* Long}, a {@link Double} or a {@link String} (for {@code int}, {@code float}, {@code long}
|
||||
* or {@code String} fields respectively). <i>This parameter is only used for static
|
||||
* fields</i>. Its value is ignored for non static fields, which must be initialized through
|
||||
* bytecode instructions in constructors or methods.
|
||||
* @return a visitor to visit field annotations and attributes, or {@literal null} if this class
|
||||
* visitor is not interested in visiting these annotations and attributes.
|
||||
*/
|
||||
public FieldVisitor visitField(
|
||||
|
|
@ -299,19 +291,19 @@ public abstract class ClassVisitor {
|
|||
|
||||
/**
|
||||
* Visits a method of the class. This method <i>must</i> return a new {@link MethodVisitor}
|
||||
* instance (or <tt>null</tt>) each time it is called, i.e., it should not return a previously
|
||||
* instance (or {@literal null}) each time it is called, i.e., it should not return a previously
|
||||
* returned visitor.
|
||||
*
|
||||
* @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 Type}).
|
||||
* @param signature the method's signature. May be <tt>null</tt> if the method parameters, return
|
||||
* type and exceptions do not use generic types.
|
||||
* @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
|
||||
* Type#getInternalName()}). May be <tt>null</tt>.
|
||||
* @return an object to visit the byte code of the method, or <tt>null</tt> if this class visitor
|
||||
* is not interested in visiting the code of this method.
|
||||
* Type#getInternalName()}). May be {@literal null}.
|
||||
* @return an object to visit the byte code of the method, or {@literal null} if this class
|
||||
* visitor is not interested in visiting the code of this method.
|
||||
*/
|
||||
public MethodVisitor visitMethod(
|
||||
final int access,
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ public class ClassWriter extends ClassVisitor {
|
|||
/** The number_of_classes field of the InnerClasses attribute, or 0. */
|
||||
private int numberOfInnerClasses;
|
||||
|
||||
/** The 'classes' array of the InnerClasses attribute, or <tt>null</tt>. */
|
||||
/** The 'classes' array of the InnerClasses attribute, or {@literal null}. */
|
||||
private ByteVector innerClasses;
|
||||
|
||||
/** The class_index field of the EnclosingMethod attribute, or 0. */
|
||||
|
|
@ -138,34 +138,34 @@ public class ClassWriter extends ClassVisitor {
|
|||
/** The source_file_index field of the SourceFile attribute, or 0. */
|
||||
private int sourceFileIndex;
|
||||
|
||||
/** The debug_extension field of the SourceDebugExtension attribute, or <tt>null</tt>. */
|
||||
/** The debug_extension field of the SourceDebugExtension attribute, or {@literal null}. */
|
||||
private ByteVector debugExtension;
|
||||
|
||||
/**
|
||||
* The last runtime visible annotation of this class. The previous ones can be accessed with the
|
||||
* {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastRuntimeVisibleAnnotation;
|
||||
|
||||
/**
|
||||
* The last runtime invisible annotation of this class. The previous ones can be accessed with the
|
||||
* {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastRuntimeInvisibleAnnotation;
|
||||
|
||||
/**
|
||||
* The last runtime visible type annotation of this class. The previous ones can be accessed with
|
||||
* the {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastRuntimeVisibleTypeAnnotation;
|
||||
|
||||
/**
|
||||
* The last runtime invisible type annotation of this class. The previous ones can be accessed
|
||||
* with the {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastRuntimeInvisibleTypeAnnotation;
|
||||
|
||||
/** The Module attribute of this class, or <tt>null</tt>. */
|
||||
/** The Module attribute of this class, or {@literal null}. */
|
||||
private ModuleWriter moduleWriter;
|
||||
|
||||
/** The host_class_index field of the NestHost attribute, or 0. */
|
||||
|
|
@ -174,12 +174,12 @@ public class ClassWriter extends ClassVisitor {
|
|||
/** The number_of_classes field of the NestMembers attribute, or 0. */
|
||||
private int numberOfNestMemberClasses;
|
||||
|
||||
/** The 'classes' array of the NestMembers attribute, or <tt>null</tt>. */
|
||||
/** The 'classes' array of the NestMembers attribute, or {@literal null}. */
|
||||
private ByteVector nestMemberClasses;
|
||||
|
||||
/**
|
||||
* The first non standard attribute of this class. The next ones can be accessed with the {@link
|
||||
* Attribute#nextAttribute} field. May be <tt>null</tt>.
|
||||
* Attribute#nextAttribute} field. May be {@literal null}.
|
||||
*
|
||||
* <p><b>WARNING</b>: this list stores the attributes in the <i>reverse</i> order of their visit.
|
||||
* firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link
|
||||
|
|
@ -234,7 +234,7 @@ public class ClassWriter extends ClassVisitor {
|
|||
* maximum stack size nor the stack frames will be computed for these methods</i>.
|
||||
*/
|
||||
public ClassWriter(final ClassReader classReader, final int flags) {
|
||||
super(Opcodes.ASM6);
|
||||
super(Opcodes.ASM7);
|
||||
symbolTable = classReader == null ? new SymbolTable(this) : new SymbolTable(this, classReader);
|
||||
if ((flags & COMPUTE_FRAMES) != 0) {
|
||||
this.compute = MethodWriter.COMPUTE_ALL_FRAMES;
|
||||
|
|
@ -298,7 +298,7 @@ public class ClassWriter extends ClassVisitor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void visitNestHostExperimental(final String nestHost) {
|
||||
public void visitNestHost(final String nestHost) {
|
||||
nestHostClassIndex = symbolTable.addConstantClass(nestHost).index;
|
||||
}
|
||||
|
||||
|
|
@ -355,7 +355,7 @@ public class ClassWriter extends ClassVisitor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void visitNestMemberExperimental(final String nestMember) {
|
||||
public void visitNestMember(final String nestMember) {
|
||||
if (nestMemberClasses == null) {
|
||||
nestMemberClasses = new ByteVector();
|
||||
}
|
||||
|
|
@ -436,8 +436,10 @@ public class ClassWriter extends ClassVisitor {
|
|||
* Returns the content of the class file that was built by this ClassWriter.
|
||||
*
|
||||
* @return the binary content of the JVMS ClassFile structure that was built by this ClassWriter.
|
||||
* @throws ClassTooLargeException if the constant pool of the class is too large.
|
||||
* @throws MethodTooLargeException if the Code attribute of a method is too large.
|
||||
*/
|
||||
public byte[] toByteArray() {
|
||||
public byte[] toByteArray() throws ClassTooLargeException, MethodTooLargeException {
|
||||
// First step: compute the size in bytes of the ClassFile structure.
|
||||
// The magic field uses 4 bytes, 10 mandatory fields (minor_version, major_version,
|
||||
// constant_pool_count, access_flags, this_class, super_class, interfaces_count, fields_count,
|
||||
|
|
@ -543,8 +545,9 @@ public class ClassWriter extends ClassVisitor {
|
|||
// IMPORTANT: this must be the last part of the ClassFile size computation, because the previous
|
||||
// statements can add attribute names to the constant pool, thereby changing its size!
|
||||
size += symbolTable.getConstantPoolLength();
|
||||
if (symbolTable.getConstantPoolCount() > 0xFFFF) {
|
||||
throw new IndexOutOfBoundsException("Class file too large!");
|
||||
int constantPoolCount = symbolTable.getConstantPoolCount();
|
||||
if (constantPoolCount > 0xFFFF) {
|
||||
throw new ClassTooLargeException(symbolTable.getClassName(), constantPoolCount);
|
||||
}
|
||||
|
||||
// Second step: allocate a ByteVector of the correct size (in order to avoid any array copy in
|
||||
|
|
@ -902,7 +905,7 @@ public class ClassWriter extends ClassVisitor {
|
|||
* @param owner the internal name of the method's owner class.
|
||||
* @param name the method's name.
|
||||
* @param descriptor the method's descriptor.
|
||||
* @param isInterface <tt>true</tt> if <tt>owner</tt> is an interface.
|
||||
* @param isInterface {@literal true} if {@code owner} is an interface.
|
||||
* @return the index of a new or already existing method reference item.
|
||||
*/
|
||||
public int newMethod(
|
||||
|
|
|
|||
|
|
@ -109,6 +109,16 @@ public final class ConstantDynamic {
|
|||
return bootstrapMethodArguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of this constant.
|
||||
*
|
||||
* @return the size of this constant, i.e., 2 for {@code long} and {@code double}, 1 otherwise.
|
||||
*/
|
||||
public int getSize() {
|
||||
char firstCharOfDescriptor = descriptor.charAt(0);
|
||||
return (firstCharOfDescriptor == 'J' || firstCharOfDescriptor == 'D') ? 2 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object object) {
|
||||
if (object == this) {
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ package org.springframework.asm;
|
|||
|
||||
/**
|
||||
* A visitor to visit a Java field. The methods of this class must be called in the following order:
|
||||
* ( <tt>visitAnnotation</tt> | <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )*
|
||||
* <tt>visitEnd</tt>.
|
||||
* ( {@code visitAnnotation} | {@code visitTypeAnnotation} | {@code visitAttribute} )* {@code
|
||||
* visitEnd}.
|
||||
*
|
||||
* @author Eric Bruneton
|
||||
*/
|
||||
|
|
@ -38,7 +38,7 @@ public abstract class FieldVisitor {
|
|||
|
||||
/**
|
||||
* The ASM API version implemented by this visitor. The value of this field must be one of {@link
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
|
||||
*/
|
||||
protected final int api;
|
||||
|
||||
|
|
@ -49,8 +49,7 @@ public abstract class FieldVisitor {
|
|||
* Constructs a new {@link FieldVisitor}.
|
||||
*
|
||||
* @param api the ASM API version implemented by this visitor. Must be one of {@link
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link
|
||||
* Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
|
||||
*/
|
||||
public FieldVisitor(final int api) {
|
||||
this(api, null);
|
||||
|
|
@ -60,16 +59,12 @@ public abstract class FieldVisitor {
|
|||
* Constructs a new {@link FieldVisitor}.
|
||||
*
|
||||
* @param api the ASM API version implemented by this visitor. Must be one of {@link
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link
|
||||
* Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
|
||||
* @param fieldVisitor the field visitor to which this visitor must delegate method calls. May be
|
||||
* null.
|
||||
*/
|
||||
public FieldVisitor(final int api, final FieldVisitor fieldVisitor) {
|
||||
if (api != Opcodes.ASM6
|
||||
&& api != Opcodes.ASM5
|
||||
&& api != Opcodes.ASM4
|
||||
&& api != Opcodes.ASM7_EXPERIMENTAL) {
|
||||
if (api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 && api != Opcodes.ASM7) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.api = api;
|
||||
|
|
@ -80,8 +75,8 @@ public abstract class FieldVisitor {
|
|||
* Visits an annotation of the field.
|
||||
*
|
||||
* @param descriptor the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
|
||||
* @param visible {@literal true} if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
|
||||
* interested in visiting this annotation.
|
||||
*/
|
||||
public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
|
||||
|
|
@ -97,17 +92,17 @@ public abstract class FieldVisitor {
|
|||
* @param typeRef a reference to the annotated type. The sort of this type reference must be
|
||||
* {@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 <tt>null</tt> if the annotation targets
|
||||
* static inner type within 'typeRef'. May be {@literal null} if the annotation targets
|
||||
* 'typeRef' as a whole.
|
||||
* @param descriptor the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
|
||||
* @param visible {@literal true} if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
|
||||
* interested in visiting this annotation.
|
||||
*/
|
||||
public AnnotationVisitor visitTypeAnnotation(
|
||||
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
|
||||
if (api < Opcodes.ASM5) {
|
||||
throw new UnsupportedOperationException();
|
||||
throw new UnsupportedOperationException("This feature requires ASM5");
|
||||
}
|
||||
if (fv != null) {
|
||||
return fv.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
|
||||
|
|
|
|||
|
|
@ -70,31 +70,31 @@ final class FieldWriter extends FieldVisitor {
|
|||
|
||||
/**
|
||||
* The last runtime visible annotation of this field. The previous ones can be accessed with the
|
||||
* {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastRuntimeVisibleAnnotation;
|
||||
|
||||
/**
|
||||
* The last runtime invisible annotation of this field. The previous ones can be accessed with the
|
||||
* {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastRuntimeInvisibleAnnotation;
|
||||
|
||||
/**
|
||||
* The last runtime visible type annotation of this field. The previous ones can be accessed with
|
||||
* the {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastRuntimeVisibleTypeAnnotation;
|
||||
|
||||
/**
|
||||
* The last runtime invisible type annotation of this field. The previous ones can be accessed
|
||||
* with the {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastRuntimeInvisibleTypeAnnotation;
|
||||
|
||||
/**
|
||||
* The first non standard attribute of this field. The next ones can be accessed with the {@link
|
||||
* Attribute#nextAttribute} field. May be <tt>null</tt>.
|
||||
* Attribute#nextAttribute} field. May be {@literal null}.
|
||||
*
|
||||
* <p><b>WARNING</b>: this list stores the attributes in the <i>reverse</i> order of their visit.
|
||||
* firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link
|
||||
|
|
@ -114,8 +114,8 @@ final class FieldWriter extends FieldVisitor {
|
|||
* @param access the field's access flags (see {@link Opcodes}).
|
||||
* @param name the field's name.
|
||||
* @param descriptor the field's descriptor (see {@link Type}).
|
||||
* @param signature the field's signature. May be <tt>null</tt>.
|
||||
* @param constantValue the field's constant value. May be <tt>null</tt>.
|
||||
* @param signature the field's signature. May be {@literal null}.
|
||||
* @param constantValue the field's constant value. May be {@literal null}.
|
||||
*/
|
||||
FieldWriter(
|
||||
final SymbolTable symbolTable,
|
||||
|
|
@ -124,7 +124,7 @@ final class FieldWriter extends FieldVisitor {
|
|||
final String descriptor,
|
||||
final String signature,
|
||||
final Object constantValue) {
|
||||
super(Opcodes.ASM6);
|
||||
super(Opcodes.ASM7);
|
||||
this.symbolTable = symbolTable;
|
||||
this.accessFlags = access;
|
||||
this.nameIndex = symbolTable.addConstantUtf8(name);
|
||||
|
|
|
|||
|
|
@ -1105,15 +1105,15 @@ class Frame {
|
|||
|
||||
/**
|
||||
* Merges the input frame of the given {@link Frame} with the input and output frames of this
|
||||
* {@link Frame}. Returns <tt>true</tt> if the given frame has been changed by this operation (the
|
||||
* input and output frames of this {@link Frame} are never changed).
|
||||
* {@link Frame}. Returns {@literal true} if the given frame has been changed by this operation
|
||||
* (the input and output frames of this {@link Frame} are never changed).
|
||||
*
|
||||
* @param symbolTable the type table to use to lookup and store type {@link Symbol}.
|
||||
* @param dstFrame the {@link Frame} whose input frame must be updated. This should be the frame
|
||||
* of a successor, in the control flow graph, of the basic block corresponding to this frame.
|
||||
* @param catchTypeIndex if 'frame' corresponds to an exception handler basic block, the type
|
||||
* table index of the caught exception type, otherwise 0.
|
||||
* @return <tt>true</tt> if the input frame of 'frame' has been changed by this operation.
|
||||
* @return {@literal true} if the input frame of 'frame' has been changed by this operation.
|
||||
*/
|
||||
final boolean merge(
|
||||
final SymbolTable symbolTable, final Frame dstFrame, final int catchTypeIndex) {
|
||||
|
|
@ -1242,7 +1242,7 @@ class Frame {
|
|||
|
||||
/**
|
||||
* Merges the type at the given index in the given abstract type array with the given type.
|
||||
* Returns <tt>true</tt> if the type array has been modified by this operation.
|
||||
* Returns {@literal true} if the type array has been modified by this operation.
|
||||
*
|
||||
* @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.
|
||||
|
|
@ -1252,7 +1252,7 @@ class Frame {
|
|||
* {@link #REFERENCE_KIND} or {@link #UNINITIALIZED_KIND} kind, with positive or null array
|
||||
* dimensions.
|
||||
* @param dstIndex the index of the type that must be merged in dstTypes.
|
||||
* @return <tt>true</tt> if the type array has been modified by this operation.
|
||||
* @return {@literal true} if the type array has been modified by this operation.
|
||||
*/
|
||||
private static boolean merge(
|
||||
final SymbolTable symbolTable,
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ final class Handler {
|
|||
final int catchType;
|
||||
|
||||
/**
|
||||
* The internal name of the type of exceptions handled by this handler, or <tt>null</tt> to catch
|
||||
* any exceptions.
|
||||
* The internal name of the type of exceptions handled by this handler, or {@literal null} to
|
||||
* catch any exceptions.
|
||||
*/
|
||||
final String catchTypeDescriptor;
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ final class Handler {
|
|||
* @param handlerPc the handler_pc field of this JVMS exception_table entry.
|
||||
* @param catchType The catch_type field of this JVMS exception_table entry.
|
||||
* @param catchTypeDescriptor The internal name of the type of exceptions handled by this handler,
|
||||
* or <tt>null</tt> to catch any exceptions.
|
||||
* or {@literal null} to catch any exceptions.
|
||||
*/
|
||||
Handler(
|
||||
final Label startPc,
|
||||
|
|
@ -111,9 +111,9 @@ final class Handler {
|
|||
* Removes the range between start and end from the Handler list that begins with the given
|
||||
* element.
|
||||
*
|
||||
* @param firstHandler the beginning of a Handler list. May be <tt>null</tt>.
|
||||
* @param firstHandler the beginning of a Handler list. May be {@literal null}.
|
||||
* @param start the start of the range to be removed.
|
||||
* @param end the end of the range to be removed. Maybe <tt>null</tt>.
|
||||
* @param end the end of the range to be removed. Maybe {@literal null}.
|
||||
* @return the exception handler list with the start-end range removed.
|
||||
*/
|
||||
static Handler removeRange(final Handler firstHandler, final Label start, final Label end) {
|
||||
|
|
@ -152,7 +152,7 @@ final class Handler {
|
|||
/**
|
||||
* Returns the number of elements of the Handler list that begins with the given element.
|
||||
*
|
||||
* @param firstHandler the beginning of a Handler list. May be <tt>null</tt>.
|
||||
* @param firstHandler the beginning of a Handler list. May be {@literal null}.
|
||||
* @return the number of elements of the Handler list that begins with 'handler'.
|
||||
*/
|
||||
static int getExceptionTableLength(final Handler firstHandler) {
|
||||
|
|
@ -169,7 +169,7 @@ final class Handler {
|
|||
* Returns the size in bytes of the JVMS exception_table corresponding to the Handler list that
|
||||
* begins with the given element. <i>This includes the exception_table_length field.</i>
|
||||
*
|
||||
* @param firstHandler the beginning of a Handler list. May be <tt>null</tt>.
|
||||
* @param firstHandler the beginning of a Handler list. May be {@literal null}.
|
||||
* @return the size in bytes of the exception_table_length and exception_table structures.
|
||||
*/
|
||||
static int getExceptionTableSize(final Handler firstHandler) {
|
||||
|
|
@ -180,7 +180,7 @@ final class Handler {
|
|||
* Puts the JVMS exception_table corresponding to the Handler list that begins with the given
|
||||
* element. <i>This includes the exception_table_length field.</i>
|
||||
*
|
||||
* @param firstHandler the beginning of a Handler list. May be <tt>null</tt>.
|
||||
* @param firstHandler the beginning of a Handler list. May be {@literal null}.
|
||||
* @param output where the exception_table_length and exception_table structures must be put.
|
||||
*/
|
||||
static void putExceptionTable(final Handler firstHandler, final ByteVector output) {
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@ public class Label {
|
|||
*
|
||||
* @param code the bytecode of the method.
|
||||
* @param bytecodeOffset the bytecode offset of this label.
|
||||
* @return <tt>true</tt> if a blank that was left for this label was too small to store the
|
||||
* @return {@literal true} if a blank that was left for this label was too small to store the
|
||||
* offset. In such a case the corresponding jump instruction is replaced with an equivalent
|
||||
* ASM specific instruction using an unsigned two bytes offset. These ASM specific
|
||||
* instructions are later replaced with standard bytecode instructions with wider offsets (4
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
// 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 org.springframework.asm;
|
||||
|
||||
/**
|
||||
* Exception thrown when the Code attribute of a method produced by a {@link ClassWriter} is too
|
||||
* large.
|
||||
*
|
||||
* @author Jason Zaugg
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public final class MethodTooLargeException extends IndexOutOfBoundsException {
|
||||
|
||||
private final String className;
|
||||
private final String methodName;
|
||||
private final String descriptor;
|
||||
private final int codeSize;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link MethodTooLargeException}.
|
||||
*
|
||||
* @param className the internal name of the owner class.
|
||||
* @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.
|
||||
*/
|
||||
public MethodTooLargeException(
|
||||
final String className,
|
||||
final String methodName,
|
||||
final String descriptor,
|
||||
final int codeSize) {
|
||||
super("Method too large: " + className + "." + methodName + " " + descriptor);
|
||||
this.className = className;
|
||||
this.methodName = methodName;
|
||||
this.descriptor = descriptor;
|
||||
this.codeSize = codeSize;
|
||||
}
|
||||
|
||||
/** @return the internal name of the owner class. */
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
/** @return the name of the method. */
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
/** @return the descriptor of the method. */
|
||||
public String getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
/** @return the size of the method's Code attribute, in bytes. */
|
||||
public int getCodeSize() {
|
||||
return codeSize;
|
||||
}
|
||||
}
|
||||
|
|
@ -29,20 +29,20 @@ package org.springframework.asm;
|
|||
|
||||
/**
|
||||
* A visitor to visit a Java method. The methods of this class must be called in the following
|
||||
* order: ( <tt>visitParameter</tt> )* [ <tt>visitAnnotationDefault</tt> ] (
|
||||
* <tt>visitAnnotation</tt> | <tt>visitAnnotableParameterCount</tt> |
|
||||
* <tt>visitParameterAnnotation</tt> <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* [
|
||||
* <tt>visitCode</tt> ( <tt>visitFrame</tt> | <tt>visit<i>X</i>Insn</tt> | <tt>visitLabel</tt> |
|
||||
* <tt>visitInsnAnnotation</tt> | <tt>visitTryCatchBlock</tt> | <tt>visitTryCatchAnnotation</tt> |
|
||||
* <tt>visitLocalVariable</tt> | <tt>visitLocalVariableAnnotation</tt> | <tt>visitLineNumber</tt> )*
|
||||
* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In addition, the <tt>visit<i>X</i>Insn</tt> and
|
||||
* <tt>visitLabel</tt> methods must be called in the sequential order of the bytecode instructions
|
||||
* of the visited code, <tt>visitInsnAnnotation</tt> must be called <i>after</i> the annotated
|
||||
* instruction, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the labels passed as
|
||||
* arguments have been visited, <tt>visitTryCatchBlockAnnotation</tt> must be called <i>after</i>
|
||||
* the corresponding try catch block has been visited, and the <tt>visitLocalVariable</tt>,
|
||||
* <tt>visitLocalVariableAnnotation</tt> and <tt>visitLineNumber</tt> methods must be called
|
||||
* <i>after</i> the labels passed as arguments have been visited.
|
||||
* order: ( {@code visitParameter} )* [ {@code visitAnnotationDefault} ] ( {@code visitAnnotation} |
|
||||
* {@code visitAnnotableParameterCount} | {@code visitParameterAnnotation} {@code
|
||||
* visitTypeAnnotation} | {@code visitAttribute} )* [ {@code visitCode} ( {@code visitFrame} |
|
||||
* {@code visit<i>X</i>Insn} | {@code visitLabel} | {@code visitInsnAnnotation} | {@code
|
||||
* visitTryCatchBlock} | {@code visitTryCatchAnnotation} | {@code visitLocalVariable} | {@code
|
||||
* visitLocalVariableAnnotation} | {@code visitLineNumber} )* {@code visitMaxs} ] {@code visitEnd}.
|
||||
* In addition, the {@code visit<i>X</i>Insn} and {@code visitLabel} methods must be called in the
|
||||
* sequential order of the bytecode instructions of the visited code, {@code visitInsnAnnotation}
|
||||
* must be called <i>after</i> the annotated instruction, {@code visitTryCatchBlock} must be called
|
||||
* <i>before</i> the labels passed as arguments have been visited, {@code
|
||||
* visitTryCatchBlockAnnotation} must be called <i>after</i> the corresponding try catch block has
|
||||
* been visited, and the {@code visitLocalVariable}, {@code visitLocalVariableAnnotation} and {@code
|
||||
* visitLineNumber} methods must be called <i>after</i> the labels passed as arguments have been
|
||||
* visited.
|
||||
*
|
||||
* @author Eric Bruneton
|
||||
*/
|
||||
|
|
@ -52,7 +52,7 @@ public abstract class MethodVisitor {
|
|||
|
||||
/**
|
||||
* The ASM API version implemented by this visitor. The value of this field must be one of {@link
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
|
||||
*/
|
||||
protected final int api;
|
||||
|
||||
|
|
@ -63,8 +63,7 @@ public abstract class MethodVisitor {
|
|||
* Constructs a new {@link MethodVisitor}.
|
||||
*
|
||||
* @param api the ASM API version implemented by this visitor. Must be one of {@link
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link
|
||||
* Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
|
||||
*/
|
||||
public MethodVisitor(final int api) {
|
||||
this(api, null);
|
||||
|
|
@ -74,16 +73,12 @@ public abstract class MethodVisitor {
|
|||
* Constructs a new {@link MethodVisitor}.
|
||||
*
|
||||
* @param api the ASM API version implemented by this visitor. Must be one of {@link
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link
|
||||
* Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
|
||||
* @param methodVisitor the method visitor to which this visitor must delegate method calls. May
|
||||
* be null.
|
||||
*/
|
||||
public MethodVisitor(final int api, final MethodVisitor methodVisitor) {
|
||||
if (api != Opcodes.ASM6
|
||||
&& api != Opcodes.ASM5
|
||||
&& api != Opcodes.ASM4
|
||||
&& api != Opcodes.ASM7_EXPERIMENTAL) {
|
||||
if (api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 && api != Opcodes.ASM7) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.api = api;
|
||||
|
|
@ -98,8 +93,8 @@ public abstract class MethodVisitor {
|
|||
* Visits a parameter of this method.
|
||||
*
|
||||
* @param name parameter name or null if none is provided.
|
||||
* @param access the parameter's access flags, only <tt>ACC_FINAL</tt>, <tt>ACC_SYNTHETIC</tt>
|
||||
* or/and <tt>ACC_MANDATED</tt> are allowed (see {@link Opcodes}).
|
||||
* @param access the parameter's access flags, only {@code ACC_FINAL}, {@code ACC_SYNTHETIC}
|
||||
* or/and {@code ACC_MANDATED} are allowed (see {@link Opcodes}).
|
||||
*/
|
||||
public void visitParameter(final String name, final int access) {
|
||||
if (api < Opcodes.ASM5) {
|
||||
|
|
@ -114,9 +109,9 @@ public abstract class MethodVisitor {
|
|||
* Visits the default value of this annotation interface method.
|
||||
*
|
||||
* @return a visitor to the visit the actual default value of this annotation interface method, or
|
||||
* <tt>null</tt> 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.
|
||||
* {@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.
|
||||
*/
|
||||
public AnnotationVisitor visitAnnotationDefault() {
|
||||
if (mv != null) {
|
||||
|
|
@ -129,8 +124,8 @@ public abstract class MethodVisitor {
|
|||
* Visits an annotation of this method.
|
||||
*
|
||||
* @param descriptor the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
|
||||
* @param visible {@literal true} if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
|
||||
* interested in visiting this annotation.
|
||||
*/
|
||||
public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
|
||||
|
|
@ -149,11 +144,11 @@ public abstract class MethodVisitor {
|
|||
* 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 <tt>null</tt> if the annotation targets
|
||||
* static inner type within 'typeRef'. May be {@literal null} if the annotation targets
|
||||
* 'typeRef' as a whole.
|
||||
* @param descriptor the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
|
||||
* @param visible {@literal true} if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
|
||||
* interested in visiting this annotation.
|
||||
*/
|
||||
public AnnotationVisitor visitTypeAnnotation(
|
||||
|
|
@ -177,8 +172,8 @@ public abstract class MethodVisitor {
|
|||
* be strictly less when a method has synthetic parameters and when these parameters are
|
||||
* ignored when computing parameter indices for the purpose of parameter annotations (see
|
||||
* https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
|
||||
* @param visible <tt>true</tt> to define the number of method parameters that can have
|
||||
* annotations visible at runtime, <tt>false</tt> to define the number of method parameters
|
||||
* @param visible {@literal true} to define the number of method parameters that can have
|
||||
* annotations visible at runtime, {@literal false} to define the number of method parameters
|
||||
* that can have annotations invisible at runtime.
|
||||
*/
|
||||
public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
|
||||
|
|
@ -197,8 +192,8 @@ public abstract class MethodVisitor {
|
|||
* descriptor</i>, in particular in case of synthetic parameters (see
|
||||
* https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
|
||||
* @param descriptor the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
|
||||
* @param visible {@literal true} if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
|
||||
* interested in visiting this annotation.
|
||||
*/
|
||||
public AnnotationVisitor visitParameterAnnotation(
|
||||
|
|
@ -532,7 +527,7 @@ public abstract class MethodVisitor {
|
|||
*
|
||||
* @param value the constant to be loaded on the stack. This parameter must be a non null {@link
|
||||
* Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, a {@link
|
||||
* Type} of OBJECT or ARRAY sort for <tt>.class</tt> constants, for classes whose version is
|
||||
* Type} of OBJECT or ARRAY sort for {@code .class} constants, for classes whose version is
|
||||
* 49, a {@link Type} of METHOD sort for MethodType, a {@link Handle} for MethodHandle
|
||||
* constants, for classes whose version is 51 or a {@link ConstantDynamic} for a constant
|
||||
* dynamic for classes whose version is 55.
|
||||
|
|
@ -543,7 +538,7 @@ public abstract class MethodVisitor {
|
|||
|| (value instanceof Type && ((Type) value).getSort() == Type.METHOD))) {
|
||||
throw new UnsupportedOperationException(REQUIRES_ASM5);
|
||||
}
|
||||
if (api != Opcodes.ASM7_EXPERIMENTAL && value instanceof ConstantDynamic) {
|
||||
if (api != Opcodes.ASM7 && value instanceof ConstantDynamic) {
|
||||
throw new UnsupportedOperationException("This feature requires ASM7");
|
||||
}
|
||||
if (mv != null) {
|
||||
|
|
@ -569,8 +564,8 @@ public abstract class MethodVisitor {
|
|||
* @param min the minimum key value.
|
||||
* @param max the maximum key value.
|
||||
* @param dflt beginning of the default handler block.
|
||||
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the
|
||||
* handler block for the <tt>min + i</tt> key.
|
||||
* @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
|
||||
* handler block for the {@code min + i} key.
|
||||
*/
|
||||
public void visitTableSwitchInsn(
|
||||
final int min, final int max, final Label dflt, final Label... labels) {
|
||||
|
|
@ -584,8 +579,8 @@ public abstract class MethodVisitor {
|
|||
*
|
||||
* @param dflt beginning of the default handler block.
|
||||
* @param keys the values of the keys.
|
||||
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the
|
||||
* handler block for the <tt>keys[i]</tt> key.
|
||||
* @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
|
||||
* handler block for the {@code keys[i]} key.
|
||||
*/
|
||||
public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
|
||||
if (mv != null) {
|
||||
|
|
@ -617,11 +612,11 @@ public abstract class MethodVisitor {
|
|||
* 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 <tt>null</tt> if the annotation targets
|
||||
* static inner type within 'typeRef'. May be {@literal null} if the annotation targets
|
||||
* 'typeRef' as a whole.
|
||||
* @param descriptor the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
|
||||
* @param visible {@literal true} if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
|
||||
* interested in visiting this annotation.
|
||||
*/
|
||||
public AnnotationVisitor visitInsnAnnotation(
|
||||
|
|
@ -645,8 +640,8 @@ public abstract class MethodVisitor {
|
|||
* @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
|
||||
* <tt>null</tt> to catch any exceptions (for "finally" blocks).
|
||||
* @param type the internal name of the type of exceptions handled by the handler, 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).
|
||||
*/
|
||||
|
|
@ -665,11 +660,11 @@ public abstract class MethodVisitor {
|
|||
* @param typeRef a reference to the annotated type. The sort of this type reference must be
|
||||
* {@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 <tt>null</tt> if the annotation targets
|
||||
* static inner type within 'typeRef'. May be {@literal null} if the annotation targets
|
||||
* 'typeRef' as a whole.
|
||||
* @param descriptor the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
|
||||
* @param visible {@literal true} if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
|
||||
* interested in visiting this annotation.
|
||||
*/
|
||||
public AnnotationVisitor visitTryCatchAnnotation(
|
||||
|
|
@ -688,7 +683,7 @@ public abstract class MethodVisitor {
|
|||
*
|
||||
* @param name the name of a local variable.
|
||||
* @param descriptor the type descriptor of this local variable.
|
||||
* @param signature the type signature of this local variable. May be <tt>null</tt> if the local
|
||||
* @param signature the type signature of this local variable. May be {@literal null} if the local
|
||||
* variable type does not use generic types.
|
||||
* @param start the first instruction corresponding to the scope of this local variable
|
||||
* (inclusive).
|
||||
|
|
@ -716,7 +711,7 @@ public abstract class MethodVisitor {
|
|||
* {@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 <tt>null</tt> if the annotation targets
|
||||
* static inner type within 'typeRef'. May be {@literal null} if the annotation targets
|
||||
* 'typeRef' as a whole.
|
||||
* @param start the fist instructions corresponding to the continuous ranges that make the scope
|
||||
* of this local variable (inclusive).
|
||||
|
|
@ -725,8 +720,8 @@ public abstract class MethodVisitor {
|
|||
* @param index the local variable's index in each range. This array must have the same size as
|
||||
* the 'start' array.
|
||||
* @param descriptor the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
|
||||
* @param visible {@literal true} if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
|
||||
* interested in visiting this annotation.
|
||||
*/
|
||||
public AnnotationVisitor visitLocalVariableAnnotation(
|
||||
|
|
@ -753,7 +748,7 @@ public abstract class MethodVisitor {
|
|||
* @param line a line number. This number refers to the source file from which the class was
|
||||
* compiled.
|
||||
* @param start the first instruction corresponding to this line number.
|
||||
* @throws IllegalArgumentException if <tt>start</tt> has not already been visited by this visitor
|
||||
* @throws IllegalArgumentException if {@code start} has not already been visited by this visitor
|
||||
* (by the {@link #visitLabel} method).
|
||||
*/
|
||||
public void visitLineNumber(final int line, final Label start) {
|
||||
|
|
|
|||
|
|
@ -322,35 +322,37 @@ final class MethodWriter extends MethodVisitor {
|
|||
/**
|
||||
* The first element in the exception handler list (used to generate the exception_table of the
|
||||
* Code attribute). The next ones can be accessed with the {@link Handler#nextHandler} field. May
|
||||
* be <tt>null</tt>.
|
||||
* be {@literal null}.
|
||||
*/
|
||||
private Handler firstHandler;
|
||||
|
||||
/**
|
||||
* The last element in the exception handler list (used to generate the exception_table of the
|
||||
* Code attribute). The next ones can be accessed with the {@link Handler#nextHandler} field. May
|
||||
* be <tt>null</tt>.
|
||||
* be {@literal null}.
|
||||
*/
|
||||
private Handler lastHandler;
|
||||
|
||||
/** The line_number_table_length field of the LineNumberTable code attribute. */
|
||||
private int lineNumberTableLength;
|
||||
|
||||
/** The line_number_table array of the LineNumberTable code attribute, or <tt>null</tt>. */
|
||||
/** The line_number_table array of the LineNumberTable code attribute, or {@literal null}. */
|
||||
private ByteVector lineNumberTable;
|
||||
|
||||
/** The local_variable_table_length field of the LocalVariableTable code attribute. */
|
||||
private int localVariableTableLength;
|
||||
|
||||
/** The local_variable_table array of the LocalVariableTable code attribute, or <tt>null</tt>. */
|
||||
/**
|
||||
* The local_variable_table array of the LocalVariableTable code attribute, or {@literal null}.
|
||||
*/
|
||||
private ByteVector localVariableTable;
|
||||
|
||||
/** The local_variable_type_table_length field of the LocalVariableTypeTable code attribute. */
|
||||
private int localVariableTypeTableLength;
|
||||
|
||||
/**
|
||||
* The local_variable_type_table array of the LocalVariableTypeTable code attribute, or
|
||||
* <tt>null</tt>.
|
||||
* The local_variable_type_table array of the LocalVariableTypeTable code attribute, or {@literal
|
||||
* null}.
|
||||
*/
|
||||
private ByteVector localVariableTypeTable;
|
||||
|
||||
|
|
@ -362,19 +364,19 @@ final class MethodWriter extends MethodVisitor {
|
|||
|
||||
/**
|
||||
* The last runtime visible type annotation of the Code attribute. The previous ones can be
|
||||
* accessed with the {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* accessed with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastCodeRuntimeVisibleTypeAnnotation;
|
||||
|
||||
/**
|
||||
* The last runtime invisible type annotation of the Code attribute. The previous ones can be
|
||||
* accessed with the {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* accessed with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastCodeRuntimeInvisibleTypeAnnotation;
|
||||
|
||||
/**
|
||||
* The first non standard attribute of the Code attribute. The next ones can be accessed with the
|
||||
* {@link Attribute#nextAttribute} field. May be <tt>null</tt>.
|
||||
* {@link Attribute#nextAttribute} field. May be {@literal null}.
|
||||
*
|
||||
* <p><b>WARNING</b>: this list stores the attributes in the <i>reverse</i> order of their visit.
|
||||
* firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link
|
||||
|
|
@ -388,7 +390,7 @@ final class MethodWriter extends MethodVisitor {
|
|||
/** The number_of_exceptions field of the Exceptions attribute. */
|
||||
private final int numberOfExceptions;
|
||||
|
||||
/** The exception_index_table array of the Exceptions attribute, or <tt>null</tt>. */
|
||||
/** The exception_index_table array of the Exceptions attribute, or {@literal null}. */
|
||||
private final int[] exceptionIndexTable;
|
||||
|
||||
/** The signature_index field of the Signature attribute. */
|
||||
|
|
@ -396,13 +398,13 @@ final class MethodWriter extends MethodVisitor {
|
|||
|
||||
/**
|
||||
* The last runtime visible annotation of this method. The previous ones can be accessed with the
|
||||
* {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastRuntimeVisibleAnnotation;
|
||||
|
||||
/**
|
||||
* The last runtime invisible annotation of this method. The previous ones can be accessed with
|
||||
* the {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastRuntimeInvisibleAnnotation;
|
||||
|
||||
|
|
@ -411,8 +413,8 @@ final class MethodWriter extends MethodVisitor {
|
|||
|
||||
/**
|
||||
* The runtime visible parameter annotations of this method. Each array element contains the last
|
||||
* annotation of a parameter (which can be <tt>null</tt> - the previous ones can be accessed with
|
||||
* the {@link AnnotationWriter#previousAnnotation} field). May be <tt>null</tt>.
|
||||
* annotation of a parameter (which can be {@literal null} - the previous ones can be accessed
|
||||
* with the {@link AnnotationWriter#previousAnnotation} field). May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter[] lastRuntimeVisibleParameterAnnotations;
|
||||
|
||||
|
|
@ -421,35 +423,35 @@ final class MethodWriter extends MethodVisitor {
|
|||
|
||||
/**
|
||||
* The runtime invisible parameter annotations of this method. Each array element contains the
|
||||
* last annotation of a parameter (which can be <tt>null</tt> - the previous ones can be accessed
|
||||
* with the {@link AnnotationWriter#previousAnnotation} field). May be <tt>null</tt>.
|
||||
* last annotation of a parameter (which can be {@literal null} - the previous ones can be
|
||||
* accessed with the {@link AnnotationWriter#previousAnnotation} field). May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter[] lastRuntimeInvisibleParameterAnnotations;
|
||||
|
||||
/**
|
||||
* The last runtime visible type annotation of this method. The previous ones can be accessed with
|
||||
* the {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastRuntimeVisibleTypeAnnotation;
|
||||
|
||||
/**
|
||||
* The last runtime invisible type annotation of this method. The previous ones can be accessed
|
||||
* with the {@link AnnotationWriter#previousAnnotation} field. May be <tt>null</tt>.
|
||||
* with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
|
||||
*/
|
||||
private AnnotationWriter lastRuntimeInvisibleTypeAnnotation;
|
||||
|
||||
/** The default_value field of the AnnotationDefault attribute, or <tt>null</tt>. */
|
||||
/** The default_value field of the AnnotationDefault attribute, or {@literal null}. */
|
||||
private ByteVector defaultValue;
|
||||
|
||||
/** The parameters_count field of the MethodParameters attribute. */
|
||||
private int parametersCount;
|
||||
|
||||
/** The 'parameters' array of the MethodParameters attribute, or <tt>null</tt>. */
|
||||
/** The 'parameters' array of the MethodParameters attribute, or {@literal null}. */
|
||||
private ByteVector parameters;
|
||||
|
||||
/**
|
||||
* The first non standard attribute of this method. The next ones can be accessed with the {@link
|
||||
* Attribute#nextAttribute} field. May be <tt>null</tt>.
|
||||
* Attribute#nextAttribute} field. May be {@literal null}.
|
||||
*
|
||||
* <p><b>WARNING</b>: this list stores the attributes in the <i>reverse</i> order of their visit.
|
||||
* firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link
|
||||
|
|
@ -483,7 +485,7 @@ final class MethodWriter extends MethodVisitor {
|
|||
/**
|
||||
* The current basic block, i.e. the basic block of the last visited instruction. When {@link
|
||||
* #compute} is equal to {@link #COMPUTE_MAX_STACK_AND_LOCAL} or {@link #COMPUTE_ALL_FRAMES}, this
|
||||
* field is <tt>null</tt> for unreachable code. When {@link #compute} is equal to {@link
|
||||
* field is {@literal null} for unreachable code. When {@link #compute} is equal to {@link
|
||||
* #COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES} or {@link #COMPUTE_INSERTED_FRAMES}, this field stays
|
||||
* unchanged throughout the whole method (i.e. the whole code is seen as a single basic block;
|
||||
* indeed, the existing frames are sufficient by hypothesis to compute any intermediate frame -
|
||||
|
|
@ -579,8 +581,8 @@ final class MethodWriter extends MethodVisitor {
|
|||
* @param access the method's access flags (see {@link Opcodes}).
|
||||
* @param name the method's name.
|
||||
* @param descriptor the method's descriptor (see {@link Type}).
|
||||
* @param signature the method's signature. May be <tt>null</tt>.
|
||||
* @param exceptions the internal names of the method's exceptions. May be <tt>null</tt>.
|
||||
* @param signature the method's signature. May be {@literal null}.
|
||||
* @param exceptions the internal names of the method's exceptions. May be {@literal null}.
|
||||
* @param compute indicates what must be computed (see #compute).
|
||||
*/
|
||||
MethodWriter(
|
||||
|
|
@ -591,7 +593,7 @@ final class MethodWriter extends MethodVisitor {
|
|||
final String signature,
|
||||
final String[] exceptions,
|
||||
final int compute) {
|
||||
super(Opcodes.ASM6);
|
||||
super(Opcodes.ASM7);
|
||||
this.symbolTable = symbolTable;
|
||||
this.accessFlags = "<init>".equals(name) ? access | Constants.ACC_CONSTRUCTOR : access;
|
||||
this.nameIndex = symbolTable.addConstantUtf8(name);
|
||||
|
|
@ -1289,9 +1291,13 @@ final class MethodWriter extends MethodVisitor {
|
|||
// Add the instruction to the bytecode of the method.
|
||||
Symbol constantSymbol = symbolTable.addConstant(value);
|
||||
int constantIndex = constantSymbol.index;
|
||||
char firstDescriptorChar;
|
||||
boolean isLongOrDouble =
|
||||
constantSymbol.tag == Symbol.CONSTANT_LONG_TAG
|
||||
|| constantSymbol.tag == Symbol.CONSTANT_DOUBLE_TAG;
|
||||
|| constantSymbol.tag == Symbol.CONSTANT_DOUBLE_TAG
|
||||
|| (constantSymbol.tag == Symbol.CONSTANT_DYNAMIC_TAG
|
||||
&& ((firstDescriptorChar = constantSymbol.value.charAt(0)) == 'J'
|
||||
|| firstDescriptorChar == 'D'));
|
||||
if (isLongOrDouble) {
|
||||
code.put12(Constants.LDC2_W, constantIndex);
|
||||
} else if (constantIndex >= 256) {
|
||||
|
|
@ -1843,7 +1849,7 @@ final class MethodWriter extends MethodVisitor {
|
|||
/**
|
||||
* Ends the visit of {@link #currentFrame} by writing it in the StackMapTable entries and by
|
||||
* updating the StackMapTable number_of_entries (except if the current frame is the first one,
|
||||
* which is implicit in StackMapTable). Then resets {@link #currentFrame} to <tt>null</tt>.
|
||||
* which is implicit in StackMapTable). Then resets {@link #currentFrame} to {@literal null}.
|
||||
*/
|
||||
void visitFrameEnd() {
|
||||
if (previousFrame != null) {
|
||||
|
|
@ -2076,7 +2082,8 @@ final class MethodWriter extends MethodVisitor {
|
|||
// For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
|
||||
if (code.length > 0) {
|
||||
if (code.length > 65535) {
|
||||
throw new IndexOutOfBoundsException("Method code too large!");
|
||||
throw new MethodTooLargeException(
|
||||
symbolTable.getClassName(), name, descriptor, code.length);
|
||||
}
|
||||
symbolTable.addConstantUtf8(Constants.CODE);
|
||||
// The Code attribute has 6 header bytes, plus 2, 2, 4 and 2 bytes respectively for max_stack,
|
||||
|
|
|
|||
|
|
@ -29,9 +29,8 @@ package org.springframework.asm;
|
|||
|
||||
/**
|
||||
* A visitor to visit a Java module. The methods of this class must be called in the following
|
||||
* order: <tt>visitMainClass</tt> | ( <tt>visitPackage</tt> | <tt>visitRequire</tt> |
|
||||
* <tt>visitExport</tt> | <tt>visitOpen</tt> | <tt>visitUse</tt> | <tt>visitProvide</tt> )*
|
||||
* <tt>visitEnd</tt>.
|
||||
* order: ( {@code visitMainClass} | ( {@code visitPackage} | {@code visitRequire} | {@code
|
||||
* visitExport} | {@code visitOpen} | {@code visitUse} | {@code visitProvide} )* ) {@code visitEnd}.
|
||||
*
|
||||
* @author Remi Forax
|
||||
* @author Eric Bruneton
|
||||
|
|
@ -39,7 +38,7 @@ package org.springframework.asm;
|
|||
public abstract class ModuleVisitor {
|
||||
/**
|
||||
* The ASM API version implemented by this visitor. The value of this field must be one of {@link
|
||||
* Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* Opcodes#ASM6} or {@link Opcodes#ASM7}.
|
||||
*/
|
||||
protected final int api;
|
||||
|
||||
|
|
@ -50,7 +49,7 @@ public abstract class ModuleVisitor {
|
|||
* Constructs a new {@link ModuleVisitor}.
|
||||
*
|
||||
* @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6}
|
||||
* or {@link Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* or {@link Opcodes#ASM7}.
|
||||
*/
|
||||
public ModuleVisitor(final int api) {
|
||||
this(api, null);
|
||||
|
|
@ -60,12 +59,12 @@ public abstract class ModuleVisitor {
|
|||
* Constructs a new {@link ModuleVisitor}.
|
||||
*
|
||||
* @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6}
|
||||
* or {@link Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* or {@link Opcodes#ASM7}.
|
||||
* @param moduleVisitor the module visitor to which this visitor must delegate method calls. May
|
||||
* be null.
|
||||
*/
|
||||
public ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) {
|
||||
if (api != Opcodes.ASM6 && api != Opcodes.ASM7_EXPERIMENTAL) {
|
||||
if (api != Opcodes.ASM6 && api != Opcodes.ASM7) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.api = api;
|
||||
|
|
@ -100,7 +99,7 @@ public abstract class ModuleVisitor {
|
|||
* @param module the fully qualified name (using dots) of the dependence.
|
||||
* @param access the access flag of the dependence among {@code ACC_TRANSITIVE}, {@code
|
||||
* ACC_STATIC_PHASE}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
|
||||
* @param version the module version at compile time, or <tt>null</tt>.
|
||||
* @param version the module version at compile time, or {@literal null}.
|
||||
*/
|
||||
public void visitRequire(final String module, final int access, final String version) {
|
||||
if (mv != null) {
|
||||
|
|
@ -115,7 +114,7 @@ public abstract class ModuleVisitor {
|
|||
* @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
|
||||
* classes of the exported package, or <tt>null</tt>.
|
||||
* classes of the exported package, or {@literal null}.
|
||||
*/
|
||||
public void visitExport(final String packaze, final int access, final String... modules) {
|
||||
if (mv != null) {
|
||||
|
|
@ -130,7 +129,7 @@ public abstract class ModuleVisitor {
|
|||
* @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
|
||||
* reflection to the classes of the open package, or <tt>null</tt>.
|
||||
* reflection to the classes of the open package, or {@literal null}.
|
||||
*/
|
||||
public void visitOpen(final String packaze, final int access, final String... modules) {
|
||||
if (mv != null) {
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ final class ModuleWriter extends ModuleVisitor {
|
|||
private int mainClassIndex;
|
||||
|
||||
ModuleWriter(final SymbolTable symbolTable, final int name, final int access, final int version) {
|
||||
super(Opcodes.ASM6);
|
||||
super(Opcodes.ASM7);
|
||||
this.symbolTable = symbolTable;
|
||||
this.moduleNameIndex = name;
|
||||
this.moduleFlags = access;
|
||||
|
|
|
|||
|
|
@ -45,12 +45,7 @@ public interface Opcodes {
|
|||
int ASM4 = 4 << 16 | 0 << 8;
|
||||
int ASM5 = 5 << 16 | 0 << 8;
|
||||
int ASM6 = 6 << 16 | 0 << 8;
|
||||
|
||||
/**
|
||||
* <b>Experimental, use at your own risk. This field will be renamed when it becomes stable, this
|
||||
* will break existing code using it</b>.
|
||||
*/
|
||||
int ASM7_EXPERIMENTAL = 1 << 24 | 7 << 16 | 0 << 8;
|
||||
int ASM7 = 7 << 16 | 0 << 8;
|
||||
|
||||
// Java ClassFile versions (the minor version is stored in the 16 most
|
||||
// significant bits, and the
|
||||
|
|
@ -72,12 +67,10 @@ public interface Opcodes {
|
|||
/**
|
||||
* Version flag indicating that the class is using 'preview' features.
|
||||
*
|
||||
* <p>{@code version & V_PREVIEW_EXPERIMENTAL == V_PREVIEW_EXPERIMENTAL} tests if a version is
|
||||
* flagged with {@code V_PREVIEW_EXPERIMENTAL}.
|
||||
*
|
||||
* @deprecated This API is experimental.
|
||||
* <p>{@code version & V_PREVIEW == V_PREVIEW} tests if a version is flagged with {@code
|
||||
* V_PREVIEW}.
|
||||
*/
|
||||
@Deprecated int V_PREVIEW_EXPERIMENTAL = 0xFFFF0000;
|
||||
int V_PREVIEW = 0xFFFF0000;
|
||||
|
||||
// Access flags values, defined in
|
||||
// - https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.1-200-E.1
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package org.springframework.asm;
|
|||
|
||||
/**
|
||||
* Utility class exposing constants related to Spring's internal repackaging
|
||||
* of the ASM bytecode library: currently based on ASM 6.2 plus minor patches.
|
||||
* of the ASM bytecode library: currently based on ASM 7.0 plus minor patches.
|
||||
*
|
||||
* <p>See <a href="package-summary.html">package-level javadocs</a> for more
|
||||
* information on {@code org.springframework.asm}.
|
||||
|
|
@ -31,8 +31,8 @@ public final class SpringAsmInfo {
|
|||
|
||||
/**
|
||||
* The ASM compatibility version for Spring's ASM visitor implementations:
|
||||
* currently {@link Opcodes#ASM7_EXPERIMENTAL}.
|
||||
* currently {@link Opcodes#ASM7}, as of Spring Framework 5.1.
|
||||
*/
|
||||
public static final int ASM_VERSION = Opcodes.ASM7_EXPERIMENTAL;
|
||||
public static final int ASM_VERSION = Opcodes.ASM7;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ abstract class Symbol {
|
|||
* symbols,
|
||||
* <li>an internal class name for {@link #CONSTANT_CLASS_TAG}, {@link #TYPE_TAG} and {@link
|
||||
* #UNINITIALIZED_TYPE_TAG} symbols,
|
||||
* <li><tt>null</tt> for the other types of symbol.
|
||||
* <li>{@literal null} for the other types of symbol.
|
||||
* </ul>
|
||||
*/
|
||||
final String value;
|
||||
|
|
@ -205,9 +205,10 @@ abstract class Symbol {
|
|||
* @param index the symbol index in the constant pool, in the BootstrapMethods attribute, or in
|
||||
* the (ASM specific) type table of a class (depending on 'tag').
|
||||
* @param tag the symbol type. Must be one of the static tag values defined in this class.
|
||||
* @param owner The internal name of the symbol's owner class. Maybe <tt>null</tt>.
|
||||
* @param name The name of the symbol's corresponding class field or method. Maybe <tt>null</tt>.
|
||||
* @param value The string value of this symbol. Maybe <tt>null</tt>.
|
||||
* @param owner The internal name of the symbol's owner class. Maybe {@literal null}.
|
||||
* @param name The name of the symbol's corresponding class field or method. Maybe {@literal
|
||||
* null}.
|
||||
* @param value The string value of this symbol. Maybe {@literal null}.
|
||||
* @param data The numeric value of this symbol.
|
||||
*/
|
||||
Symbol(
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ final class SymbolTable {
|
|||
final ClassWriter classWriter;
|
||||
|
||||
/**
|
||||
* The ClassReader from which this SymbolTable was constructed, or <tt>null</tt> if it was
|
||||
* The ClassReader from which this SymbolTable was constructed, or {@literal null} if it was
|
||||
* constructed from scratch.
|
||||
*/
|
||||
private final ClassReader sourceClassReader;
|
||||
|
|
@ -161,7 +161,7 @@ final class SymbolTable {
|
|||
* 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
|
||||
* <tt>i</tt> has its {@link Symbol#index} equal to <tt>i</tt> (and vice versa).
|
||||
* {@code i} has its {@link Symbol#index} equal to {@code i} (and vice versa).
|
||||
*/
|
||||
private Entry[] typeTable;
|
||||
|
||||
|
|
@ -203,6 +203,7 @@ final class SymbolTable {
|
|||
// method calls below), and to account for bootstrap method entries.
|
||||
entries = new Entry[constantPoolCount * 2];
|
||||
char[] charBuffer = new char[classReader.getMaxStringLength()];
|
||||
boolean hasBootstrapMethods = false;
|
||||
int itemIndex = 1;
|
||||
while (itemIndex < constantPoolCount) {
|
||||
int itemOffset = classReader.getItem(itemIndex);
|
||||
|
|
@ -252,6 +253,7 @@ final class SymbolTable {
|
|||
break;
|
||||
case Symbol.CONSTANT_DYNAMIC_TAG:
|
||||
case Symbol.CONSTANT_INVOKE_DYNAMIC_TAG:
|
||||
hasBootstrapMethods = true;
|
||||
nameAndTypeItemOffset =
|
||||
classReader.getItem(classReader.readUnsignedShort(itemOffset + 2));
|
||||
addConstantDynamicOrInvokeDynamicReference(
|
||||
|
|
@ -276,7 +278,23 @@ final class SymbolTable {
|
|||
(itemTag == Symbol.CONSTANT_LONG_TAG || itemTag == Symbol.CONSTANT_DOUBLE_TAG) ? 2 : 1;
|
||||
}
|
||||
|
||||
// Copy the BootstrapMethods 'bootstrap_methods' array binary content, if any.
|
||||
// Copy the BootstrapMethods, if any.
|
||||
if (hasBootstrapMethods) {
|
||||
copyBootstrapMethods(classReader, charBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the BootstrapMethods 'bootstrap_methods' array binary content and add them as entries of
|
||||
* the SymbolTable.
|
||||
*
|
||||
* @param classReader the ClassReader whose bootstrap methods must be copied to initialize the
|
||||
* SymbolTable.
|
||||
* @param charBuffer a buffer used to read strings in the constant pool.
|
||||
*/
|
||||
private void copyBootstrapMethods(final ClassReader classReader, final char[] charBuffer) {
|
||||
// Find attributOffset of the 'bootstrap_methods' array.
|
||||
byte[] inputBytes = classReader.b;
|
||||
int currentAttributeOffset = classReader.getFirstAttributeOffset();
|
||||
for (int i = classReader.readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
|
||||
String attributeName = classReader.readUTF8(currentAttributeOffset, charBuffer);
|
||||
|
|
@ -313,8 +331,8 @@ final class SymbolTable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return the ClassReader from which this SymbolTable was constructed, or <tt>null</tt> if it was
|
||||
* constructed from scratch.
|
||||
* @return the ClassReader from which this SymbolTable was constructed, or {@literal null} if it
|
||||
* was constructed from scratch.
|
||||
*/
|
||||
ClassReader getSource() {
|
||||
return sourceClassReader;
|
||||
|
|
|
|||
|
|
@ -39,31 +39,31 @@ import java.lang.reflect.Method;
|
|||
*/
|
||||
public class Type {
|
||||
|
||||
/** The sort of the <tt>void</tt> type. See {@link #getSort}. */
|
||||
/** The sort of the {@code void} type. See {@link #getSort}. */
|
||||
public static final int VOID = 0;
|
||||
|
||||
/** The sort of the <tt>boolean</tt> type. See {@link #getSort}. */
|
||||
/** The sort of the {@code boolean} type. See {@link #getSort}. */
|
||||
public static final int BOOLEAN = 1;
|
||||
|
||||
/** The sort of the <tt>char</tt> type. See {@link #getSort}. */
|
||||
/** The sort of the {@code char} type. See {@link #getSort}. */
|
||||
public static final int CHAR = 2;
|
||||
|
||||
/** The sort of the <tt>byte</tt> type. See {@link #getSort}. */
|
||||
/** The sort of the {@code byte} type. See {@link #getSort}. */
|
||||
public static final int BYTE = 3;
|
||||
|
||||
/** The sort of the <tt>short</tt> type. See {@link #getSort}. */
|
||||
/** The sort of the {@code short} type. See {@link #getSort}. */
|
||||
public static final int SHORT = 4;
|
||||
|
||||
/** The sort of the <tt>int</tt> type. See {@link #getSort}. */
|
||||
/** The sort of the {@code int} type. See {@link #getSort}. */
|
||||
public static final int INT = 5;
|
||||
|
||||
/** The sort of the <tt>float</tt> type. See {@link #getSort}. */
|
||||
/** The sort of the {@code float} type. See {@link #getSort}. */
|
||||
public static final int FLOAT = 6;
|
||||
|
||||
/** The sort of the <tt>long</tt> type. See {@link #getSort}. */
|
||||
/** The sort of the {@code long} type. See {@link #getSort}. */
|
||||
public static final int LONG = 7;
|
||||
|
||||
/** The sort of the <tt>double</tt> type. See {@link #getSort}. */
|
||||
/** The sort of the {@code double} type. See {@link #getSort}. */
|
||||
public static final int DOUBLE = 8;
|
||||
|
||||
/** The sort of array reference types. See {@link #getSort}. */
|
||||
|
|
@ -81,32 +81,32 @@ public class Type {
|
|||
/** The descriptors of the primitive types. */
|
||||
private static final String PRIMITIVE_DESCRIPTORS = "VZCBSIFJD";
|
||||
|
||||
/** The <tt>void</tt> type. */
|
||||
/** The {@code void} type. */
|
||||
public static final Type VOID_TYPE = new Type(VOID, PRIMITIVE_DESCRIPTORS, VOID, VOID + 1);
|
||||
|
||||
/** The <tt>boolean</tt> type. */
|
||||
/** The {@code boolean} type. */
|
||||
public static final Type BOOLEAN_TYPE =
|
||||
new Type(BOOLEAN, PRIMITIVE_DESCRIPTORS, BOOLEAN, BOOLEAN + 1);
|
||||
|
||||
/** The <tt>char</tt> type. */
|
||||
/** The {@code char} type. */
|
||||
public static final Type CHAR_TYPE = new Type(CHAR, PRIMITIVE_DESCRIPTORS, CHAR, CHAR + 1);
|
||||
|
||||
/** The <tt>byte</tt> type. */
|
||||
/** The {@code byte} type. */
|
||||
public static final Type BYTE_TYPE = new Type(BYTE, PRIMITIVE_DESCRIPTORS, BYTE, BYTE + 1);
|
||||
|
||||
/** The <tt>short</tt> type. */
|
||||
/** The {@code short} type. */
|
||||
public static final Type SHORT_TYPE = new Type(SHORT, PRIMITIVE_DESCRIPTORS, SHORT, SHORT + 1);
|
||||
|
||||
/** The <tt>int</tt> type. */
|
||||
/** The {@code int} type. */
|
||||
public static final Type INT_TYPE = new Type(INT, PRIMITIVE_DESCRIPTORS, INT, INT + 1);
|
||||
|
||||
/** The <tt>float</tt> type. */
|
||||
/** The {@code float} type. */
|
||||
public static final Type FLOAT_TYPE = new Type(FLOAT, PRIMITIVE_DESCRIPTORS, FLOAT, FLOAT + 1);
|
||||
|
||||
/** The <tt>long</tt> type. */
|
||||
/** The {@code long} type. */
|
||||
public static final Type LONG_TYPE = new Type(LONG, PRIMITIVE_DESCRIPTORS, LONG, LONG + 1);
|
||||
|
||||
/** The <tt>double</tt> type. */
|
||||
/** The {@code double} type. */
|
||||
public static final Type DOUBLE_TYPE =
|
||||
new Type(DOUBLE, PRIMITIVE_DESCRIPTORS, DOUBLE, DOUBLE + 1);
|
||||
|
||||
|
|
@ -366,8 +366,8 @@ public class Type {
|
|||
* @param methodDescriptor a method descriptor.
|
||||
* @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 =
|
||||
* <tt>(argumentsSize << 2) | returnSize</tt> (argumentsSize is therefore equal to <tt>i
|
||||
* >> 2</tt>, and returnSize to <tt>i & 0x03</tt>).
|
||||
* {@code (argumentsSize << 2) | returnSize} (argumentsSize is therefore equal to {@code
|
||||
* i >> 2}, and returnSize to {@code i & 0x03}).
|
||||
*/
|
||||
public static int getArgumentsAndReturnSizes(final String methodDescriptor) {
|
||||
int argumentsSize = 1;
|
||||
|
|
@ -560,8 +560,8 @@ public class Type {
|
|||
*
|
||||
* @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 =
|
||||
* <tt>(argumentsSize << 2) | returnSize</tt> (argumentsSize is therefore equal to <tt>i
|
||||
* >> 2</tt>, and returnSize to <tt>i & 0x03</tt>).
|
||||
* {@code (argumentsSize << 2) | returnSize} (argumentsSize is therefore equal to {@code
|
||||
* i >> 2}, and returnSize to {@code i & 0x03}).
|
||||
*/
|
||||
public int getArgumentsAndReturnSizes() {
|
||||
return getArgumentsAndReturnSizes(getDescriptor());
|
||||
|
|
@ -742,8 +742,8 @@ public class Type {
|
|||
/**
|
||||
* Returns the size of values of this type. This method must not be used for method types.
|
||||
*
|
||||
* @return the size of values of this type, i.e., 2 for <tt>long</tt> and <tt>double</tt>, 0 for
|
||||
* <tt>void</tt> and 1 otherwise.
|
||||
* @return the size of values of this type, i.e., 2 for {@code long} and {@code double}, 0 for
|
||||
* {@code void} and 1 otherwise.
|
||||
*/
|
||||
public int getSize() {
|
||||
switch (sort) {
|
||||
|
|
@ -775,7 +775,7 @@ public class Type {
|
|||
* IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL, ISHR, IUSHR, IAND, IOR, IXOR and
|
||||
* IRETURN.
|
||||
* @return an opcode that is similar to the given opcode, but adapted to this {@link Type}. For
|
||||
* example, if this type is <tt>float</tt> and <tt>opcode</tt> is IRETURN, this method returns
|
||||
* example, if this type is {@code float} and {@code opcode} is IRETURN, this method returns
|
||||
* FRETURN.
|
||||
*/
|
||||
public int getOpcode(final int opcode) {
|
||||
|
|
@ -848,7 +848,7 @@ public class Type {
|
|||
* Tests if the given object is equal to this type.
|
||||
*
|
||||
* @param object the object to be compared to this type.
|
||||
* @return <tt>true</tt> if the given object is equal to this type.
|
||||
* @return {@literal true} if the given object is equal to this type.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final Object object) {
|
||||
|
|
|
|||
|
|
@ -113,8 +113,8 @@ public class TypePath {
|
|||
* object.
|
||||
*
|
||||
* @param typePath a type path in string form, in the format used by {@link #toString()}. May be
|
||||
* <tt>null</tt> or empty.
|
||||
* @return the corresponding TypePath object, or <tt>null</tt> if the path is empty.
|
||||
* {@literal null} or empty.
|
||||
* @return the corresponding TypePath object, or {@literal null} if the path is empty.
|
||||
*/
|
||||
public static TypePath fromString(final String typePath) {
|
||||
if (typePath == null || typePath.length() == 0) {
|
||||
|
|
@ -187,7 +187,7 @@ public class TypePath {
|
|||
* Puts the type_path JVMS structure corresponding to the given TypePath into the given
|
||||
* ByteVector.
|
||||
*
|
||||
* @param typePath a TypePath instance, or <tt>null</tt> for empty paths.
|
||||
* @param typePath a TypePath instance, or {@literal null} for empty paths.
|
||||
* @param output where the type path must be put.
|
||||
*/
|
||||
static void put(final TypePath typePath, final ByteVector output) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue