1 /*
  2  * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 package jdk.internal.classfile;
 26 
 27 import java.io.IOException;
 28 import java.lang.constant.ClassDesc;
 29 import java.nio.file.Files;
 30 import java.nio.file.Path;
 31 import java.util.function.Consumer;
 32 import java.util.function.Function;
 33 
 34 import jdk.internal.classfile.attribute.ModuleAttribute;
 35 import jdk.internal.classfile.attribute.UnknownAttribute;
 36 import jdk.internal.classfile.constantpool.ClassEntry;
 37 import jdk.internal.classfile.constantpool.ConstantPoolBuilder;
 38 import jdk.internal.classfile.constantpool.Utf8Entry;
 39 import jdk.internal.classfile.impl.ClassfileImpl;
 40 import jdk.internal.classfile.impl.TemporaryConstantPool;
 41 import java.lang.reflect.AccessFlag;
 42 import jdk.internal.classfile.attribute.CharacterRangeInfo;
 43 import jdk.internal.classfile.attribute.LocalVariableInfo;
 44 import jdk.internal.classfile.attribute.LocalVariableTypeInfo;
 45 import jdk.internal.classfile.instruction.ExceptionCatch;
 46 import static java.util.Objects.requireNonNull;
 47 
 48 /**
 49  * Represents a context for parsing, transforming, and generating classfiles.
 50  * A {@code Classfile} has a set of options that condition how parsing and
 51  * generation is done.
 52  */
 53 public sealed interface Classfile
 54         permits ClassfileImpl {
 55 
 56     /**
 57      * {@return a context with default options}
 58      */
 59     static Classfile of() {
 60         return ClassfileImpl.DEFAULT_CONTEXT;
 61     }
 62 
 63     /**
 64      * {@return a new context with options altered from the default}
 65      * @param options the desired processing options
 66      */
 67     static Classfile of(Option... options) {
 68         return of().withOptions(options);
 69     }
 70 
 71     /**
 72      * {@return a copy of the context with altered options}
 73      * @param options the desired processing options
 74      */
 75     Classfile withOptions(Option... options);
 76 
 77     /**
 78      * An option that affects the parsing and writing of classfiles.
 79      */
 80     sealed interface Option {
 81     }
 82 
 83     /**
 84      * Option describing attribute mappers for custom attributes.
 85      * Default is only to process standard attributes.
 86      */
 87     sealed interface AttributeMapperOption extends Option
 88             permits ClassfileImpl.AttributeMapperOptionImpl {
 89 
 90         /**
 91          * {@return an option describing attribute mappers for custom attributes}
 92          * @param attributeMapper a function mapping attribute names to attribute mappers
 93          */
 94         static AttributeMapperOption of(Function<Utf8Entry, AttributeMapper<?>> attributeMapper) {
 95             requireNonNull(attributeMapper);
 96             return new ClassfileImpl.AttributeMapperOptionImpl(attributeMapper);
 97         }
 98 
 99         Function<Utf8Entry, AttributeMapper<?>> attributeMapper();
100     }
101 
102     /**
103      * Option describing the class hierarchy resolver to use when generating
104      * stack maps.
105      */
106     sealed interface ClassHierarchyResolverOption extends Option
107             permits ClassfileImpl.ClassHierarchyResolverOptionImpl {
108 
109         /**
110          * {@return an option describing the class hierarchy resolver to use when
111          * generating stack maps}
112          * @param classHierarchyResolver the resolver
113          */
114         static ClassHierarchyResolverOption of(ClassHierarchyResolver classHierarchyResolver) {
115             requireNonNull(classHierarchyResolver);
116             return new ClassfileImpl.ClassHierarchyResolverOptionImpl(classHierarchyResolver);
117         }
118 
119         ClassHierarchyResolver classHierarchyResolver();
120     }
121 
122     /**
123      * Option describing whether to preserve the original constant pool when
124      * transforming a classfile.  Reusing the constant pool enables significant
125      * optimizations in processing time and minimizes differences between the
126      * original and transformed classfile, but may result in a bigger classfile
127      * when a classfile is significantly transformed.
128      * Default is {@code SHARED_POOL} to preserve the original constant
129      * pool.
130      */
131     enum ConstantPoolSharingOption implements Option {
132         SHARED_POOL,
133         NEW_POOL
134     }
135 
136     /**
137      * Option describing whether or not to patch out unreachable code.
138      * Default is {@code PATCH_DEAD_CODE} to automatically patch out unreachable
139      * code with NOPs.
140      */
141     enum DeadCodeOption implements Option {
142         PATCH_DEAD_CODE,
143         KEEP_DEAD_CODE
144     }
145 
146     /**
147      * Option describing whether or not to filter unresolved labels.
148      * Default is {@code FAIL_ON_DEAD_LABELS} to throw IllegalStateException
149      * when any {@link ExceptionCatch}, {@link LocalVariableInfo},
150      * {@link LocalVariableTypeInfo}, or {@link CharacterRangeInfo}
151      * reference to unresolved {@link Label} during bytecode serialization.
152      * Setting this option to {@code DROP_DEAD_LABELS} filters the above
153      * elements instead.
154      */
155     enum DeadLabelsOption implements Option {
156         FAIL_ON_DEAD_LABELS,
157         DROP_DEAD_LABELS
158     }
159 
160     /**
161      * Option describing whether to process or discard debug elements.
162      * Debug elements include the local variable table, local variable type
163      * table, and character range table.  Discarding debug elements may
164      * reduce the overhead of parsing or transforming classfiles.
165      * Default is {@code PASS_DEBUG} to process debug elements.
166      */
167     enum DebugElementsOption implements Option {
168         PASS_DEBUG,
169         DROP_DEBUG
170     }
171 
172     /**
173      * Option describing whether to process or discard line numbers.
174      * Discarding line numbers may reduce the overhead of parsing or transforming
175      * classfiles.
176      * Default is {@code PASS_LINE_NUMBERS} to process line numbers.
177      */
178     enum LineNumbersOption implements Option {
179         PASS_LINE_NUMBERS,
180         DROP_LINE_NUMBERS;
181     }
182 
183     /**
184      * Option describing whether or not to automatically rewrite short jumps to
185      * long when necessary.
186      * Default is {@code FIX_SHORT_JUMPS} to automatically rewrite jump
187      * instructions.
188      */
189     enum ShortJumpsOption implements Option {
190         FIX_SHORT_JUMPS,
191         FAIL_ON_SHORT_JUMPS
192     }
193 
194     /**
195      * Option describing whether or not to generate stackmaps.
196      * Default is {@code STACK_MAPS_WHEN_REQUIRED} to generate stack
197      * maps for {@link #JAVA_6_VERSION} or above, where specifically for
198      * {@link #JAVA_6_VERSION} the stack maps may not be generated.
199      * @jvms 4.10.1 Verification by Type Checking
200      */
201     enum StackMapsOption implements Option {
202         STACK_MAPS_WHEN_REQUIRED,
203         GENERATE_STACK_MAPS,
204         DROP_STACK_MAPS
205     }
206 
207     /**
208      * Option describing whether to process or discard unrecognized attributes.
209      * Default is {@code PASS_UNKNOWN_ATTRIBUTES} to process unrecognized
210      * attributes, and deliver as instances of {@link UnknownAttribute}.
211      */
212     enum UnknownAttributesOption implements Option {
213         PASS_UNKNOWN_ATTRIBUTES,
214         DROP_UNKNOWN_ATTRIBUTES
215     }
216 
217     /**
218      * Parse a classfile into a {@link ClassModel}.
219      * @param bytes the bytes of the classfile
220      * @return the class model
221      */
222     ClassModel parse(byte[] bytes);
223 
224     /**
225      * Parse a classfile into a {@link ClassModel}.
226      * @param path the path to the classfile
227      * @return the class model
228      */
229     default ClassModel parse(Path path) throws IOException {
230         return parse(Files.readAllBytes(path));
231     }
232 
233     /**
234      * Build a classfile into a byte array.
235      * @param thisClass the name of the class to build
236      * @param handler a handler that receives a {@link ClassBuilder}
237      * @return the classfile bytes
238      */
239     default byte[] build(ClassDesc thisClass,
240                          Consumer<? super ClassBuilder> handler) {
241         ConstantPoolBuilder pool = ConstantPoolBuilder.of();
242         return build(pool.classEntry(thisClass), pool, handler);
243     }
244 
245     /**
246      * Build a classfile into a byte array using the provided constant pool
247      * builder.
248      *
249      * @param thisClassEntry the name of the class to build
250      * @param constantPool the constant pool builder
251      * @param handler a handler that receives a {@link ClassBuilder}
252      * @return the classfile bytes
253      */
254     byte[] build(ClassEntry thisClassEntry,
255                  ConstantPoolBuilder constantPool,
256                  Consumer<? super ClassBuilder> handler);
257 
258     /**
259      * Build a classfile into a file.
260      * @param path the path to the file to write
261      * @param thisClass the name of the class to build
262      * @param handler a handler that receives a {@link ClassBuilder}
263      */
264     default void buildTo(Path path,
265                          ClassDesc thisClass,
266                          Consumer<ClassBuilder> handler) throws IOException {
267         Files.write(path, build(thisClass, handler));
268     }
269 
270     /**
271      * Build a classfile into a file using the provided constant pool
272      * builder.
273      *
274      * @param path the path to the file to write
275      * @param thisClassEntry the name of the class to build
276      * @param constantPool the constant pool builder
277      * @param handler a handler that receives a {@link ClassBuilder}
278      */
279     default void buildTo(Path path,
280                          ClassEntry thisClassEntry,
281                          ConstantPoolBuilder constantPool,
282                          Consumer<? super ClassBuilder> handler) throws IOException {
283         Files.write(path, build(thisClassEntry, constantPool, handler));
284     }
285 
286     /**
287      * Build a module descriptor into a byte array.
288      * @param moduleAttribute the {@code Module} attribute
289      * @return the classfile bytes
290      */
291     default byte[] buildModule(ModuleAttribute moduleAttribute) {
292         return buildModule(moduleAttribute, clb -> {});
293     }
294 
295     /**
296      * Build a module descriptor into a byte array.
297      * @param moduleAttribute the {@code Module} attribute
298      * @param handler a handler that receives a {@link ClassBuilder}
299      * @return the classfile bytes
300      */
301     default byte[] buildModule(ModuleAttribute moduleAttribute,
302                                      Consumer<? super ClassBuilder> handler) {
303         return build(ClassDesc.of("module-info"), clb -> {
304             clb.withFlags(AccessFlag.MODULE);
305             clb.with(moduleAttribute);
306             handler.accept(clb);
307         });
308     }
309 
310     /**
311      * Build a module descriptor into a file.
312      * @param path the file to write
313      * @param moduleAttribute the {@code Module} attribute
314      */
315     default void buildModuleTo(Path path,
316                                      ModuleAttribute moduleAttribute) throws IOException {
317         buildModuleTo(path, moduleAttribute, clb -> {});
318     }
319 
320     /**
321      * Build a module descriptor into a file.
322      * @param path the file to write
323      * @param moduleAttribute the {@code Module} attribute
324      * @param handler a handler that receives a {@link ClassBuilder}
325      */
326     default void buildModuleTo(Path path,
327                                      ModuleAttribute moduleAttribute,
328                                      Consumer<? super ClassBuilder> handler) throws IOException {
329         Files.write(path, buildModule(moduleAttribute, handler));
330     }
331 
332     /**
333      * Transform one classfile into a new classfile with the aid of a
334      * {@link ClassTransform}.  The transform will receive each element of
335      * this class, as well as a {@link ClassBuilder} for building the new class.
336      * The transform is free to preserve, remove, or replace elements as it
337      * sees fit.
338      *
339      * @implNote
340      * This method behaves as if:
341      * {@snippet lang=java :
342      *     this.build(model.thisClass(), ConstantPoolBuilder.of(model),
343      *                     b -> b.transform(model, transform));
344      * }
345      *
346      * @param model class model to transform
347      * @param transform the transform
348      * @return the bytes of the new class
349      */
350     default byte[] transform(ClassModel model, ClassTransform transform) {
351         return transform(model, model.thisClass(), transform);
352     }
353 
354     default byte[] transform(ClassModel model, ClassDesc newClassName, ClassTransform transform) {
355         return transform(model, TemporaryConstantPool.INSTANCE.classEntry(newClassName), transform);
356     }
357 
358     byte[] transform(ClassModel model, ClassEntry newClassName, ClassTransform transform);
359 
360     int MAGIC_NUMBER = 0xCAFEBABE;
361 
362     int NOP             = 0;
363     int ACONST_NULL     = 1;
364     int ICONST_M1       = 2;
365     int ICONST_0        = 3;
366     int ICONST_1        = 4;
367     int ICONST_2        = 5;
368     int ICONST_3        = 6;
369     int ICONST_4        = 7;
370     int ICONST_5        = 8;
371     int LCONST_0        = 9;
372     int LCONST_1        = 10;
373     int FCONST_0        = 11;
374     int FCONST_1        = 12;
375     int FCONST_2        = 13;
376     int DCONST_0        = 14;
377     int DCONST_1        = 15;
378     int BIPUSH          = 16;
379     int SIPUSH          = 17;
380     int LDC             = 18;
381     int LDC_W           = 19;
382     int LDC2_W          = 20;
383     int ILOAD           = 21;
384     int LLOAD           = 22;
385     int FLOAD           = 23;
386     int DLOAD           = 24;
387     int ALOAD           = 25;
388     int ILOAD_0         = 26;
389     int ILOAD_1         = 27;
390     int ILOAD_2         = 28;
391     int ILOAD_3         = 29;
392     int LLOAD_0         = 30;
393     int LLOAD_1         = 31;
394     int LLOAD_2         = 32;
395     int LLOAD_3         = 33;
396     int FLOAD_0         = 34;
397     int FLOAD_1         = 35;
398     int FLOAD_2         = 36;
399     int FLOAD_3         = 37;
400     int DLOAD_0         = 38;
401     int DLOAD_1         = 39;
402     int DLOAD_2         = 40;
403     int DLOAD_3         = 41;
404     int ALOAD_0         = 42;
405     int ALOAD_1         = 43;
406     int ALOAD_2         = 44;
407     int ALOAD_3         = 45;
408     int IALOAD          = 46;
409     int LALOAD          = 47;
410     int FALOAD          = 48;
411     int DALOAD          = 49;
412     int AALOAD          = 50;
413     int BALOAD          = 51;
414     int CALOAD          = 52;
415     int SALOAD          = 53;
416     int ISTORE          = 54;
417     int LSTORE          = 55;
418     int FSTORE          = 56;
419     int DSTORE          = 57;
420     int ASTORE          = 58;
421     int ISTORE_0        = 59;
422     int ISTORE_1        = 60;
423     int ISTORE_2        = 61;
424     int ISTORE_3        = 62;
425     int LSTORE_0        = 63;
426     int LSTORE_1        = 64;
427     int LSTORE_2        = 65;
428     int LSTORE_3        = 66;
429     int FSTORE_0        = 67;
430     int FSTORE_1        = 68;
431     int FSTORE_2        = 69;
432     int FSTORE_3        = 70;
433     int DSTORE_0        = 71;
434     int DSTORE_1        = 72;
435     int DSTORE_2        = 73;
436     int DSTORE_3        = 74;
437     int ASTORE_0        = 75;
438     int ASTORE_1        = 76;
439     int ASTORE_2        = 77;
440     int ASTORE_3        = 78;
441     int IASTORE         = 79;
442     int LASTORE         = 80;
443     int FASTORE         = 81;
444     int DASTORE         = 82;
445     int AASTORE         = 83;
446     int BASTORE         = 84;
447     int CASTORE         = 85;
448     int SASTORE         = 86;
449     int POP             = 87;
450     int POP2            = 88;
451     int DUP             = 89;
452     int DUP_X1          = 90;
453     int DUP_X2          = 91;
454     int DUP2            = 92;
455     int DUP2_X1         = 93;
456     int DUP2_X2         = 94;
457     int SWAP            = 95;
458     int IADD            = 96;
459     int LADD            = 97;
460     int FADD            = 98;
461     int DADD            = 99;
462     int ISUB            = 100;
463     int LSUB            = 101;
464     int FSUB            = 102;
465     int DSUB            = 103;
466     int IMUL            = 104;
467     int LMUL            = 105;
468     int FMUL            = 106;
469     int DMUL            = 107;
470     int IDIV            = 108;
471     int LDIV            = 109;
472     int FDIV            = 110;
473     int DDIV            = 111;
474     int IREM            = 112;
475     int LREM            = 113;
476     int FREM            = 114;
477     int DREM            = 115;
478     int INEG            = 116;
479     int LNEG            = 117;
480     int FNEG            = 118;
481     int DNEG            = 119;
482     int ISHL            = 120;
483     int LSHL            = 121;
484     int ISHR            = 122;
485     int LSHR            = 123;
486     int IUSHR           = 124;
487     int LUSHR           = 125;
488     int IAND            = 126;
489     int LAND            = 127;
490     int IOR             = 128;
491     int LOR             = 129;
492     int IXOR            = 130;
493     int LXOR            = 131;
494     int IINC            = 132;
495     int I2L             = 133;
496     int I2F             = 134;
497     int I2D             = 135;
498     int L2I             = 136;
499     int L2F             = 137;
500     int L2D             = 138;
501     int F2I             = 139;
502     int F2L             = 140;
503     int F2D             = 141;
504     int D2I             = 142;
505     int D2L             = 143;
506     int D2F             = 144;
507     int I2B             = 145;
508     int I2C             = 146;
509     int I2S             = 147;
510     int LCMP            = 148;
511     int FCMPL           = 149;
512     int FCMPG           = 150;
513     int DCMPL           = 151;
514     int DCMPG           = 152;
515     int IFEQ            = 153;
516     int IFNE            = 154;
517     int IFLT            = 155;
518     int IFGE            = 156;
519     int IFGT            = 157;
520     int IFLE            = 158;
521     int IF_ICMPEQ       = 159;
522     int IF_ICMPNE       = 160;
523     int IF_ICMPLT       = 161;
524     int IF_ICMPGE       = 162;
525     int IF_ICMPGT       = 163;
526     int IF_ICMPLE       = 164;
527     int IF_ACMPEQ       = 165;
528     int IF_ACMPNE       = 166;
529     int GOTO            = 167;
530     int JSR             = 168;
531     int RET             = 169;
532     int TABLESWITCH     = 170;
533     int LOOKUPSWITCH    = 171;
534     int IRETURN         = 172;
535     int LRETURN         = 173;
536     int FRETURN         = 174;
537     int DRETURN         = 175;
538     int ARETURN         = 176;
539     int RETURN          = 177;
540     int GETSTATIC       = 178;
541     int PUTSTATIC       = 179;
542     int GETFIELD        = 180;
543     int PUTFIELD        = 181;
544     int INVOKEVIRTUAL   = 182;
545     int INVOKESPECIAL   = 183;
546     int INVOKESTATIC    = 184;
547     int INVOKEINTERFACE = 185;
548     int INVOKEDYNAMIC   = 186;
549     int NEW             = 187;
550     int NEWARRAY        = 188;
551     int ANEWARRAY       = 189;
552     int ARRAYLENGTH     = 190;
553     int ATHROW          = 191;
554     int CHECKCAST       = 192;
555     int INSTANCEOF      = 193;
556     int MONITORENTER    = 194;
557     int MONITOREXIT     = 195;
558     int WIDE            = 196;
559     int MULTIANEWARRAY  = 197;
560     int IFNULL          = 198;
561     int IFNONNULL       = 199;
562     int GOTO_W          = 200;
563     int JSR_W           = 201;
564 
565     int ACC_PUBLIC = 0x0001;
566     int ACC_PROTECTED = 0x0004;
567     int ACC_PRIVATE = 0x0002;
568     int ACC_INTERFACE = 0x0200;
569     int ACC_ENUM = 0x4000;
570     int ACC_ANNOTATION = 0x2000;
571     int ACC_SUPER = 0x0020;
572     int ACC_ABSTRACT = 0x0400;
573     int ACC_VOLATILE = 0x0040;
574     int ACC_TRANSIENT = 0x0080;
575     int ACC_SYNTHETIC = 0x1000;
576     int ACC_STATIC = 0x0008;
577     int ACC_FINAL = 0x0010;
578     int ACC_SYNCHRONIZED = 0x0020;
579     int ACC_BRIDGE = 0x0040;
580     int ACC_VARARGS = 0x0080;
581     int ACC_NATIVE = 0x0100;
582     int ACC_STRICT = 0x0800;
583     int ACC_MODULE = 0x8000;
584     int ACC_OPEN = 0x20;
585     int ACC_MANDATED = 0x8000;
586     int ACC_TRANSITIVE = 0x20;
587     int ACC_STATIC_PHASE = 0x40;
588 
589     int CRT_STATEMENT       = 0x0001;
590     int CRT_BLOCK           = 0x0002;
591     int CRT_ASSIGNMENT      = 0x0004;
592     int CRT_FLOW_CONTROLLER = 0x0008;
593     int CRT_FLOW_TARGET     = 0x0010;
594     int CRT_INVOKE          = 0x0020;
595     int CRT_CREATE          = 0x0040;
596     int CRT_BRANCH_TRUE     = 0x0080;
597     int CRT_BRANCH_FALSE    = 0x0100;
598 
599     int TAG_CLASS = 7;
600     int TAG_CONSTANTDYNAMIC = 17;
601     int TAG_DOUBLE = 6;
602     int TAG_FIELDREF = 9;
603     int TAG_FLOAT = 4;
604     int TAG_INTEGER = 3;
605     int TAG_INTERFACEMETHODREF = 11;
606     int TAG_INVOKEDYNAMIC = 18;
607     int TAG_LONG = 5;
608     int TAG_METHODHANDLE = 15;
609     int TAG_METHODREF = 10;
610     int TAG_METHODTYPE = 16;
611     int TAG_MODULE = 19;
612     int TAG_NAMEANDTYPE = 12;
613     int TAG_PACKAGE = 20;
614     int TAG_STRING = 8;
615     int TAG_UNICODE = 2;
616     int TAG_UTF8 = 1;
617 
618     // annotation element values
619     char AEV_BYTE = 'B';
620     char AEV_CHAR = 'C';
621     char AEV_DOUBLE = 'D';
622     char AEV_FLOAT = 'F';
623     char AEV_INT = 'I';
624     char AEV_LONG = 'J';
625     char AEV_SHORT = 'S';
626     char AEV_BOOLEAN = 'Z';
627     char AEV_STRING = 's';
628     char AEV_ENUM = 'e';
629     char AEV_CLASS = 'c';
630     char AEV_ANNOTATION = '@';
631     char AEV_ARRAY = '[';
632 
633     //type annotations
634     int TAT_CLASS_TYPE_PARAMETER = 0x00;
635     int TAT_METHOD_TYPE_PARAMETER = 0x01;
636     int TAT_CLASS_EXTENDS = 0x10;
637     int TAT_CLASS_TYPE_PARAMETER_BOUND = 0x11;
638     int TAT_METHOD_TYPE_PARAMETER_BOUND = 0x12;
639     int TAT_FIELD = 0x13;
640     int TAT_METHOD_RETURN = 0x14;
641     int TAT_METHOD_RECEIVER = 0x15;
642     int TAT_METHOD_FORMAL_PARAMETER = 0x16;
643     int TAT_THROWS = 0x17;
644     int TAT_LOCAL_VARIABLE = 0x40;
645     int TAT_RESOURCE_VARIABLE = 0x41;
646     int TAT_EXCEPTION_PARAMETER = 0x42;
647     int TAT_INSTANCEOF = 0x43;
648     int TAT_NEW = 0x44;
649     int TAT_CONSTRUCTOR_REFERENCE = 0x45;
650     int TAT_METHOD_REFERENCE = 0x46;
651     int TAT_CAST = 0x47;
652     int TAT_CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
653     int TAT_METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
654     int TAT_CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
655     int TAT_METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
656 
657     //stackmap verification types
658     int VT_TOP = 0;
659     int VT_INTEGER = 1;
660     int VT_FLOAT = 2;
661     int VT_DOUBLE = 3;
662     int VT_LONG = 4;
663     int VT_NULL = 5;
664     int VT_UNINITIALIZED_THIS = 6;
665     int VT_OBJECT = 7;
666     int VT_UNINITIALIZED = 8;
667 
668     int DEFAULT_CLASS_FLAGS = ACC_PUBLIC;
669 
670     int JAVA_1_VERSION = 45;
671     int JAVA_2_VERSION = 46;
672     int JAVA_3_VERSION = 47;
673     int JAVA_4_VERSION = 48;
674     int JAVA_5_VERSION = 49;
675     int JAVA_6_VERSION = 50;
676     int JAVA_7_VERSION = 51;
677     int JAVA_8_VERSION = 52;
678     int JAVA_9_VERSION = 53;
679     int JAVA_10_VERSION = 54;
680     int JAVA_11_VERSION = 55;
681     int JAVA_12_VERSION = 56;
682     int JAVA_13_VERSION = 57;
683     int JAVA_14_VERSION = 58;
684     int JAVA_15_VERSION = 59;
685     int JAVA_16_VERSION = 60;
686     int JAVA_17_VERSION = 61;
687     int JAVA_18_VERSION = 62;
688     int JAVA_19_VERSION = 63;
689     int JAVA_20_VERSION = 64;
690     int JAVA_21_VERSION = 65;
691     int JAVA_22_VERSION = 66;
692 
693     /**
694      * A minor version number indicating a class uses preview features
695      * of a Java SE version since 12, for major versions {@value
696      * #JAVA_12_VERSION} and above.
697      */
698     int PREVIEW_MINOR_VERSION = 65535;
699 
700     static int latestMajorVersion() {
701         return JAVA_22_VERSION;
702     }
703 
704     static int latestMinorVersion() {
705         return 0;
706     }
707 
708 }