001package Torello.Java.Additional; 002 003import Torello.Java.FileRW; 004import Torello.Java.LFEC; 005import Torello.Java.Additional.Ret2; 006import Torello.Java.ReadOnly.ReadOnlyList; 007 008import Torello.JavaDoc.CSSLinks; 009import Torello.JavaDoc.LinkJavaSource; 010 011import java.util.stream.Stream; 012import java.util.Objects; 013 014import static Torello.Java.C.BCYAN; 015import static Torello.Java.C.RESET; 016import static Torello.JavaDoc.Entity.FIELD; 017 018/** 019 * A Data-Class for representing a Java {@code '.class'} File's Constant-Pool. 020 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_TOP_TABLE> 021 */ 022public class ConstantPool 023{ 024 // ******************************************************************************************** 025 // ******************************************************************************************** 026 // Static Inner Class: Reference 027 // ******************************************************************************************** 028 // ******************************************************************************************** 029 030 031 /** 032 * A Data-Class which can represent: 033 * 034 * <BR /><BR /><UL CLASS=JDUL> 035 * <LI><B>{@link TAG_FIELD_REF}</B> (9)</LI> 036 * <LI><B>{@link TAG_METHOD_REF}</B> (10)</LI> 037 * <LI><B>{@link TAG_INTERFACE_METHOD_REF}</B> (11)</LI> 038 * </UL> 039 * 040 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_REF_CGPT_DESC> 041 */ 042 @CSSLinks(FileNames="ConstantPool.css") 043 public static class Reference 044 { 045 // **************************************************************************************** 046 // **************************************************************************************** 047 // Instance Fields 048 // **************************************************************************************** 049 // **************************************************************************************** 050 051 052 /** The Constant-Pool Table-Index where this {@code Reference} is located */ 053 public final int tableIndex; 054 055 /** 056 * The Constant-Pool Tg-Kind associated with this instance. This Java {@code 'byte'} may 057 * take only one of only three values: 058 * 059 * <BR /><BR /><UL CLASS=JDUL> 060 * <LI><B>{@link TAG_FIELD_REF}</B> (9)</LI> 061 * <LI><B>{@link TAG_METHOD_REF}</B> (10)</LI> 062 * <LI><B>{@link TAG_INTERFACE_METHOD_REF}</B> (11)</LI> 063 * </UL> 064 * 065 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_IN_TYPE_TAG_NOTE> 066 */ 067 public final byte tag; 068 069 /** 070 * The {@code 'className'} field specifies in which class (where) the Method or Field has 071 * actuallly been defined. For most methods and fields, the {@code 'className'} is the 072 * same as the actual class whose Constant-Pool was loaded into an instance of 073 * {@code ConstantPool}. 074 * 075 * <BR /><BR />If the field or method reference is defined in an ancestor or parent class, 076 * then this field would contain the name of that ancestor. 077 */ 078 public final String ownerClassName; 079 080 /** 081 * Constant-Pool Table-Index where owner's {@code className 'Class Constant'} was 082 * stored 083 */ 084 public final int ownerClassIndex; 085 086 /** 087 * Constant-Pool Table-Index identifying where the {@code UTF-8} Class' 088 * <B STYLE='color; red;'>Name-As-A-{@code String}</B> is located. 089 */ 090 public final int ownerClassNameUTF8Index; 091 092 /** 093 * An intermediate Constant-Pool Index-Pair that points to a Name UTF-8 Constant, and 094 * a Type-Descriptor Constant. 095 */ 096 public final int nameAndTypeIndex; 097 098 /** 099 * This is just the name of the Method or Field. Some common method names are (just for 100 * example) {@cpde 'toString'} and {@code 'equals'}. This particular Nested-Type has three 101 * fields of it's own, named: {@code 'className, 'name'} and {@code 'descriptor'}. 102 */ 103 public final String name; 104 105 /** 106 * Constant-Pool Table-Index identifying where the {@code UTF-8} Method's or Field's 107 * <B STYLE='color; red;'>Name-As-A-{@code String}</B> is located. 108 */ 109 public final int nameUTF8Index; 110 111 /** 112 * This is the descriptor of a method or field, which is Java single-line description 113 * which includes type-information stored as a simple {@code String}. A descriptor is of 114 * the format: 115 * 116 * <BR /><BR /><UL CLASS=JDUL> 117 * <LI>For a method, the descriptor specifies the parameter types and return type.</LI> 118 * <LI>For a field, the descriptor specifies the field type.</LI> 119 * </UL> 120 */ 121 public final String descriptor; 122 123 /** 124 * Constant-Pool Table-Index identifying where the {@code UTF-8} Descriptor's 125 * <B STYLE='color; red;'>Description-As-A-{@code String}</B> is located. 126 */ 127 public final int descriptorUTF8Index; 128 129 130 // **************************************************************************************** 131 // **************************************************************************************** 132 // Package-Private Constructor 133 // **************************************************************************************** 134 // **************************************************************************************** 135 136 137 Reference( 138 final ReadOnlyList<Byte> tags, 139 final ReadOnlyList<Object> values, 140 final int tableIndex 141 ) 142 { 143 this.tableIndex = tableIndex; 144 145 // May only be one of three values: TAG_FIELD_REF, TAG_METHOD_REF or 146 // TAG_INTERFACE_METHOD_REF 147 // 148 // public final byte tag; 149 150 this.tag = tags.get(tableIndex); 151 152 // temporary variable 153 @SuppressWarnings("unchecked") 154 final Ret2<Integer, Integer> methodOrFieldConstantR2 = 155 (Ret2<Integer, Integer>) values.get(tableIndex); 156 157 this.ownerClassIndex = methodOrFieldConstantR2.a; 158 159 160 // Constant-Pool Table-Index identifying where the UTF-8 Class' 161 // Name-As-A-String is located. 162 // 163 // public final byte ownerClassNameUTF8Index; 164 165 this.ownerClassNameUTF8Index = (Integer) values.get(Reference.this.ownerClassIndex); 166 167 168 // The 'className' field specifies in which class (where) the Method or Field has 169 // actuallly been defined. 170 // 171 // If the field or method reference is defined in an ancestor or parent class, 172 // then this field would contain the name of that ancestor. 173 // 174 // public final String ownerClassName; 175 176 this.ownerClassName = (String) values.get(this.ownerClassNameUTF8Index); 177 178 // public final int nameAndTyeIndex; 179 this.nameAndTypeIndex = methodOrFieldConstantR2.b; 180 181 // Temporary Local Variable 182 @SuppressWarnings("unchecked") 183 final Ret2<Integer, Integer> nameAndTypeConstantR2 = 184 (Ret2<Integer, Integer>) values.get(methodOrFieldConstantR2.b); 185 186 187 // Constant-Pool Table-Index identifying where the UTF-8 Method's or Field's 188 // Name-As-A-String is located. 189 // 190 // public final byte nameUTF8Index; 191 192 this.nameUTF8Index = nameAndTypeConstantR2.a; 193 194 195 // This is just the name of the Method or Field. Some common method names are (for 196 // example) 'toString' and 'equals'. This particular Nested-Type has three fields of 197 // it's own, named: 'className, 'name' and 'descriptor'. 198 // 199 // public final String name; 200 201 this.name = (String) values.get(this.nameUTF8Index); 202 203 204 // Constant-Pool Table-Index identifying where the UTF-8 Descriptor's 205 // Description-As-A-String is located. 206 // 207 // public final byte descriptorUTF8Index; 208 209 this.descriptorUTF8Index = nameAndTypeConstantR2.b; 210 211 212 // This is the descriptor of a method or field. A descriptor is of the format: 213 // * For a method, the descriptor specifies the parameter types and return type. 214 // * For a field, the descriptor specifies the field type. 215 // 216 // public final String descriptor; 217 218 this.descriptor = (String) values.get(this.descriptorUTF8Index); 219 } 220 221 222 // **************************************************************************************** 223 // **************************************************************************************** 224 // java.lang.Object 225 // **************************************************************************************** 226 // **************************************************************************************** 227 228 229 /** 230 * Converts {@cpode 'this'} instance into a {@code java.lang.String}. 231 * @return The data-content of this record, as a {@code String}, for printing. 232 */ 233 public final String toString() 234 { 235 return 236 "Reference:\n" + 237 "{\n" + 238 " tag: " + tag + " - " + ConstantPool.tagNames.get(tag) + '\n' + 239 " Table-Index: " + this.tableIndex + '\n' + 240 " ownerClassName: " + this.ownerClassName + '\n' + 241 " name: " + this.name + '\n' + 242 " descriptor: " + this.descriptor + '\n' + 243 "}"; 244 } 245 246 /** 247 * Checks for {@code Object}-equality between {@code 'this'} instance and {@code 'other'}. 248 * 249 * @param other This may be any Java-{@code Object}, but only an instance of 250 * {@code ConstantPool.Reference} will permit this method to return {@code TRUE}. 251 * 252 * @return {@code TRUE} if-and-only-if parameter {@code 'other'} is an instance of 253 * {@code Reference} and has identical field values. 254 */ 255 public boolean equals(Object other) 256 { 257 if (!(other instanceof Reference)) return false; 258 259 Reference r = (Reference) other; 260 261 return 262 (this.tag == r.tag) 263 264 && Objects.equals(this.ownerClassName, r.ownerClassName) 265 && (this.ownerClassIndex == r.ownerClassIndex) 266 && (this.ownerClassNameUTF8Index == r.ownerClassNameUTF8Index) 267 268 && Objects.equals(this.name, r.name) 269 && (this.nameUTF8Index == r.nameUTF8Index) 270 271 && Objects.equals(this.descriptor, r.descriptor) 272 && (this.descriptorUTF8Index == r.descriptorUTF8Index); 273 } 274 275 /** 276 * Generates a Hash-Code. 277 * @return An integer Hash-Code that may be used by Java's Hashing Data-Structures. 278 */ 279 public int hashCode() 280 { 281 return this.name.hashCode() + 282 this.ownerClassNameUTF8Index + 283 this.nameUTF8Index + 284 this.descriptorUTF8Index; 285 } 286 } 287 288 289 // ******************************************************************************************** 290 // ******************************************************************************************** 291 // Static Inner Class: Reference 292 // ******************************************************************************************** 293 // ******************************************************************************************** 294 295 296 /** 297 * A class representing the "Reference-Kind" values associated with a {@code Method-Handle}. 298 * 299 * <p>Method-Handles use "Reference-Kinds" to describe the type of operation they perform, 300 * such as accessing fields or invoking methods.</p> 301 */ 302 @CSSLinks(FileNames="ConstantPool.css") 303 public static class MethodHandle 304 { 305 // **************************************************************************************** 306 // **************************************************************************************** 307 // Instance Fields 308 // **************************************************************************************** 309 // **************************************************************************************** 310 311 312 /** The Constant-Pool Table-Index where this {@code Method-Handle} is located */ 313 public final int tableIndex; 314 315 /** 316 * Contains a Java {@code byte}. Guaranteed to be equal to one of the 9 {@code static} 317 * {@code byte}-Constant Fields (the various "kinds"). 318 * 319 * <BR /><BR />The complete list of <CODE>Method Handle</CODE> 'kinds' may be viewed in 320 * the documentation for the {@code static} field {@link #handleKindNames}. The table in 321 * the javadoc Documentation-Table there contains 'stringified' versions of all of the 322 * {@code static} 'kind' {@code byte} constants also provided in this class. 323 */ 324 public final byte kind; 325 326 /** 327 * Points to a Constant in the Constant-Pool Table. This Index-Pointer must be a pointer 328 * to one of the following: 329 * {@link #TAG_FIELD_REF Field-Reference}, 330 * {@link #TAG_METHOD_REF Method-Reference} or a 331 * {@link #TAG_INTERFACE_METHOD_REF Interface-Method-Reference} 332 */ 333 public final int referencedIndex; 334 335 /** 336 * This contains the actual Tag-Kind (as a Java {@code byte}) of the Reference to which 337 * this handle points. This particular field may hold only one of three different values: 338 * <B> 339 * {@link #TAG_FIELD_REF 9}, 340 * {@link #TAG_METHOD_REF 10} or 341 * {@link #TAG_INTERFACE_METHOD_REF 11} 342 * </B> 343 */ 344 public final byte referencedTagKind; 345 346 /** The name of the method or field to which this reference points, as a {@code String} */ 347 public final String referencedName; 348 349 350 // **************************************************************************************** 351 // **************************************************************************************** 352 // Static, Final Fields: The 9 different Method-Handle "Kinds" 353 // **************************************************************************************** 354 // **************************************************************************************** 355 356 357 /** 358 * Reference-Kind value for {@code getField}. 359 * Used to retrieve an instance field from an object. 360 */ 361 public static final byte KIND_GET_FIELD = 1; 362 363 /** 364 * Reference-Kind value for {@code getStatic}. 365 * Used to retrieve a static field from a class. 366 */ 367 public static final byte KIND_GET_STATIC = 2; 368 369 /** 370 * Reference-Kind value for {@code putField}. 371 * Used to assign a value to an instance field. 372 */ 373 public static final byte KIND_PUT_FIELD = 3; 374 375 /** 376 * Reference-Kind value for {@code putStatic}. 377 * Used to assign a value to a static field. 378 */ 379 public static final byte KIND_PUT_STATIC = 4; 380 381 /** 382 * Reference-Kind value for {@code invokeVirtual}. 383 * Used to invoke an instance method via virtual dispatch. 384 */ 385 public static final byte KIND_INVOKE_VIRTUAL = 5; 386 387 /** 388 * Reference-Kind value for {@code invokeStatic}. 389 * Used to invoke a static method. 390 */ 391 public static final byte KIND_INVOKE_STATIC = 6; 392 393 /** 394 * Reference-Kind value for {@code invokeSpecial}. 395 * Used to invoke an instance method directly (e.g., via {@code super} calls). 396 */ 397 public static final byte KIND_INVOKE_SPECIAL = 7; 398 399 /** 400 * Reference-Kind value for {@code newInvokeSpecial}. 401 * Used to invoke a class constructor. 402 */ 403 public static final byte KIND_NEW_INVOKE_SPECIAL = 8; 404 405 /** 406 * Reference-Kind value for {@code invokeInterface}. 407 * Used to invoke a method declared in an interface. 408 */ 409 public static final byte KIND_INVOKE_INTERFACE = 9; 410 411 412 // **************************************************************************************** 413 // **************************************************************************************** 414 // Static, Final Fields: Lookup Table 415 // **************************************************************************************** 416 // **************************************************************************************** 417 418 419 /** 420 * This list is contains exactly 9 non-null entries. Each entry in this list corresponds 421 * to one of the 9 Handle "Kind's" 422 * 423 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_MH_KIND_NAMES> 424 */ 425 @SuppressWarnings("unchecked") 426 @LinkJavaSource(handle="MethodHandleData") 427 public static final ReadOnlyList<String> handleKindNames = 428 (ReadOnlyList<String>) LFEC.readObjectFromFile_JAR 429 (ConstantPool.class, "data-files/data5.roaldat", true, ReadOnlyList.class); 430 431 432 // **************************************************************************************** 433 // **************************************************************************************** 434 // Package-Private Constructor 435 // **************************************************************************************** 436 // **************************************************************************************** 437 438 439 MethodHandle( 440 final ReadOnlyList<Byte> tags, 441 final ReadOnlyList<Object> values, 442 final int tableIndex 443 ) 444 { 445 // The Constant-Pool Table-Index where this Method-Handle is located 446 // public final int tableIndex; 447 448 this.tableIndex = tableIndex; 449 450 451 @SuppressWarnings("unchecked") 452 final Ret2<Byte, Integer> methHandleR2 = 453 (Ret2<Byte, Integer>) values.get(tableIndex); 454 455 456 // Contains a Java byte. Guaranteed to be equal to one of the 9 static 457 // byte-Constant Fields (the various "kinds"), listed in this class. 458 // 459 // public final byte kind; 460 461 this.kind = methHandleR2.a; 462 463 464 // Points to a Constant in the Constant-Pool Table. This Index-Pointer must be a pointer 465 // to one of the following: TAG_FIELD_REF, TAG_METHOD_REF, TAG_INTERFACE_METHD_REF 466 // 467 // public final int referencedIndex; 468 469 this.referencedIndex = methHandleR2.b; 470 471 472 // This contains the actual Tag-Kind (as a Java byte) of the Reference to which 473 // this handle points. This particular field may hold only one of three different values: 474 // TAG_FIELD_REF, TAG_METHOD_REF, TAG_INTERFACE_METHD_REF 475 // 476 // public final byte referencedTagKind; 477 478 this.referencedTagKind = tags.get(this.referencedIndex); 479 480 @SuppressWarnings("unchecked") 481 final Ret2<Integer, Integer> referenceR2 = (Ret2<Integer, Integer>) 482 values.get(this.referencedIndex); 483 484 @SuppressWarnings("unchecked") 485 final Ret2<Integer, Integer> nameAndTypeR2 = 486 (Ret2<Integer, Integer>) values.get(referenceR2.b); 487 488 489 // The name of the method or field to which this reference points, as a String 490 // public final String referencedName; 491 492 this.referencedName = (String) values.get(nameAndTypeR2.a); 493 } 494 495 496 // **************************************************************************************** 497 // **************************************************************************************** 498 // java.lang.Object 499 // **************************************************************************************** 500 // **************************************************************************************** 501 502 503 /** 504 * Checks for {@code Object}-equality between {@code 'this'} instance and {@code 'other'}. 505 * 506 * @param other This may be any Java-{@code Object}, but only an instance of 507 * {@code ConstantPool.MethodHandle} will permit this method to return {@code TRUE}. 508 * 509 * @return {@code TRUE} if-and-only-if parameter {@code 'other'} is an instance of 510 * {@code MethodHandle} and has identical field values. 511 */ 512 public boolean equals(Object other) 513 { 514 if (! (other instanceof MethodHandle)) return false; 515 516 final MethodHandle o = (MethodHandle) other; 517 518 return 519 (this.tableIndex == o.tableIndex) 520 && (this.kind == o.kind) 521 && (this.referencedIndex == o.referencedIndex) 522 && (this.referencedTagKind == o.referencedTagKind) 523 && Objects.equals(this.referencedName, o.referencedName); 524 } 525 526 /** 527 * Generates a hash-code. Fulfills Java's Hash-Code reuirement. 528 * @return a good attempt at an efficient, but fair hashcode. 529 */ 530 public int hashCode() 531 { return this.tableIndex + this.kind + this.referencedIndex; } 532 533 /** 534 * Generate a human readable {@code String}. 535 * @return {@code 'this'} instance as a Java String 536 */ 537 public String toString() 538 { 539 return 540 "Method Handle:\n" + 541 "{\n" + 542 " Handle's Table-Index: " + this.tableIndex + '\n' + 543 " Referenced Item's Name: " + this.referencedName + '\n' + 544 " Handle Kind: " + this.kind + '\n' + 545 546 " Handle Kind's Name: " + 547 MethodHandle.handleKindNames.get(this.kind) + '\n' + 548 549 " Referenced Item's Table-Index: " + this.referencedIndex + '\n' + 550 " Referenced Item's Kind (as byte): " + this.referencedTagKind + '\n' + 551 552 " Referenced Item's Kind (as String): " + 553 ConstantPool.tagNames.get(this.referencedTagKind) + '\n' + 554 "}"; 555 } 556 } 557 558 559 // ******************************************************************************************** 560 // ******************************************************************************************** 561 // Static Inner Class: Dynamic 562 // ******************************************************************************************** 563 // ******************************************************************************************** 564 565 566 /** 567 * Used to represent Java {@code '.class'} File Constant's whose Tag-Kind is: 568 * 569 * <BR /><BR /><UL CLASS=JDUL> 570 * <LI><B>{@link #TAG_DYNAMIC}</B> ({@code 17})</LI> 571 * <LI><B>{@link #TAG_INVOKE_DYNAMIC}</B> ({@code 18})</LI> 572 * </UL> 573 */ 574 public static class Dynamic 575 { 576 // **************************************************************************************** 577 // **************************************************************************************** 578 // Instance Fields 579 // **************************************************************************************** 580 // **************************************************************************************** 581 582 583 /** The Constant-Pool Table-Index where this {@code Reference} is located */ 584 public final int tableIndex; 585 586 /** 587 * The Constant-Pool Tg-Kind associated with this instance. This Java {@code 'byte'} may 588 * take one of only two values: 589 * 590 * <BR /><BR /><UL CLASS=JDUL> 591 * <LI><B>{@link #TAG_DYNAMIC}</B> ({@code 17})</LI> 592 * <LI><B>{@link #TAG_INVOKE_DYNAMIC}</B> ({@code 18})</LI> 593 * </UL> 594 * 595 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_IN_TYPE_TAG_NOTE> 596 */ 597 public final byte tag; 598 599 /** 600 * This field will be assigned {@code TRUE} if-and-only-if field {@link #tag} has been 601 * assigned <B>{@code 17}</B>. Tthe only other value which may be assigned to field 602 * {@link #tag} is <B>{@code 18}</B>, when that field is equal to <B>{@code 18}</B>, this 603 * field be {@code FALSE}. 604 * 605 * <BR /><BR />{@code boolean} fields such as this are here purely to make life easier, 606 * occasionally. 607 */ 608 public final boolean dynamicOrInvokeDynamic; 609 610 /** 611 * The index into the Bootstrap Method Table, pointing to a bootstrap method 612 * definition in the `.class` file attributes. 613 */ 614 public final int bootstrapMethodIndex; 615 616 /** 617 * The index into the constant pool, pointing to a {@link #TAG_NAME_AND_TYPE} 618 * Record / Structure that provides the name and type descriptor of this entry. 619 * 620 * <BR /><BR />The Constant-Pool entry that is stored in the Table-Index specified by 621 * the integer in {@code 'nameAndTypeIndex'} is actually a 4 Byte Integer-Pair. The two 622 * integers that comprise a "Name And Type" Constant (a "record" or "Structure") are simply 623 * two Index-Pointers back into the Constant-Pool's Table. 624 * 625 * <BR /><BR />The first Index-Pointer is to a {@code UTF-8 String} storing the "name" of 626 * for the Method of the Method-Handle. The second Index-Poniter points to a Table-Index 627 * which contains the Method-Type - also stored as a {@code UTF-8 String}. 628 */ 629 public final int nameAndTypeIndex; 630 631 /** 632 * The Constant in the Constant-Pool which may be found at the index specified by field 633 * {@link #nameAndTypeIndex} is, itself, a "Record" of sorts; and contains two integer data 634 * fields in its Record. The first integer is a Table Index-Pointer to a "name", and is 635 * represented by a {@code UTF-8} Table-Constant. 636 * 637 * <BR /><BR />The Constant-Pool Table-Index for the {@code UTF-8 String} Constanta is 638 * saved as an integer in this {@code public, final} field. 639 * 640 * <BR /><BR />The second integer of the Two-Integer Data-Record 641 * ({@link #nameAndTypeIndex}) stores a "Type as a String." The index for that 642 * {@code UTF-8 String} is stored in the {@code public final} field {@link #typeIndex}. 643 */ 644 public final int nameIndex; 645 646 /** 647 * This stores the Java 'type' for a Method-Handle as a {@cde UTF-8} Constant. You should 648 * review the documented explanations for the fields {@link #nameAndTypeIndex} and also for 649 * {@link #nameIndex} for more information. 650 */ 651 public final int typeIndex; 652 653 /** 654 * This stores the Method-Name of the Bootstrap-Method specified by this Method-Handle 655 * instance. 656 */ 657 public final String name; 658 659 660 // **************************************************************************************** 661 // **************************************************************************************** 662 // Package-Private Constructor 663 // **************************************************************************************** 664 // **************************************************************************************** 665 666 667 Dynamic( 668 final ReadOnlyList<Byte> tags, 669 final ReadOnlyList<Object> values, 670 final int tableIndex 671 ) 672 { 673 // The Constant-Pool Table-Index where this Method-Handle is located 674 // public final int tableIndex; 675 676 this.tableIndex = tableIndex; 677 678 this.tag = tags.get(tableIndex); 679 680 this.dynamicOrInvokeDynamic = (this.tag == 17); 681 682 @SuppressWarnings("unchecked") 683 final Ret2<Integer, Integer> dynamicR2 = 684 (Ret2<Integer, Integer>) values.get(tableIndex); 685 686 this.bootstrapMethodIndex = dynamicR2.a; 687 688 this.nameAndTypeIndex = dynamicR2.b; 689 690 @SuppressWarnings("unchecked") 691 final Ret2<Integer, Integer> nameAndTypeR2 = 692 (Ret2<Integer, Integer>) values.get(nameAndTypeIndex); 693 694 this.nameIndex = nameAndTypeR2.a; 695 696 this.typeIndex = nameAndTypeR2.b; 697 698 this.name = (String) values.get(this.nameIndex); 699 } 700 701 702 // **************************************************************************************** 703 // **************************************************************************************** 704 // java.lang.Object 705 // **************************************************************************************** 706 // **************************************************************************************** 707 708 709 /** Check whether this instance equals parameter {@code 'other'} */ 710 public boolean equals(Object other) 711 { 712 if (! (other instanceof ConstantPool.Dynamic)) return false; 713 714 ConstantPool.Dynamic o = (ConstantPool.Dynamic) other; 715 716 return 717 (this.tableIndex == o.tableIndex) 718 && (this.tag == o.tag) 719 && (this.dynamicOrInvokeDynamic == o.dynamicOrInvokeDynamic) 720 && (this.bootstrapMethodIndex == o.bootstrapMethodIndex) 721 && (this.nameAndTypeIndex == o.nameAndTypeIndex) 722 && (this.nameIndex == o.nameIndex) 723 && (this.typeIndex == o.typeIndex) 724 && Objects.equals(this.name, o.name); 725 } 726 727 /** Generate a simple, efficient, hash-code for this instance. */ 728 public int hashCode() 729 { return this.tableIndex + this.bootstrapMethodIndex + this.nameAndTypeIndex; } 730 731 /** Generate a {@code java.lang.String} representation for this instance. */ 732 public String toString() 733 { 734 return 735 "{\n" + 736 " tableIndex: " + tableIndex + "\n" + 737 " tag: " + tag + " (" + (dynamicOrInvokeDynamic ? "Dynamic" : "Invoke-Dynamic") + ")\n" + 738 " dynamicOrInvokeDynamic: " + dynamicOrInvokeDynamic + "\n" + 739 " name: " + name + "\n" + 740 " bootstrapMethodIndex: " + bootstrapMethodIndex + "\n" + 741 " nameAndTypeIndex: " + nameAndTypeIndex + "\n" + 742 " nameIndex: " + nameIndex + "\n" + 743 " typeIndex: " + typeIndex + "\n" + 744 "}"; 745 } 746 } 747 748 749 // ******************************************************************************************** 750 // ******************************************************************************************** 751 // Instance Fields: PARALLEL-ARRAYS (all Public-Final Constants & ReadOnly) 752 // ******************************************************************************************** 753 // ******************************************************************************************** 754 755 756 /** <EMBED CLASS='external-html' DATA-FILE-ID=CP_TABLE_SIZE> */ 757 public final int tableSize; 758 759 /** <EMBED CLASS='external-html' DATA-FILE-ID=CP_TABLE_SIZE_BYTES> */ 760 public final int tableSizeBytes; 761 762 /** 763 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_TAGS> 764 * @see #tagNames 765 */ 766 public final ReadOnlyList<Byte> tags; 767 768 769 /** 770 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_VALUES> 771 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_VALUES_TYPE_NOTE> 772 */ 773 public final ReadOnlyList<Object> values; 774 775 /** 776 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_DEREF_VALUES> 777 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_DEREF_VAL_TABLE> 778 */ 779 @LinkJavaSource(handle="DereferencedValue") 780 public final ReadOnlyList<Object> dereferencedValues; 781 782 /** Original Byte-Array Indices */ 783 public final ReadOnlyList<Integer> indices; 784 785 /** <EMBED CLASS='external-html' DATA-FILE-ID=CP_INDICES_GROUP_BY> */ 786 public final ReadOnlyList<ReadOnlyList<Integer>> indicesGroupBy; 787 788 789 // ******************************************************************************************** 790 // ******************************************************************************************** 791 // Static-Final Constants / ReadOnly Lookup-Tables as Lists. (List-Index is the "Lookup Key") 792 // ******************************************************************************************** 793 // ******************************************************************************************** 794 795 796 @SuppressWarnings("rawtypes") 797 private static Ret2 dataFileR2 = LFEC.readObjectFromFile_JAR 798 (ConstantPool.class, "data-files/data3.r2dat", true, Ret2.class); 799 800 801 /** 802 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_TAG_NAMES> 803 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_TAG_NAMES_TABLE> 804 * @see #tags List of Types/Kinds for each Constant 805 * @see #values List of Values for each Constant 806 */ 807 @LinkJavaSource(handle="ConstantPoolData", entity=FIELD, name="tagNames") 808 public static final ReadOnlyList<String> tagNames = dataFileR2.GET(1); 809 810 811 /** 812 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_TAG_WIDTH_BYTES> 813 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_TAG_WB_TABLE> 814 */ 815 @LinkJavaSource(handle="ConstantPoolData", entity=FIELD, name="tagWidthBytes") 816 public static final ReadOnlyList<Byte> tagWidthBytes = dataFileR2.GET(2); 817 818 819 // Don't need it. References are loaded into memory now. Erase it for the G.C. 820 static { dataFileR2 = null; } 821 822 823 // ******************************************************************************************** 824 // ******************************************************************************************** 825 // Static Constants: This is the "inverse" of the "tagNames" List 826 // ******************************************************************************************** 827 // ******************************************************************************************** 828 // 829 // 830 // NOTE: Here is what I said-to / asked Chat-GPT: 831 // 832 // It's Monday. I did a flurry of Round-House Kicks at L.A. Fitness yesterday. It took 3 833 // years of practice (it feels like) to be able to do that. I have another Java-Doc 834 // Help/Question for you. It is about my ConstantPool class again. Do you think you could 835 // help me write some Java-Doc Comments? Anywhere between 1 and three lines of Java-Doc would 836 // be great. I cannot think after such a huge breakfast! 837 // 838 // Above question was followed-By the list of ... 839 // `public static final byte` - Fields **BUT** WITHOUT the Java-Doc comments included below... 840 // 841 // Below is how Chat-GPT replied to me (no changes were made to the output - not one character) 842 843 /** 844 * Tag byte indicating the next constant in the table is a UTF-8 encoded {@code String}. 845 * Typically used for identifiers such as names or other textual data. 846 */ 847 public static final byte TAG_UTF_8 = 1; 848 849 /** 850 * Tag byte indicating the next constant in the table is a 32-bit integer. 851 * Used for numeric constants within the constant pool. 852 */ 853 public static final byte TAG_INTEGER = 3; 854 855 /** 856 * Tag byte indicating the next constant in the table is a 32-bit floating-point number. 857 * Represents constants of the {@code float} data type. 858 */ 859 public static final byte TAG_FLOAT = 4; 860 861 /** 862 * Tag byte indicating the next constant in the table is a 64-bit long integer. 863 * Represents constants of the {@code long} data type. 864 */ 865 public static final byte TAG_LONG = 5; 866 867 /** 868 * Tag byte indicating the next constant in the table is a 64-bit double-precision floating-point number. 869 * Represents constants of the {@code double} data type. 870 */ 871 public static final byte TAG_DOUBLE = 6; 872 873 /** 874 * Tag byte indicating the next constant in the table is a class reference. 875 * Represents a {@code Class} or interface type. 876 */ 877 public static final byte TAG_CLASS = 7; 878 879 /** 880 * Tag byte indicating the next constant in the table is a {@code String} reference. 881 * The referenced {@code String} is stored elsewhere in the constant pool. 882 */ 883 public static final byte TAG_STRING = 8; 884 885 /** 886 * Tag byte indicating the next constant in the table is a reference to a field. 887 * Used for fields within a {@code Class} or interface. 888 */ 889 public static final byte TAG_FIELD_REF = 9; 890 891 /** 892 * Tag byte indicating the next constant in the table is a reference to a method. 893 * Refers to methods defined in a {@code Class}. 894 */ 895 public static final byte TAG_METHOD_REF = 10; 896 897 /** 898 * Tag byte indicating the next constant in the table is a reference to an interface method. 899 * Refers to methods declared within an interface. 900 */ 901 public static final byte TAG_INTERFACE_METHOD_REF = 11; 902 903 /** 904 * Tag byte indicating the next constant in the table is a name-and-type descriptor. 905 * Encodes the name and type of a field or method. 906 */ 907 public static final byte TAG_NAME_AND_TYPE = 12; 908 909 /** 910 * Tag byte indicating the next constant in the table is a method handle. 911 * Represents a reference to a method handle for dynamic invocation. 912 */ 913 public static final byte TAG_METHOD_HANDLE = 15; 914 915 /** 916 * Tag byte indicating the next constant in the table is a method type. 917 * Encodes the method's descriptor, including parameter and return types. 918 */ 919 public static final byte TAG_METHOD_TYPE = 16; 920 921 /** 922 * Tag byte indicating the next constant in the table is a dynamic constant. 923 * Represents a runtime-computed constant, often linked to lambdas or invokedynamic instructions. 924 */ 925 public static final byte TAG_DYNAMIC = 17; 926 927 /** 928 * Tag byte indicating the next constant in the table is an invoke-dynamic constant. 929 * Represents a bootstrap method and dynamic call site for runtime resolution. 930 */ 931 public static final byte TAG_INVOKE_DYNAMIC = 18; 932 933 /** 934 * Tag byte indicating the next constant in the table is a module reference. 935 * Encodes the name of a module within the constant pool. 936 */ 937 public static final byte TAG_MODULE = 19; 938 939 /** 940 * Tag byte indicating the next constant in the table is a package reference. 941 * Encodes the name of a package within the constant pool. 942 */ 943 public static final byte TAG_PACKAGE = 20; 944 945 946 // ******************************************************************************************** 947 // ******************************************************************************************** 948 // Constructor 949 // ******************************************************************************************** 950 // ******************************************************************************************** 951 952 953 /** 954 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_CONSTRUCTOR> 955 * @param bArr A Class-File which has been loaded from disk into a memory, as a Java 956 * {@code byte[]} Array. 957 */ 958 @LinkJavaSource(handle="ConstPoolCtorHelper") 959 @LinkJavaSource(handle="ReadConstant") 960 @LinkJavaSource(handle="DereferencedValue") 961 @LinkJavaSource(handle="Validate") 962 public ConstantPool(final byte[] bArr) 963 { 964 RetN r = ConstPoolCtorHelper.construct(bArr); 965 966 this.tags = r.GET(1); 967 this.values = r.GET(2); 968 this.dereferencedValues = r.GET(3); 969 this.indices = r.GET(4); 970 this.indicesGroupBy = r.GET(5); 971 this.tableSizeBytes = r.GET(6); 972 973 this.tableSize = this.tags.size(); 974 } 975 976 977 // ******************************************************************************************** 978 // ******************************************************************************************** 979 // java.lang.Object Methods 980 // ******************************************************************************************** 981 // ******************************************************************************************** 982 983 984 /** 985 * Converts the contents of an instance of this class into a User-Readable {@code String}. 986 * @return A Java-{@code String} which explicates a Java {@code '.class'} File's Constant-Pool. 987 */ 988 @LinkJavaSource(handle="CPToString") 989 public String toString() 990 { return CPToString.str(this.tags, this.values, this.indicesGroupBy); } 991 992 /** 993 * Checks for equality with another instance of {@code ConstantPool}. 994 * 995 * @param other Any Java-{@code Object}, but only an instance of {@code ConstantPool} whose 996 * {@link #tags} and {@link #values} Array-Lists are equal will cause this method to return 997 * {@code TRUE}. 998 * 999 * @return {@code TRUE} if and only if the contents {@code 'this'} instance of Constant-Pool 1000 * equals those found in parameter {@code 'other'} 1001 */ 1002 public boolean equals(Object other) 1003 { 1004 if (! (other instanceof ConstantPool)) return false; 1005 1006 ConstantPool o = (ConstantPool) other; 1007 1008 return 1009 this.tags.equals(o.tags) 1010 && this.values.equals(o.values) 1011 && this.indices.equals(o.indices); 1012 } 1013 1014 /** 1015 * Java's traditional Hash-Code generator Method. 1016 * 1017 * @return a (plausibly unique) Hash-Code, which may be used for placing instances of 1018 * {@code ConstantPool} into Hash-Tables. 1019 */ 1020 public int hashCode() 1021 { 1022 // No, this isn't any good... To-Do: Worry about it... 1023 int hash = 0; 1024 for (Byte tag : this.tags) if (tag != null) hash += tag; 1025 return hash; 1026 } 1027 1028 1029 // ******************************************************************************************** 1030 // ******************************************************************************************** 1031 // Some Easy-To-Use and Easy-To-Write Getters 1032 // ******************************************************************************************** 1033 // ******************************************************************************************** 1034 1035 1036 /** 1037 * Retrieves the names of all Field-References which were listed in the Constant-Pool 1038 * table that was used to build {@code 'this'} instance. 1039 * 1040 * @return A Java-{@code Stream} containing the names of any / all fields from the table. 1041 */ 1042 @LinkJavaSource(handle="AllNames", name="getAllFieldNames") 1043 public Stream<String> allFieldNames() 1044 { 1045 return AllNames.getAllFieldNames( 1046 this.indicesGroupBy.get(ConstantPool.TAG_FIELD_REF), 1047 this.values 1048 ); 1049 } 1050 1051 /** 1052 * <EMBED CLASS='external-html' DATA-FILE-ID=CP_GET_ALL_METHNAME> 1053 * 1054 * @return A Java-{@code Stream<String>} containing the names of any / all methods and 1055 * "Method References" from the Constant-Pool Table. 1056 */ 1057 @LinkJavaSource(handle="AllNames", name="getAllMethodNames") 1058 public Stream<String> allMethodNames() 1059 { 1060 return AllNames.getAllMethodNames( 1061 this.indicesGroupBy.get(ConstantPool.TAG_METHOD_REF), 1062 this.indicesGroupBy.get(ConstantPool.TAG_INTERFACE_METHOD_REF), 1063 this.values 1064 ); 1065 } 1066 1067 /** 1068 * All Constants in this Pool whose Tag-Kind are: 1069 * 1070 * <BR /><BR /><UL CLASS=JDUL> 1071 * <LI><B>{@link #TAG_FIELD_REF}</B> (9)</LI> 1072 * </UL> 1073 * 1074 * @return All Field-References contained by {@code 'this'} table. The Java {@code Stream} 1075 * which is returned contains instances of {@link ConstantPool.Reference}. 1076 * 1077 * @see #dereferencedValues 1078 * @see #indicesGroupBy 1079 */ 1080 @SuppressWarnings("unchecked") 1081 public Stream<ConstantPool.Reference> allFields() 1082 { 1083 return this.indicesGroupBy 1084 .get(ConstantPool.TAG_FIELD_REF) 1085 .stream() 1086 .map((Integer index) -> (ConstantPool.Reference) this.dereferencedValues.get(index)); 1087 } 1088 1089 /** 1090 * All Constants in this Pool whose Tag-Kind are: 1091 * 1092 * <BR /><BR /><UL CLASS=JDUL> 1093 * <LI><B>{@link #TAG_METHOD_REF}</B> (10)</LI> 1094 * <LI><B>{@link #TAG_INTERFACE_METHOD_REF}</B> (10)</LI> 1095 * </UL> 1096 * 1097 * @return All Method-References contained by {@code 'this'} table. The Java {@code Stream} 1098 * which is returned contains instances of {@link ConstantPool.Reference}. 1099 * 1100 * @see #dereferencedValues 1101 * @see #indicesGroupBy 1102 */ 1103 @SuppressWarnings("unchecked") 1104 public Stream<ConstantPool.Reference> allMethods() 1105 { 1106 return Stream.concat( 1107 this.indicesGroupBy.get(ConstantPool.TAG_METHOD_REF).stream(), 1108 this.indicesGroupBy.get(ConstantPool.TAG_INTERFACE_METHOD_REF).stream() 1109 ) 1110 .map((Integer index) -> (ConstantPool.Reference) this.dereferencedValues.get(index)); 1111 } 1112}