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 }