diff --git a/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java b/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java index c0b6b82752e..f1ff5049e6d 100644 --- a/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java @@ -67,16 +67,16 @@ public abstract class AnnotationVisitor { * @param annotationVisitor the annotation visitor to which this visitor must delegate method * calls. May be {@literal null}. */ - @SuppressWarnings("deprecation") public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) { - if (api != Opcodes.ASM7 + if (api != Opcodes.ASM8 + && api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 - && api != Opcodes.ASM8_EXPERIMENTAL) { + && api != Opcodes.ASM9_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } - // SPRING PATCH: no preview mode check for ASM 8 experimental + // SPRING PATCH: no preview mode check for ASM 9 experimental this.api = api; this.av = annotationVisitor; } diff --git a/spring-core/src/main/java/org/springframework/asm/AnnotationWriter.java b/spring-core/src/main/java/org/springframework/asm/AnnotationWriter.java index 0b29d380582..3a9c6fc1ec3 100644 --- a/spring-core/src/main/java/org/springframework/asm/AnnotationWriter.java +++ b/spring-core/src/main/java/org/springframework/asm/AnnotationWriter.java @@ -112,7 +112,7 @@ final class AnnotationWriter extends AnnotationVisitor { final boolean useNamedValues, final ByteVector annotation, final AnnotationWriter previousAnnotation) { - super(/* latest api = */ Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM8); this.symbolTable = symbolTable; this.useNamedValues = useNamedValues; this.annotation = annotation; diff --git a/spring-core/src/main/java/org/springframework/asm/ClassReader.java b/spring-core/src/main/java/org/springframework/asm/ClassReader.java index b2591c7fbb9..de157591395 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassReader.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassReader.java @@ -415,7 +415,7 @@ public class ClassReader { * @param parsingOptions the options to use to parse this class. One or more of {@link * #SKIP_CODE}, {@link #SKIP_DEBUG}, {@link #SKIP_FRAMES} or {@link #EXPAND_FRAMES}. */ - @SuppressWarnings("deprecation") + @SuppressWarnings("deprecation") // for visitPermittedSubtypeExperimental public void accept( final ClassVisitor classVisitor, final Attribute[] attributePrototypes, @@ -515,6 +515,7 @@ public class ClassReader { runtimeInvisibleTypeAnnotationsOffset = currentAttributeOffset; } else if (Constants.RECORD.equals(attributeName)) { recordOffset = currentAttributeOffset; + accessFlags |= Opcodes.ACC_RECORD; } else if (Constants.MODULE.equals(attributeName)) { moduleOffset = currentAttributeOffset; } else if (Constants.MODULE_MAIN_CLASS.equals(attributeName)) { @@ -861,7 +862,6 @@ public class ClassReader { * @param recordComponentOffset the offset of the current record component. * @return the offset of the first byte following the record component. */ - @SuppressWarnings("deprecation") private int readRecordComponent( final ClassVisitor classVisitor, final Context context, final int recordComponentOffset) { char[] charBuffer = context.charBuffer; @@ -874,7 +874,6 @@ public class ClassReader { // Read the record component attributes (the variables are ordered as in Section 4.7 of the // JVMS). - int accessFlags = 0; // Attribute offsets exclude the attribute_name_index and attribute_length fields. // - The string corresponding to the Signature attribute, or null. String signature = null; @@ -901,8 +900,6 @@ public class ClassReader { // typical classes). if (Constants.SIGNATURE.equals(attributeName)) { signature = readUTF8(currentOffset, charBuffer); - } else if (Constants.DEPRECATED.equals(attributeName)) { - accessFlags |= Opcodes.ACC_DEPRECATED; } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) { runtimeVisibleAnnotationsOffset = currentOffset; } else if (Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) { @@ -928,7 +925,7 @@ public class ClassReader { } RecordComponentVisitor recordComponentVisitor = - classVisitor.visitRecordComponentExperimental(accessFlags, name, descriptor, signature); + classVisitor.visitRecordComponent(name, descriptor, signature); if (recordComponentVisitor == null) { return currentOffset; } @@ -944,8 +941,7 @@ public class ClassReader { // Parse num_element_value_pairs and element_value_pairs and visit these values. currentAnnotationOffset = readElementValues( - recordComponentVisitor.visitAnnotationExperimental( - annotationDescriptor, /* visible = */ true), + recordComponentVisitor.visitAnnotation(annotationDescriptor, /* visible = */ true), currentAnnotationOffset, /* named = */ true, charBuffer); @@ -963,8 +959,7 @@ public class ClassReader { // Parse num_element_value_pairs and element_value_pairs and visit these values. currentAnnotationOffset = readElementValues( - recordComponentVisitor.visitAnnotationExperimental( - annotationDescriptor, /* visible = */ false), + recordComponentVisitor.visitAnnotation(annotationDescriptor, /* visible = */ false), currentAnnotationOffset, /* named = */ true, charBuffer); @@ -984,7 +979,7 @@ public class ClassReader { // Parse num_element_value_pairs and element_value_pairs and visit these values. currentAnnotationOffset = readElementValues( - recordComponentVisitor.visitTypeAnnotationExperimental( + recordComponentVisitor.visitTypeAnnotation( context.currentTypeAnnotationTarget, context.currentTypeAnnotationTargetPath, annotationDescriptor, @@ -1008,7 +1003,7 @@ public class ClassReader { // Parse num_element_value_pairs and element_value_pairs and visit these values. currentAnnotationOffset = readElementValues( - recordComponentVisitor.visitTypeAnnotationExperimental( + recordComponentVisitor.visitTypeAnnotation( context.currentTypeAnnotationTarget, context.currentTypeAnnotationTargetPath, annotationDescriptor, @@ -1024,12 +1019,12 @@ public class ClassReader { // Copy and reset the nextAttribute field so that it can also be used in FieldWriter. Attribute nextAttribute = attributes.nextAttribute; attributes.nextAttribute = null; - recordComponentVisitor.visitAttributeExperimental(attributes); + recordComponentVisitor.visitAttribute(attributes); attributes = nextAttribute; } // Visit the end of the field. - recordComponentVisitor.visitEndExperimental(); + recordComponentVisitor.visitEnd(); return currentOffset; } @@ -1531,113 +1526,113 @@ public class ClassReader { final int bytecodeOffset = currentOffset - bytecodeStartOffset; final int opcode = classBuffer[currentOffset] & 0xFF; switch (opcode) { - case Constants.NOP: - case Constants.ACONST_NULL: - case Constants.ICONST_M1: - case Constants.ICONST_0: - case Constants.ICONST_1: - case Constants.ICONST_2: - case Constants.ICONST_3: - case Constants.ICONST_4: - case Constants.ICONST_5: - case Constants.LCONST_0: - case Constants.LCONST_1: - case Constants.FCONST_0: - case Constants.FCONST_1: - case Constants.FCONST_2: - case Constants.DCONST_0: - case Constants.DCONST_1: - case Constants.IALOAD: - case Constants.LALOAD: - case Constants.FALOAD: - case Constants.DALOAD: - case Constants.AALOAD: - case Constants.BALOAD: - case Constants.CALOAD: - case Constants.SALOAD: - case Constants.IASTORE: - case Constants.LASTORE: - case Constants.FASTORE: - case Constants.DASTORE: - case Constants.AASTORE: - case Constants.BASTORE: - case Constants.CASTORE: - case Constants.SASTORE: - case Constants.POP: - case Constants.POP2: - case Constants.DUP: - case Constants.DUP_X1: - case Constants.DUP_X2: - case Constants.DUP2: - case Constants.DUP2_X1: - case Constants.DUP2_X2: - case Constants.SWAP: - case Constants.IADD: - case Constants.LADD: - case Constants.FADD: - case Constants.DADD: - case Constants.ISUB: - case Constants.LSUB: - case Constants.FSUB: - case Constants.DSUB: - case Constants.IMUL: - case Constants.LMUL: - case Constants.FMUL: - case Constants.DMUL: - case Constants.IDIV: - case Constants.LDIV: - case Constants.FDIV: - case Constants.DDIV: - case Constants.IREM: - case Constants.LREM: - case Constants.FREM: - case Constants.DREM: - case Constants.INEG: - case Constants.LNEG: - case Constants.FNEG: - case Constants.DNEG: - case Constants.ISHL: - case Constants.LSHL: - case Constants.ISHR: - case Constants.LSHR: - case Constants.IUSHR: - case Constants.LUSHR: - case Constants.IAND: - case Constants.LAND: - case Constants.IOR: - case Constants.LOR: - case Constants.IXOR: - case Constants.LXOR: - case Constants.I2L: - case Constants.I2F: - case Constants.I2D: - case Constants.L2I: - case Constants.L2F: - case Constants.L2D: - case Constants.F2I: - case Constants.F2L: - case Constants.F2D: - case Constants.D2I: - case Constants.D2L: - case Constants.D2F: - case Constants.I2B: - case Constants.I2C: - case Constants.I2S: - case Constants.LCMP: - case Constants.FCMPL: - case Constants.FCMPG: - case Constants.DCMPL: - case Constants.DCMPG: - case Constants.IRETURN: - case Constants.LRETURN: - case Constants.FRETURN: - case Constants.DRETURN: - case Constants.ARETURN: - case Constants.RETURN: - case Constants.ARRAYLENGTH: - case Constants.ATHROW: - case Constants.MONITORENTER: - case Constants.MONITOREXIT: + case Opcodes.NOP: + case Opcodes.ACONST_NULL: + case Opcodes.ICONST_M1: + case Opcodes.ICONST_0: + case Opcodes.ICONST_1: + case Opcodes.ICONST_2: + case Opcodes.ICONST_3: + case Opcodes.ICONST_4: + case Opcodes.ICONST_5: + case Opcodes.LCONST_0: + case Opcodes.LCONST_1: + case Opcodes.FCONST_0: + case Opcodes.FCONST_1: + case Opcodes.FCONST_2: + case Opcodes.DCONST_0: + case Opcodes.DCONST_1: + case Opcodes.IALOAD: + case Opcodes.LALOAD: + case Opcodes.FALOAD: + case Opcodes.DALOAD: + case Opcodes.AALOAD: + case Opcodes.BALOAD: + case Opcodes.CALOAD: + case Opcodes.SALOAD: + case Opcodes.IASTORE: + case Opcodes.LASTORE: + case Opcodes.FASTORE: + case Opcodes.DASTORE: + case Opcodes.AASTORE: + case Opcodes.BASTORE: + case Opcodes.CASTORE: + case Opcodes.SASTORE: + case Opcodes.POP: + case Opcodes.POP2: + case Opcodes.DUP: + case Opcodes.DUP_X1: + case Opcodes.DUP_X2: + case Opcodes.DUP2: + case Opcodes.DUP2_X1: + case Opcodes.DUP2_X2: + case Opcodes.SWAP: + case Opcodes.IADD: + case Opcodes.LADD: + case Opcodes.FADD: + case Opcodes.DADD: + case Opcodes.ISUB: + case Opcodes.LSUB: + case Opcodes.FSUB: + case Opcodes.DSUB: + case Opcodes.IMUL: + case Opcodes.LMUL: + case Opcodes.FMUL: + case Opcodes.DMUL: + case Opcodes.IDIV: + case Opcodes.LDIV: + case Opcodes.FDIV: + case Opcodes.DDIV: + case Opcodes.IREM: + case Opcodes.LREM: + case Opcodes.FREM: + case Opcodes.DREM: + case Opcodes.INEG: + case Opcodes.LNEG: + case Opcodes.FNEG: + case Opcodes.DNEG: + case Opcodes.ISHL: + case Opcodes.LSHL: + case Opcodes.ISHR: + case Opcodes.LSHR: + case Opcodes.IUSHR: + case Opcodes.LUSHR: + case Opcodes.IAND: + case Opcodes.LAND: + case Opcodes.IOR: + case Opcodes.LOR: + case Opcodes.IXOR: + case Opcodes.LXOR: + case Opcodes.I2L: + case Opcodes.I2F: + case Opcodes.I2D: + case Opcodes.L2I: + case Opcodes.L2F: + case Opcodes.L2D: + case Opcodes.F2I: + case Opcodes.F2L: + case Opcodes.F2D: + case Opcodes.D2I: + case Opcodes.D2L: + case Opcodes.D2F: + case Opcodes.I2B: + case Opcodes.I2C: + case Opcodes.I2S: + case Opcodes.LCMP: + case Opcodes.FCMPL: + case Opcodes.FCMPG: + case Opcodes.DCMPL: + case Opcodes.DCMPG: + case Opcodes.IRETURN: + case Opcodes.LRETURN: + case Opcodes.FRETURN: + case Opcodes.DRETURN: + case Opcodes.ARETURN: + case Opcodes.RETURN: + case Opcodes.ARRAYLENGTH: + case Opcodes.ATHROW: + case Opcodes.MONITORENTER: + case Opcodes.MONITOREXIT: case Constants.ILOAD_0: case Constants.ILOAD_1: case Constants.ILOAD_2: @@ -1680,24 +1675,24 @@ public class ClassReader { case Constants.ASTORE_3: currentOffset += 1; break; - case Constants.IFEQ: - case Constants.IFNE: - case Constants.IFLT: - case Constants.IFGE: - case Constants.IFGT: - case Constants.IFLE: - case Constants.IF_ICMPEQ: - case Constants.IF_ICMPNE: - case Constants.IF_ICMPLT: - case Constants.IF_ICMPGE: - case Constants.IF_ICMPGT: - case Constants.IF_ICMPLE: - case Constants.IF_ACMPEQ: - case Constants.IF_ACMPNE: - case Constants.GOTO: - case Constants.JSR: - case Constants.IFNULL: - case Constants.IFNONNULL: + case Opcodes.IFEQ: + case Opcodes.IFNE: + case Opcodes.IFLT: + case Opcodes.IFGE: + case Opcodes.IFGT: + case Opcodes.IFLE: + case Opcodes.IF_ICMPEQ: + case Opcodes.IF_ICMPNE: + case Opcodes.IF_ICMPLT: + case Opcodes.IF_ICMPGE: + case Opcodes.IF_ICMPGT: + case Opcodes.IF_ICMPLE: + case Opcodes.IF_ACMPEQ: + case Opcodes.IF_ACMPNE: + case Opcodes.GOTO: + case Opcodes.JSR: + case Opcodes.IFNULL: + case Opcodes.IFNONNULL: createLabel(bytecodeOffset + readShort(currentOffset + 1), labels); currentOffset += 3; break; @@ -1730,27 +1725,27 @@ public class ClassReader { break; case Constants.WIDE: switch (classBuffer[currentOffset + 1] & 0xFF) { - case Constants.ILOAD: - case Constants.FLOAD: - case Constants.ALOAD: - case Constants.LLOAD: - case Constants.DLOAD: - case Constants.ISTORE: - case Constants.FSTORE: - case Constants.ASTORE: - case Constants.LSTORE: - case Constants.DSTORE: - case Constants.RET: + case Opcodes.ILOAD: + case Opcodes.FLOAD: + case Opcodes.ALOAD: + case Opcodes.LLOAD: + case Opcodes.DLOAD: + case Opcodes.ISTORE: + case Opcodes.FSTORE: + case Opcodes.ASTORE: + case Opcodes.LSTORE: + case Opcodes.DSTORE: + case Opcodes.RET: currentOffset += 4; break; - case Constants.IINC: + case Opcodes.IINC: currentOffset += 6; break; default: throw new IllegalArgumentException(); } break; - case Constants.TABLESWITCH: + case Opcodes.TABLESWITCH: // Skip 0 to 3 padding bytes. currentOffset += 4 - (bytecodeOffset & 3); // Read the default label and the number of table entries. @@ -1763,7 +1758,7 @@ public class ClassReader { currentOffset += 4; } break; - case Constants.LOOKUPSWITCH: + case Opcodes.LOOKUPSWITCH: // Skip 0 to 3 padding bytes. currentOffset += 4 - (bytecodeOffset & 3); // Read the default label and the number of switch cases. @@ -1776,44 +1771,44 @@ public class ClassReader { currentOffset += 8; } break; - case Constants.ILOAD: - case Constants.LLOAD: - case Constants.FLOAD: - case Constants.DLOAD: - case Constants.ALOAD: - case Constants.ISTORE: - case Constants.LSTORE: - case Constants.FSTORE: - case Constants.DSTORE: - case Constants.ASTORE: - case Constants.RET: - case Constants.BIPUSH: - case Constants.NEWARRAY: - case Constants.LDC: + case Opcodes.ILOAD: + case Opcodes.LLOAD: + case Opcodes.FLOAD: + case Opcodes.DLOAD: + case Opcodes.ALOAD: + case Opcodes.ISTORE: + case Opcodes.LSTORE: + case Opcodes.FSTORE: + case Opcodes.DSTORE: + case Opcodes.ASTORE: + case Opcodes.RET: + case Opcodes.BIPUSH: + case Opcodes.NEWARRAY: + case Opcodes.LDC: currentOffset += 2; break; - case Constants.SIPUSH: + case Opcodes.SIPUSH: case Constants.LDC_W: case Constants.LDC2_W: - case Constants.GETSTATIC: - case Constants.PUTSTATIC: - case Constants.GETFIELD: - case Constants.PUTFIELD: - case Constants.INVOKEVIRTUAL: - case Constants.INVOKESPECIAL: - case Constants.INVOKESTATIC: - case Constants.NEW: - case Constants.ANEWARRAY: - case Constants.CHECKCAST: - case Constants.INSTANCEOF: - case Constants.IINC: + case Opcodes.GETSTATIC: + case Opcodes.PUTSTATIC: + case Opcodes.GETFIELD: + case Opcodes.PUTFIELD: + case Opcodes.INVOKEVIRTUAL: + case Opcodes.INVOKESPECIAL: + case Opcodes.INVOKESTATIC: + case Opcodes.NEW: + case Opcodes.ANEWARRAY: + case Opcodes.CHECKCAST: + case Opcodes.INSTANCEOF: + case Opcodes.IINC: currentOffset += 3; break; - case Constants.INVOKEINTERFACE: - case Constants.INVOKEDYNAMIC: + case Opcodes.INVOKEINTERFACE: + case Opcodes.INVOKEDYNAMIC: currentOffset += 5; break; - case Constants.MULTIANEWARRAY: + case Opcodes.MULTIANEWARRAY: currentOffset += 4; break; default: @@ -2080,113 +2075,113 @@ public class ClassReader { // Visit the instruction at this bytecode offset. int opcode = classBuffer[currentOffset] & 0xFF; switch (opcode) { - case Constants.NOP: - case Constants.ACONST_NULL: - case Constants.ICONST_M1: - case Constants.ICONST_0: - case Constants.ICONST_1: - case Constants.ICONST_2: - case Constants.ICONST_3: - case Constants.ICONST_4: - case Constants.ICONST_5: - case Constants.LCONST_0: - case Constants.LCONST_1: - case Constants.FCONST_0: - case Constants.FCONST_1: - case Constants.FCONST_2: - case Constants.DCONST_0: - case Constants.DCONST_1: - case Constants.IALOAD: - case Constants.LALOAD: - case Constants.FALOAD: - case Constants.DALOAD: - case Constants.AALOAD: - case Constants.BALOAD: - case Constants.CALOAD: - case Constants.SALOAD: - case Constants.IASTORE: - case Constants.LASTORE: - case Constants.FASTORE: - case Constants.DASTORE: - case Constants.AASTORE: - case Constants.BASTORE: - case Constants.CASTORE: - case Constants.SASTORE: - case Constants.POP: - case Constants.POP2: - case Constants.DUP: - case Constants.DUP_X1: - case Constants.DUP_X2: - case Constants.DUP2: - case Constants.DUP2_X1: - case Constants.DUP2_X2: - case Constants.SWAP: - case Constants.IADD: - case Constants.LADD: - case Constants.FADD: - case Constants.DADD: - case Constants.ISUB: - case Constants.LSUB: - case Constants.FSUB: - case Constants.DSUB: - case Constants.IMUL: - case Constants.LMUL: - case Constants.FMUL: - case Constants.DMUL: - case Constants.IDIV: - case Constants.LDIV: - case Constants.FDIV: - case Constants.DDIV: - case Constants.IREM: - case Constants.LREM: - case Constants.FREM: - case Constants.DREM: - case Constants.INEG: - case Constants.LNEG: - case Constants.FNEG: - case Constants.DNEG: - case Constants.ISHL: - case Constants.LSHL: - case Constants.ISHR: - case Constants.LSHR: - case Constants.IUSHR: - case Constants.LUSHR: - case Constants.IAND: - case Constants.LAND: - case Constants.IOR: - case Constants.LOR: - case Constants.IXOR: - case Constants.LXOR: - case Constants.I2L: - case Constants.I2F: - case Constants.I2D: - case Constants.L2I: - case Constants.L2F: - case Constants.L2D: - case Constants.F2I: - case Constants.F2L: - case Constants.F2D: - case Constants.D2I: - case Constants.D2L: - case Constants.D2F: - case Constants.I2B: - case Constants.I2C: - case Constants.I2S: - case Constants.LCMP: - case Constants.FCMPL: - case Constants.FCMPG: - case Constants.DCMPL: - case Constants.DCMPG: - case Constants.IRETURN: - case Constants.LRETURN: - case Constants.FRETURN: - case Constants.DRETURN: - case Constants.ARETURN: - case Constants.RETURN: - case Constants.ARRAYLENGTH: - case Constants.ATHROW: - case Constants.MONITORENTER: - case Constants.MONITOREXIT: + case Opcodes.NOP: + case Opcodes.ACONST_NULL: + case Opcodes.ICONST_M1: + case Opcodes.ICONST_0: + case Opcodes.ICONST_1: + case Opcodes.ICONST_2: + case Opcodes.ICONST_3: + case Opcodes.ICONST_4: + case Opcodes.ICONST_5: + case Opcodes.LCONST_0: + case Opcodes.LCONST_1: + case Opcodes.FCONST_0: + case Opcodes.FCONST_1: + case Opcodes.FCONST_2: + case Opcodes.DCONST_0: + case Opcodes.DCONST_1: + case Opcodes.IALOAD: + case Opcodes.LALOAD: + case Opcodes.FALOAD: + case Opcodes.DALOAD: + case Opcodes.AALOAD: + case Opcodes.BALOAD: + case Opcodes.CALOAD: + case Opcodes.SALOAD: + case Opcodes.IASTORE: + case Opcodes.LASTORE: + case Opcodes.FASTORE: + case Opcodes.DASTORE: + case Opcodes.AASTORE: + case Opcodes.BASTORE: + case Opcodes.CASTORE: + case Opcodes.SASTORE: + case Opcodes.POP: + case Opcodes.POP2: + case Opcodes.DUP: + case Opcodes.DUP_X1: + case Opcodes.DUP_X2: + case Opcodes.DUP2: + case Opcodes.DUP2_X1: + case Opcodes.DUP2_X2: + case Opcodes.SWAP: + case Opcodes.IADD: + case Opcodes.LADD: + case Opcodes.FADD: + case Opcodes.DADD: + case Opcodes.ISUB: + case Opcodes.LSUB: + case Opcodes.FSUB: + case Opcodes.DSUB: + case Opcodes.IMUL: + case Opcodes.LMUL: + case Opcodes.FMUL: + case Opcodes.DMUL: + case Opcodes.IDIV: + case Opcodes.LDIV: + case Opcodes.FDIV: + case Opcodes.DDIV: + case Opcodes.IREM: + case Opcodes.LREM: + case Opcodes.FREM: + case Opcodes.DREM: + case Opcodes.INEG: + case Opcodes.LNEG: + case Opcodes.FNEG: + case Opcodes.DNEG: + case Opcodes.ISHL: + case Opcodes.LSHL: + case Opcodes.ISHR: + case Opcodes.LSHR: + case Opcodes.IUSHR: + case Opcodes.LUSHR: + case Opcodes.IAND: + case Opcodes.LAND: + case Opcodes.IOR: + case Opcodes.LOR: + case Opcodes.IXOR: + case Opcodes.LXOR: + case Opcodes.I2L: + case Opcodes.I2F: + case Opcodes.I2D: + case Opcodes.L2I: + case Opcodes.L2F: + case Opcodes.L2D: + case Opcodes.F2I: + case Opcodes.F2L: + case Opcodes.F2D: + case Opcodes.D2I: + case Opcodes.D2L: + case Opcodes.D2F: + case Opcodes.I2B: + case Opcodes.I2C: + case Opcodes.I2S: + case Opcodes.LCMP: + case Opcodes.FCMPL: + case Opcodes.FCMPG: + case Opcodes.DCMPL: + case Opcodes.DCMPG: + case Opcodes.IRETURN: + case Opcodes.LRETURN: + case Opcodes.FRETURN: + case Opcodes.DRETURN: + case Opcodes.ARETURN: + case Opcodes.RETURN: + case Opcodes.ARRAYLENGTH: + case Opcodes.ATHROW: + case Opcodes.MONITORENTER: + case Opcodes.MONITOREXIT: methodVisitor.visitInsn(opcode); currentOffset += 1; break; @@ -2238,24 +2233,24 @@ public class ClassReader { methodVisitor.visitVarInsn(Opcodes.ISTORE + (opcode >> 2), opcode & 0x3); currentOffset += 1; break; - case Constants.IFEQ: - case Constants.IFNE: - case Constants.IFLT: - case Constants.IFGE: - case Constants.IFGT: - case Constants.IFLE: - case Constants.IF_ICMPEQ: - case Constants.IF_ICMPNE: - case Constants.IF_ICMPLT: - case Constants.IF_ICMPGE: - case Constants.IF_ICMPGT: - case Constants.IF_ICMPLE: - case Constants.IF_ACMPEQ: - case Constants.IF_ACMPNE: - case Constants.GOTO: - case Constants.JSR: - case Constants.IFNULL: - case Constants.IFNONNULL: + case Opcodes.IFEQ: + case Opcodes.IFNE: + case Opcodes.IFLT: + case Opcodes.IFGE: + case Opcodes.IFGT: + case Opcodes.IFLE: + case Opcodes.IF_ICMPEQ: + case Opcodes.IF_ICMPNE: + case Opcodes.IF_ICMPLT: + case Opcodes.IF_ICMPGE: + case Opcodes.IF_ICMPGT: + case Opcodes.IF_ICMPLE: + case Opcodes.IF_ACMPEQ: + case Opcodes.IF_ACMPNE: + case Opcodes.GOTO: + case Opcodes.JSR: + case Opcodes.IFNULL: + case Opcodes.IFNONNULL: methodVisitor.visitJumpInsn( opcode, labels[currentBytecodeOffset + readShort(currentOffset + 1)]); currentOffset += 3; @@ -2336,7 +2331,7 @@ public class ClassReader { currentOffset += 4; } break; - case Constants.TABLESWITCH: + case Opcodes.TABLESWITCH: { // Skip 0 to 3 padding bytes. currentOffset += 4 - (currentBytecodeOffset & 3); @@ -2353,7 +2348,7 @@ public class ClassReader { methodVisitor.visitTableSwitchInsn(low, high, defaultLabel, table); break; } - case Constants.LOOKUPSWITCH: + case Opcodes.LOOKUPSWITCH: { // Skip 0 to 3 padding bytes. currentOffset += 4 - (currentBytecodeOffset & 3); @@ -2371,30 +2366,30 @@ public class ClassReader { methodVisitor.visitLookupSwitchInsn(defaultLabel, keys, values); break; } - case Constants.ILOAD: - case Constants.LLOAD: - case Constants.FLOAD: - case Constants.DLOAD: - case Constants.ALOAD: - case Constants.ISTORE: - case Constants.LSTORE: - case Constants.FSTORE: - case Constants.DSTORE: - case Constants.ASTORE: - case Constants.RET: + case Opcodes.ILOAD: + case Opcodes.LLOAD: + case Opcodes.FLOAD: + case Opcodes.DLOAD: + case Opcodes.ALOAD: + case Opcodes.ISTORE: + case Opcodes.LSTORE: + case Opcodes.FSTORE: + case Opcodes.DSTORE: + case Opcodes.ASTORE: + case Opcodes.RET: methodVisitor.visitVarInsn(opcode, classBuffer[currentOffset + 1] & 0xFF); currentOffset += 2; break; - case Constants.BIPUSH: - case Constants.NEWARRAY: + case Opcodes.BIPUSH: + case Opcodes.NEWARRAY: methodVisitor.visitIntInsn(opcode, classBuffer[currentOffset + 1]); currentOffset += 2; break; - case Constants.SIPUSH: + case Opcodes.SIPUSH: methodVisitor.visitIntInsn(opcode, readShort(currentOffset + 1)); currentOffset += 3; break; - case Constants.LDC: + case Opcodes.LDC: methodVisitor.visitLdcInsn(readConst(classBuffer[currentOffset + 1] & 0xFF, charBuffer)); currentOffset += 2; break; @@ -2403,14 +2398,14 @@ public class ClassReader { methodVisitor.visitLdcInsn(readConst(readUnsignedShort(currentOffset + 1), charBuffer)); currentOffset += 3; break; - case Constants.GETSTATIC: - case Constants.PUTSTATIC: - case Constants.GETFIELD: - case Constants.PUTFIELD: - case Constants.INVOKEVIRTUAL: - case Constants.INVOKESPECIAL: - case Constants.INVOKESTATIC: - case Constants.INVOKEINTERFACE: + case Opcodes.GETSTATIC: + case Opcodes.PUTSTATIC: + case Opcodes.GETFIELD: + case Opcodes.PUTFIELD: + case Opcodes.INVOKEVIRTUAL: + case Opcodes.INVOKESPECIAL: + case Opcodes.INVOKESTATIC: + case Opcodes.INVOKEINTERFACE: { int cpInfoOffset = cpInfoOffsets[readUnsignedShort(currentOffset + 1)]; int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 2)]; @@ -2431,7 +2426,7 @@ public class ClassReader { } break; } - case Constants.INVOKEDYNAMIC: + case Opcodes.INVOKEDYNAMIC: { int cpInfoOffset = cpInfoOffsets[readUnsignedShort(currentOffset + 1)]; int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 2)]; @@ -2453,19 +2448,19 @@ public class ClassReader { currentOffset += 5; break; } - case Constants.NEW: - case Constants.ANEWARRAY: - case Constants.CHECKCAST: - case Constants.INSTANCEOF: + case Opcodes.NEW: + case Opcodes.ANEWARRAY: + case Opcodes.CHECKCAST: + case Opcodes.INSTANCEOF: methodVisitor.visitTypeInsn(opcode, readClass(currentOffset + 1, charBuffer)); currentOffset += 3; break; - case Constants.IINC: + case Opcodes.IINC: methodVisitor.visitIincInsn( classBuffer[currentOffset + 1] & 0xFF, classBuffer[currentOffset + 2]); currentOffset += 3; break; - case Constants.MULTIANEWARRAY: + case Opcodes.MULTIANEWARRAY: methodVisitor.visitMultiANewArrayInsn( readClass(currentOffset + 1, charBuffer), classBuffer[currentOffset + 3] & 0xFF); currentOffset += 4; diff --git a/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java b/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java index 18d4d194cf9..46b7c547977 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java @@ -32,7 +32,8 @@ package org.springframework.asm; * {@code visit} [ {@code visitSource} ] [ {@code visitModule} ][ {@code visitNestHost} ][ {@code * visitPermittedSubtype} ][ {@code visitOuterClass} ] ( {@code visitAnnotation} | {@code * visitTypeAnnotation} | {@code visitAttribute} )* ( {@code visitNestMember} | {@code - * visitInnerClass} | {@code visitField} | {@code visitMethod} )* {@code visitEnd}. + * visitInnerClass} | {@code visitRecordComponent} | {@code visitField} | {@code visitMethod} )* + * {@code visitEnd}. * * @author Eric Bruneton */ @@ -61,20 +62,21 @@ 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}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link + * Opcodes#ASM8}. * @param classVisitor the class visitor to which this visitor must delegate method calls. May be * null. */ - @SuppressWarnings("deprecation") public ClassVisitor(final int api, final ClassVisitor classVisitor) { - if (api != Opcodes.ASM7 + if (api != Opcodes.ASM8 + && api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 - && api != Opcodes.ASM8_EXPERIMENTAL) { + && api != Opcodes.ASM9_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } - // SPRING PATCH: no preview mode check for ASM 8 experimental + // SPRING PATCH: no preview mode check for ASM 9 experimental this.api = api; this.cv = classVisitor; } @@ -85,7 +87,8 @@ public abstract class ClassVisitor { * @param version the class version. The minor version is stored in the 16 most significant bits, * and the major version in the 16 least significant bits. * @param access the class's access flags (see {@link Opcodes}). This parameter also indicates if - * the class is deprecated. + * the class is deprecated {@link Opcodes#ACC_DEPRECATED} or a record {@link + * Opcodes#ACC_RECORD}. * @param name the internal name of the class (see {@link Type#getInternalName()}). * @param signature the signature of this class. May be {@literal null} if the class is not a * generic one, and does not extend or implement generic classes or interfaces. @@ -102,6 +105,9 @@ public abstract class ClassVisitor { final String signature, final String superName, final String[] interfaces) { + if (api < Opcodes.ASM8 && (access & Opcodes.ACC_RECORD) != 0) { + throw new UnsupportedOperationException("Records requires ASM8"); + } if (cv != null) { cv.visit(version, access, name, signature, superName, interfaces); } @@ -256,8 +262,8 @@ public abstract class ClassVisitor { */ @Deprecated public void visitPermittedSubtypeExperimental(final String permittedSubtype) { - if (api != Opcodes.ASM8_EXPERIMENTAL) { - throw new UnsupportedOperationException("This feature requires ASM8_EXPERIMENTAL"); + if (api != Opcodes.ASM9_EXPERIMENTAL) { + throw new UnsupportedOperationException("This feature requires ASM9_EXPERIMENTAL"); } if (cv != null) { cv.visitPermittedSubtypeExperimental(permittedSubtype); @@ -286,24 +292,20 @@ public abstract class ClassVisitor { /** * Visits a record component of the class. * - * @param access the record component access flags, the only possible value is {@link - * Opcodes#ACC_DEPRECATED}. * @param name the record component name. * @param descriptor the record component descriptor (see {@link Type}). * @param signature the record component signature. May be {@literal null} if the record component * type does not use generic types. * @return a visitor to visit this record component annotations and attributes, or {@literal null} * if this class visitor is not interested in visiting these annotations and attributes. - * @deprecated this API is experimental. */ - @Deprecated - public RecordComponentVisitor visitRecordComponentExperimental( - final int access, final String name, final String descriptor, final String signature) { - if (api < Opcodes.ASM8_EXPERIMENTAL) { - throw new UnsupportedOperationException("This feature requires ASM8_EXPERIMENTAL"); + public RecordComponentVisitor visitRecordComponent( + final String name, final String descriptor, final String signature) { + if (api < Opcodes.ASM8) { + throw new UnsupportedOperationException("This feature requires ASM8"); } if (cv != null) { - return cv.visitRecordComponentExperimental(access, name, descriptor, signature); + return cv.visitRecordComponent(name, descriptor, signature); } return null; } diff --git a/spring-core/src/main/java/org/springframework/asm/ClassWriter.java b/spring-core/src/main/java/org/springframework/asm/ClassWriter.java index ed0e48cf5b0..4641bbeefaf 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassWriter.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassWriter.java @@ -79,8 +79,8 @@ public class ClassWriter extends ClassVisitor { /** * The access_flags field of the JVMS ClassFile structure. This field can contain ASM specific - * access flags, such as {@link Opcodes#ACC_DEPRECATED}, which are removed when generating the - * ClassFile structure. + * access flags, such as {@link Opcodes#ACC_DEPRECATED} or {}@link Opcodes#ACC_RECORD}, which are + * removed when generating the ClassFile structure. */ private int accessFlags; @@ -254,7 +254,7 @@ public class ClassWriter extends ClassVisitor { * maximum stack size nor the stack frames will be computed for these methods. */ public ClassWriter(final ClassReader classReader, final int flags) { - super(/* latest api = */ Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM8); symbolTable = classReader == null ? new SymbolTable(this) : new SymbolTable(this, classReader); if ((flags & COMPUTE_FRAMES) != 0) { this.compute = MethodWriter.COMPUTE_ALL_FRAMES; @@ -372,8 +372,14 @@ public class ClassWriter extends ClassVisitor { nestMemberClasses.putShort(symbolTable.addConstantClass(nestMember).index); } + /** + * Experimental, use at your own risk. + * + * @param permittedSubtype the internal name of a permitted subtype. + * @deprecated this API is experimental. + */ @Override - @SuppressWarnings("deprecation") + @Deprecated public final void visitPermittedSubtypeExperimental(final String permittedSubtype) { if (permittedSubtypeClasses == null) { permittedSubtypeClasses = new ByteVector(); @@ -408,11 +414,10 @@ public class ClassWriter extends ClassVisitor { } @Override - @SuppressWarnings("deprecation") - public final RecordComponentVisitor visitRecordComponentExperimental( - final int access, final String name, final String descriptor, final String signature) { + public final RecordComponentVisitor visitRecordComponent( + final String name, final String descriptor, final String signature) { RecordComponentWriter recordComponentWriter = - new RecordComponentWriter(symbolTable, access, name, descriptor, signature); + new RecordComponentWriter(symbolTable, name, descriptor, signature); if (firstRecordComponent == null) { firstRecordComponent = recordComponentWriter; } else { @@ -578,7 +583,7 @@ public class ClassWriter extends ClassVisitor { } int recordComponentCount = 0; int recordSize = 0; - if (firstRecordComponent != null) { + if ((accessFlags & Opcodes.ACC_RECORD) != 0 || firstRecordComponent != null) { RecordComponentWriter recordComponentWriter = firstRecordComponent; while (recordComponentWriter != null) { ++recordComponentCount; @@ -700,7 +705,7 @@ public class ClassWriter extends ClassVisitor { .putShort(numberOfPermittedSubtypeClasses) .putByteArray(permittedSubtypeClasses.data, 0, permittedSubtypeClasses.length); } - if (firstRecordComponent != null) { + if ((accessFlags & Opcodes.ACC_RECORD) != 0 || firstRecordComponent != null) { result .putShort(symbolTable.addConstantUtf8(Constants.RECORD)) .putInt(recordSize + 2) @@ -916,7 +921,7 @@ public class ClassWriter extends ClassVisitor { * if the constant pool already contains a similar item. This method is intended for {@link * Attribute} sub classes, and is normally not needed by class generators or adapters. * - * @param name the name of the invoked method. + * @param name name of the invoked method. * @param descriptor field descriptor of the constant type. * @param bootstrapMethodHandle the bootstrap method. * @param bootstrapMethodArguments the bootstrap method constant arguments. @@ -937,7 +942,7 @@ public class ClassWriter extends ClassVisitor { * the constant pool already contains a similar item. This method is intended for {@link * Attribute} sub classes, and is normally not needed by class generators or adapters. * - * @param name the name of the invoked method. + * @param name name of the invoked method. * @param descriptor descriptor of the invoke method. * @param bootstrapMethodHandle the bootstrap method. * @param bootstrapMethodArguments the bootstrap method constant arguments. diff --git a/spring-core/src/main/java/org/springframework/asm/Constants.java b/spring-core/src/main/java/org/springframework/asm/Constants.java index 7012a7efd39..a9f5864bc46 100644 --- a/spring-core/src/main/java/org/springframework/asm/Constants.java +++ b/spring-core/src/main/java/org/springframework/asm/Constants.java @@ -34,7 +34,7 @@ package org.springframework.asm; * @see JVMS 6 * @author Eric Bruneton */ -final class Constants implements Opcodes { +final class Constants { // The ClassFile attribute names, in the order they are defined in // https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7-300. @@ -141,7 +141,7 @@ final class Constants implements Opcodes { // Constants to convert between normal and wide jump instructions. // The delta between the GOTO_W and JSR_W opcodes and GOTO and JUMP. - static final int WIDE_JUMP_OPCODE_DELTA = GOTO_W - GOTO; + static final int WIDE_JUMP_OPCODE_DELTA = GOTO_W - Opcodes.GOTO; // Constants to convert JVM opcodes to the equivalent ASM specific opcodes, and vice versa. @@ -154,24 +154,24 @@ final class Constants implements Opcodes { // ASM specific opcodes, used for long forward jump instructions. - static final int ASM_IFEQ = IFEQ + ASM_OPCODE_DELTA; - static final int ASM_IFNE = IFNE + ASM_OPCODE_DELTA; - static final int ASM_IFLT = IFLT + ASM_OPCODE_DELTA; - static final int ASM_IFGE = IFGE + ASM_OPCODE_DELTA; - static final int ASM_IFGT = IFGT + ASM_OPCODE_DELTA; - static final int ASM_IFLE = IFLE + ASM_OPCODE_DELTA; - static final int ASM_IF_ICMPEQ = IF_ICMPEQ + ASM_OPCODE_DELTA; - static final int ASM_IF_ICMPNE = IF_ICMPNE + ASM_OPCODE_DELTA; - static final int ASM_IF_ICMPLT = IF_ICMPLT + ASM_OPCODE_DELTA; - static final int ASM_IF_ICMPGE = IF_ICMPGE + ASM_OPCODE_DELTA; - static final int ASM_IF_ICMPGT = IF_ICMPGT + ASM_OPCODE_DELTA; - static final int ASM_IF_ICMPLE = IF_ICMPLE + ASM_OPCODE_DELTA; - static final int ASM_IF_ACMPEQ = IF_ACMPEQ + ASM_OPCODE_DELTA; - static final int ASM_IF_ACMPNE = IF_ACMPNE + ASM_OPCODE_DELTA; - static final int ASM_GOTO = GOTO + ASM_OPCODE_DELTA; - static final int ASM_JSR = JSR + ASM_OPCODE_DELTA; - static final int ASM_IFNULL = IFNULL + ASM_IFNULL_OPCODE_DELTA; - static final int ASM_IFNONNULL = IFNONNULL + ASM_IFNULL_OPCODE_DELTA; + static final int ASM_IFEQ = Opcodes.IFEQ + ASM_OPCODE_DELTA; + static final int ASM_IFNE = Opcodes.IFNE + ASM_OPCODE_DELTA; + static final int ASM_IFLT = Opcodes.IFLT + ASM_OPCODE_DELTA; + static final int ASM_IFGE = Opcodes.IFGE + ASM_OPCODE_DELTA; + static final int ASM_IFGT = Opcodes.IFGT + ASM_OPCODE_DELTA; + static final int ASM_IFLE = Opcodes.IFLE + ASM_OPCODE_DELTA; + static final int ASM_IF_ICMPEQ = Opcodes.IF_ICMPEQ + ASM_OPCODE_DELTA; + static final int ASM_IF_ICMPNE = Opcodes.IF_ICMPNE + ASM_OPCODE_DELTA; + static final int ASM_IF_ICMPLT = Opcodes.IF_ICMPLT + ASM_OPCODE_DELTA; + static final int ASM_IF_ICMPGE = Opcodes.IF_ICMPGE + ASM_OPCODE_DELTA; + static final int ASM_IF_ICMPGT = Opcodes.IF_ICMPGT + ASM_OPCODE_DELTA; + static final int ASM_IF_ICMPLE = Opcodes.IF_ICMPLE + ASM_OPCODE_DELTA; + static final int ASM_IF_ACMPEQ = Opcodes.IF_ACMPEQ + ASM_OPCODE_DELTA; + static final int ASM_IF_ACMPNE = Opcodes.IF_ACMPNE + ASM_OPCODE_DELTA; + static final int ASM_GOTO = Opcodes.GOTO + ASM_OPCODE_DELTA; + static final int ASM_JSR = Opcodes.JSR + ASM_OPCODE_DELTA; + static final int ASM_IFNULL = Opcodes.IFNULL + ASM_IFNULL_OPCODE_DELTA; + static final int ASM_IFNONNULL = Opcodes.IFNONNULL + ASM_IFNULL_OPCODE_DELTA; static final int ASM_GOTO_W = 220; private Constants() {} diff --git a/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java b/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java index d9a62ca1ed7..70fa653d361 100644 --- a/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java @@ -38,7 +38,8 @@ 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}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link + * Opcodes#ASM8}. */ protected final int api; @@ -49,7 +50,8 @@ 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}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link + * Opcodes#ASM8}. */ public FieldVisitor(final int api) { this(api, null); @@ -59,20 +61,21 @@ 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}. + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link + * Opcodes#ASM8}. * @param fieldVisitor the field visitor to which this visitor must delegate method calls. May be * null. */ - @SuppressWarnings("deprecation") public FieldVisitor(final int api, final FieldVisitor fieldVisitor) { - if (api != Opcodes.ASM7 + if (api != Opcodes.ASM8 + && api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 - && api != Opcodes.ASM8_EXPERIMENTAL) { + && api != Opcodes.ASM9_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } - // SPRING PATCH: no preview mode check for ASM 8 experimental + // SPRING PATCH: no preview mode check for ASM 9 experimental this.api = api; this.fv = fieldVisitor; } diff --git a/spring-core/src/main/java/org/springframework/asm/FieldWriter.java b/spring-core/src/main/java/org/springframework/asm/FieldWriter.java index ab8ad32ee59..33e0ecef416 100644 --- a/spring-core/src/main/java/org/springframework/asm/FieldWriter.java +++ b/spring-core/src/main/java/org/springframework/asm/FieldWriter.java @@ -124,7 +124,7 @@ final class FieldWriter extends FieldVisitor { final String descriptor, final String signature, final Object constantValue) { - super(/* latest api = */ Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM8); this.symbolTable = symbolTable; this.accessFlags = access; this.nameIndex = symbolTable.addConstantUtf8(name); diff --git a/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java b/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java index e3373808757..5c079e96bd2 100644 --- a/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java @@ -79,16 +79,16 @@ public abstract class MethodVisitor { * @param methodVisitor the method visitor to which this visitor must delegate method calls. May * be null. */ - @SuppressWarnings("deprecation") public MethodVisitor(final int api, final MethodVisitor methodVisitor) { - if (api != Opcodes.ASM7 + if (api != Opcodes.ASM8 + && api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 - && api != Opcodes.ASM8_EXPERIMENTAL) { + && api != Opcodes.ASM9_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } - // SPRING PATCH: no preview mode check for ASM 8 experimental + // SPRING PATCH: no preview mode check for ASM 9 experimental this.api = api; this.mv = methodVisitor; } diff --git a/spring-core/src/main/java/org/springframework/asm/MethodWriter.java b/spring-core/src/main/java/org/springframework/asm/MethodWriter.java index 4cc0552dc85..ed07e341ff4 100644 --- a/spring-core/src/main/java/org/springframework/asm/MethodWriter.java +++ b/spring-core/src/main/java/org/springframework/asm/MethodWriter.java @@ -592,7 +592,7 @@ final class MethodWriter extends MethodVisitor { final String signature, final String[] exceptions, final int compute) { - super(/* latest api = */ Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM8); this.symbolTable = symbolTable; this.accessFlags = "".equals(name) ? access | Constants.ACC_CONSTRUCTOR : access; this.nameIndex = symbolTable.addConstantUtf8(name); diff --git a/spring-core/src/main/java/org/springframework/asm/ModuleVisitor.java b/spring-core/src/main/java/org/springframework/asm/ModuleVisitor.java index 4c216d2487e..eec5ce95962 100644 --- a/spring-core/src/main/java/org/springframework/asm/ModuleVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/ModuleVisitor.java @@ -65,16 +65,16 @@ public abstract class ModuleVisitor { * @param moduleVisitor the module visitor to which this visitor must delegate method calls. May * be null. */ - @SuppressWarnings("deprecation") public ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) { - if (api != Opcodes.ASM7 + if (api != Opcodes.ASM8 + && api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 - && api != Opcodes.ASM8_EXPERIMENTAL) { + && api != Opcodes.ASM9_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } - // SPRING PATCH: no preview mode check for ASM 8 experimental + // SPRING PATCH: no preview mode check for ASM 9 experimental this.api = api; this.mv = moduleVisitor; } diff --git a/spring-core/src/main/java/org/springframework/asm/ModuleWriter.java b/spring-core/src/main/java/org/springframework/asm/ModuleWriter.java index e23e28cac47..81aefa9dc1f 100644 --- a/spring-core/src/main/java/org/springframework/asm/ModuleWriter.java +++ b/spring-core/src/main/java/org/springframework/asm/ModuleWriter.java @@ -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(/* latest api = */ Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM8); this.symbolTable = symbolTable; this.moduleNameIndex = name; this.moduleFlags = access; diff --git a/spring-core/src/main/java/org/springframework/asm/Opcodes.java b/spring-core/src/main/java/org/springframework/asm/Opcodes.java index 21fa7287b21..7d363c327fe 100644 --- a/spring-core/src/main/java/org/springframework/asm/Opcodes.java +++ b/spring-core/src/main/java/org/springframework/asm/Opcodes.java @@ -47,14 +47,14 @@ public interface Opcodes { int ASM5 = 5 << 16 | 0 << 8; int ASM6 = 6 << 16 | 0 << 8; int ASM7 = 7 << 16 | 0 << 8; + int ASM8 = 8 << 16 | 0 << 8; /** * Experimental, use at your own risk. This field will be renamed when it becomes stable, this * will break existing code using it. Only code compiled with --enable-preview can use this. - * - * @deprecated This API is experimental. + *

SPRING PATCH: no preview mode check for ASM 9 experimental, enabling it by default. */ - @Deprecated int ASM8_EXPERIMENTAL = 1 << 24 | 8 << 16 | 0 << 8; + int ASM9_EXPERIMENTAL = 1 << 24 | 9 << 16 | 0 << 8; /* * Internal flags used to redirect calls to deprecated methods. For instance, if a visitOldStuff @@ -323,6 +323,7 @@ public interface Opcodes { // access flags, and also to make sure that these flags are automatically filtered out when // written in class files (because access flags are stored using 16 bits only). + int ACC_RECORD = 0x10000; // class int ACC_DEPRECATED = 0x20000; // class, field, method // Possible values for the type operand of the NEWARRAY instruction. diff --git a/spring-core/src/main/java/org/springframework/asm/RecordComponentVisitor.java b/spring-core/src/main/java/org/springframework/asm/RecordComponentVisitor.java index 0112bd5adbb..60db34c9c58 100644 --- a/spring-core/src/main/java/org/springframework/asm/RecordComponentVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/RecordComponentVisitor.java @@ -34,13 +34,11 @@ package org.springframework.asm; * * @author Remi Forax * @author Eric Bruneton - * @deprecated this API is experimental. */ -@Deprecated public abstract class RecordComponentVisitor { /** * The ASM API version implemented by this visitor. The value of this field must be {@link - * Opcodes#ASM8_EXPERIMENTAL}. + * Opcodes#ASM8}. */ protected final int api; @@ -52,11 +50,8 @@ public abstract class RecordComponentVisitor { /** * Constructs a new {@link RecordComponentVisitor}. * - * @param api the ASM API version implemented by this visitor. Must be {@link - * Opcodes#ASM8_EXPERIMENTAL}. - * @deprecated this API is experimental. + * @param api the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM8}. */ - @Deprecated public RecordComponentVisitor(final int api) { this(api, null); } @@ -64,23 +59,21 @@ public abstract class RecordComponentVisitor { /** * Constructs a new {@link RecordComponentVisitor}. * - * @param api the ASM API version implemented by this visitor. Must be {@link - * Opcodes#ASM8_EXPERIMENTAL}. + * @param api the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM8}. * @param recordComponentVisitor the record component visitor to which this visitor must delegate * method calls. May be null. - * @deprecated this API is experimental. */ - @Deprecated public RecordComponentVisitor( final int api, final RecordComponentVisitor recordComponentVisitor) { - if (api != Opcodes.ASM7 + if (api != Opcodes.ASM8 + && api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 - && api != Opcodes.ASM8_EXPERIMENTAL) { + && api != Opcodes.ASM9_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } - // SPRING PATCH: no preview mode check for ASM 8 experimental + // SPRING PATCH: no preview mode check for ASM 9 experimental this.api = api; this.delegate = recordComponentVisitor; } @@ -89,10 +82,8 @@ public abstract class RecordComponentVisitor { * The record visitor to which this visitor must delegate method calls. May be {@literal null}. * * @return the record visitor to which this visitor must delegate method calls or {@literal null}. - * @deprecated this API is experimental. */ - @Deprecated - public RecordComponentVisitor getDelegateExperimental() { + public RecordComponentVisitor getDelegate() { return delegate; } @@ -103,13 +94,10 @@ public abstract class RecordComponentVisitor { * @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. - * @deprecated this API is experimental. */ - @Deprecated - public AnnotationVisitor visitAnnotationExperimental( - final String descriptor, final boolean visible) { + public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { if (delegate != null) { - return delegate.visitAnnotationExperimental(descriptor, visible); + return delegate.visitAnnotation(descriptor, visible); } return null; } @@ -128,13 +116,11 @@ public abstract class RecordComponentVisitor { * @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. - * @deprecated this API is experimental. */ - @Deprecated - public AnnotationVisitor visitTypeAnnotationExperimental( + public AnnotationVisitor visitTypeAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { if (delegate != null) { - return delegate.visitTypeAnnotationExperimental(typeRef, typePath, descriptor, visible); + return delegate.visitTypeAnnotation(typeRef, typePath, descriptor, visible); } return null; } @@ -143,25 +129,20 @@ public abstract class RecordComponentVisitor { * Visits a non standard attribute of the record component. * * @param attribute an attribute. - * @deprecated this API is experimental. */ - @Deprecated - public void visitAttributeExperimental(final Attribute attribute) { + public void visitAttribute(final Attribute attribute) { if (delegate != null) { - delegate.visitAttributeExperimental(attribute); + delegate.visitAttribute(attribute); } } /** * Visits the end of the record component. This method, which is the last one to be called, is * used to inform the visitor that everything have been visited. - * - * @deprecated this API is experimental. */ - @Deprecated - public void visitEndExperimental() { + public void visitEnd() { if (delegate != null) { - delegate.visitEndExperimental(); + delegate.visitEnd(); } } } diff --git a/spring-core/src/main/java/org/springframework/asm/RecordComponentWriter.java b/spring-core/src/main/java/org/springframework/asm/RecordComponentWriter.java index c775fc4bd8f..98687e60df9 100644 --- a/spring-core/src/main/java/org/springframework/asm/RecordComponentWriter.java +++ b/spring-core/src/main/java/org/springframework/asm/RecordComponentWriter.java @@ -27,19 +27,12 @@ // THE POSSIBILITY OF SUCH DAMAGE. package org.springframework.asm; -@SuppressWarnings("deprecation") final class RecordComponentWriter extends RecordComponentVisitor { /** Where the constants used in this RecordComponentWriter must be stored. */ private final SymbolTable symbolTable; - // Note: fields are ordered as in the component_info structure, and those related to attributes - // are ordered as in Section TODO of the JVMS. - // The field accessFlag doesn't exist in the component_info structure but is used to carry - // ACC_DEPRECATED which is represented by an attribute in the structure and as an access flag by - // ASM. - - /** The access_flags field can only be {@link Opcodes#ACC_DEPRECATED}. */ - private final int accessFlags; + // Note: fields are ordered as in the record_component_info structure, and those related to + // attributes are ordered as in Section 4.7 of the JVMS. /** The name_index field of the Record attribute. */ private final int nameIndex; @@ -82,10 +75,9 @@ final class RecordComponentWriter extends RecordComponentVisitor { * the {@link Attribute#nextAttribute} field. May be {@literal null}. * *

WARNING: this list stores the attributes in the reverse order of their visit. - * firstAttribute is actually the last attribute visited in {@link - * #visitAttributeExperimental(Attribute)}. The {@link #putRecordComponentInfo(ByteVector)} method - * writes the attributes in the order defined by this list, i.e. in the reverse order specified by - * the user. + * firstAttribute is actually the last attribute visited in {@link #visitAttribute(Attribute)}. + * The {@link #putRecordComponentInfo(ByteVector)} method writes the attributes in the order + * defined by this list, i.e. in the reverse order specified by the user. */ private Attribute firstAttribute; @@ -93,20 +85,17 @@ final class RecordComponentWriter extends RecordComponentVisitor { * Constructs a new {@link RecordComponentWriter}. * * @param symbolTable where the constants used in this RecordComponentWriter must be stored. - * @param accessFlags the record component access flags, only synthetic and/or deprecated. * @param name the record component name. * @param descriptor the record component descriptor (see {@link Type}). * @param signature the record component signature. May be {@literal null}. */ RecordComponentWriter( final SymbolTable symbolTable, - final int accessFlags, final String name, final String descriptor, final String signature) { - super(/* latest api = */ Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM8); this.symbolTable = symbolTable; - this.accessFlags = accessFlags; this.nameIndex = symbolTable.addConstantUtf8(name); this.descriptorIndex = symbolTable.addConstantUtf8(descriptor); if (signature != null) { @@ -119,8 +108,7 @@ final class RecordComponentWriter extends RecordComponentVisitor { // ----------------------------------------------------------------------------------------------- @Override - public AnnotationVisitor visitAnnotationExperimental( - final String descriptor, final boolean visible) { + public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { if (visible) { return lastRuntimeVisibleAnnotation = AnnotationWriter.create(symbolTable, descriptor, lastRuntimeVisibleAnnotation); @@ -131,7 +119,7 @@ final class RecordComponentWriter extends RecordComponentVisitor { } @Override - public AnnotationVisitor visitTypeAnnotationExperimental( + public AnnotationVisitor visitTypeAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { if (visible) { return lastRuntimeVisibleTypeAnnotation = @@ -145,14 +133,14 @@ final class RecordComponentWriter extends RecordComponentVisitor { } @Override - public void visitAttributeExperimental(final Attribute attribute) { + public void visitAttribute(final Attribute attribute) { // Store the attributes in the reverse order of their visit by this method. attribute.nextAttribute = firstAttribute; firstAttribute = attribute; } @Override - public void visitEndExperimental() { + public void visitEnd() { // Nothing to do. } @@ -170,9 +158,7 @@ final class RecordComponentWriter extends RecordComponentVisitor { int computeRecordComponentInfoSize() { // name_index, descriptor_index and attributes_count fields use 6 bytes. int size = 6; - size += - Attribute.computeAttributesSize( - symbolTable, accessFlags & Opcodes.ACC_DEPRECATED, signatureIndex); + size += Attribute.computeAttributesSize(symbolTable, 0, signatureIndex); size += AnnotationWriter.computeAnnotationsSize( lastRuntimeVisibleAnnotation, @@ -199,9 +185,6 @@ final class RecordComponentWriter extends RecordComponentVisitor { if (signatureIndex != 0) { ++attributesCount; } - if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) { - ++attributesCount; - } if (lastRuntimeVisibleAnnotation != null) { ++attributesCount; } @@ -218,7 +201,7 @@ final class RecordComponentWriter extends RecordComponentVisitor { attributesCount += firstAttribute.getAttributeCount(); } output.putShort(attributesCount); - Attribute.putAttributes(symbolTable, accessFlags, signatureIndex, output); + Attribute.putAttributes(symbolTable, 0, signatureIndex, output); AnnotationWriter.putAnnotations( symbolTable, lastRuntimeVisibleAnnotation, diff --git a/spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.java b/spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.java index 85972c56075..aa34d8d470d 100644 --- a/spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.java +++ b/spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.java @@ -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 7.x plus minor patches. + * of the ASM bytecode library: currently based on ASM 8.x plus minor patches. * *

See package-level javadocs for more * information on {@code org.springframework.asm}. @@ -31,9 +31,8 @@ public final class SpringAsmInfo { /** * The ASM compatibility version for Spring's ASM visitor implementations: - * currently {@link Opcodes#ASM8_EXPERIMENTAL}, as of Spring Framework 5.2.5. + * currently {@link Opcodes#ASM9_EXPERIMENTAL}, as of Spring Framework 5.3. */ - @SuppressWarnings("deprecation") - public static final int ASM_VERSION = Opcodes.ASM8_EXPERIMENTAL; + public static final int ASM_VERSION = Opcodes.ASM9_EXPERIMENTAL; } diff --git a/spring-core/src/main/java/org/springframework/asm/SymbolTable.java b/spring-core/src/main/java/org/springframework/asm/SymbolTable.java index c2142392d0e..e4c4a8461e7 100644 --- a/spring-core/src/main/java/org/springframework/asm/SymbolTable.java +++ b/spring-core/src/main/java/org/springframework/asm/SymbolTable.java @@ -31,11 +31,11 @@ package org.springframework.asm; * The constant pool entries, the BootstrapMethods attribute entries and the (ASM specific) type * table entries of a class. * + * @author Eric Bruneton * @see JVMS * 4.4 * @see JVMS * 4.7.23 - * @author Eric Bruneton */ final class SymbolTable { @@ -1046,8 +1046,10 @@ final class SymbolTable { // bootstrap methods. We must therefore add the bootstrap method arguments to the constant pool // and BootstrapMethods attribute first, so that the BootstrapMethods attribute is not modified // while adding the given bootstrap method to it, in the rest of this method. - for (Object bootstrapMethodArgument : bootstrapMethodArguments) { - addConstant(bootstrapMethodArgument); + int numBootstrapArguments = bootstrapMethodArguments.length; + int[] bootstrapMethodArgumentIndexes = new int[numBootstrapArguments]; + for (int i = 0; i < numBootstrapArguments; i++) { + bootstrapMethodArgumentIndexes[i] = addConstant(bootstrapMethodArguments[i]).index; } // Write the bootstrap method in the BootstrapMethods table. This is necessary to be able to @@ -1062,10 +1064,10 @@ final class SymbolTable { bootstrapMethodHandle.getDesc(), bootstrapMethodHandle.isInterface()) .index); - int numBootstrapArguments = bootstrapMethodArguments.length; + bootstrapMethodsAttribute.putShort(numBootstrapArguments); - for (Object bootstrapMethodArgument : bootstrapMethodArguments) { - bootstrapMethodsAttribute.putShort(addConstant(bootstrapMethodArgument).index); + for (int i = 0; i < numBootstrapArguments; i++) { + bootstrapMethodsAttribute.putShort(bootstrapMethodArgumentIndexes[i]); } // Compute the length and the hash code of the bootstrap method. diff --git a/spring-core/src/main/java/org/springframework/asm/package-info.java b/spring-core/src/main/java/org/springframework/asm/package-info.java index 85f6ccbfd79..b1ae94438ce 100644 --- a/spring-core/src/main/java/org/springframework/asm/package-info.java +++ b/spring-core/src/main/java/org/springframework/asm/package-info.java @@ -1,6 +1,6 @@ /** * Spring's repackaging of - * ASM 7.0 + * ASM 8.1 * (with Spring-specific patches; for internal use only). * *

This repackaging technique avoids any potential conflicts with