78 * the bytecode of each method. 79 * 80 * @see #ClassWriter(int) 81 */ 82 public static final int COMPUTE_MAXS = 1; 83 84 /** 85 * Flag to automatically compute the stack map frames of methods from 86 * scratch. If this flag is set, then the calls to the 87 * {@link MethodVisitor#visitFrame} method are ignored, and the stack map 88 * frames are recomputed from the methods bytecode. The arguments of the 89 * {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and 90 * recomputed from the bytecode. In other words, computeFrames implies 91 * computeMaxs. 92 * 93 * @see #ClassWriter(int) 94 */ 95 public static final int COMPUTE_FRAMES = 2; 96 97 /** 98 * Pseudo access flag to distinguish between the synthetic attribute and 99 * the synthetic access flag. 100 */ 101 static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000; 102 103 /** 104 * The type of instructions without any argument. 105 */ 106 static final int NOARG_INSN = 0; 107 108 /** 109 * The type of instructions with an signed byte argument. 110 */ 111 static final int SBYTE_INSN = 1; 112 113 /** 114 * The type of instructions with an signed short argument. 115 */ 116 static final int SHORT_INSN = 2; 117 118 /** 119 * The type of instructions with a local variable index argument. 120 */ 121 static final int VAR_INSN = 3; 122 123 /** 250 */ 251 static final int UTF8 = 1; 252 253 /** 254 * The type of CONSTANT_MethodType constant pool items. 255 */ 256 static final int MTYPE = 16; 257 258 /** 259 * The type of CONSTANT_MethodHandle constant pool items. 260 */ 261 static final int HANDLE = 15; 262 263 /** 264 * The type of CONSTANT_InvokeDynamic constant pool items. 265 */ 266 static final int INDY = 18; 267 268 /** 269 * The base value for all CONSTANT_MethodHandle constant pool items. 270 * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 271 * 9 different items. 272 */ 273 static final int HANDLE_BASE = 20; 274 275 /** 276 * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable}, 277 * instead of the constant pool, in order to avoid clashes with normal 278 * constant pool items in the ClassWriter constant pool's hash table. 279 */ 280 static final int TYPE_NORMAL = 30; 281 282 /** 283 * Uninitialized type Item stored in the ClassWriter 284 * {@link ClassWriter#typeTable}, instead of the constant pool, in order to 285 * avoid clashes with normal constant pool items in the ClassWriter constant 286 * pool's hash table. 287 */ 288 static final int TYPE_UNINIT = 31; 289 290 /** 291 * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable}, 292 * instead of the constant pool, in order to avoid clashes with normal 293 * constant pool items in the ClassWriter constant pool's hash table. 294 */ 295 static final int TYPE_MERGED = 32; 296 297 /** 298 * The type of BootstrapMethods items. These items are stored in a 299 * special class attribute named BootstrapMethods and 300 * not in the constant pool. 301 */ 302 static final int BSM = 33; 303 304 /** 305 * The class reader from which this class writer was constructed, if any. 306 */ 307 ClassReader cr; 308 309 /** 310 * Minor and major version numbers of the class to be generated. 311 */ 312 int version; 313 314 /** 315 * Index of the next item to be added in the constant pool. 316 */ 317 int index; 318 319 /** 320 * The constant pool of this class. 339 /** 340 * A reusable key used to look for items in the {@link #items} hash table. 341 */ 342 final Item key2; 343 344 /** 345 * A reusable key used to look for items in the {@link #items} hash table. 346 */ 347 final Item key3; 348 349 /** 350 * A reusable key used to look for items in the {@link #items} hash table. 351 */ 352 final Item key4; 353 354 /** 355 * A type table used to temporarily store internal names that will not 356 * necessarily be stored in the constant pool. This type table is used by 357 * the control flow and data flow analysis algorithm used to compute stack 358 * map frames from scratch. This array associates to each index <tt>i</tt> 359 * the Item whose index is <tt>i</tt>. All Item objects stored in this 360 * array are also stored in the {@link #items} hash table. These two arrays 361 * allow to retrieve an Item from its index or, conversely, to get the index 362 * of an Item from its value. Each Item stores an internal name in its 363 * {@link Item#strVal1} field. 364 */ 365 Item[] typeTable; 366 367 /** 368 * Number of elements in the {@link #typeTable} array. 369 */ 370 private short typeCount; 371 372 /** 373 * The access flags of this class. 374 */ 375 private int access; 376 377 /** 378 * The constant pool item that contains the internal name of this class. 379 */ 380 private int name; 381 382 /** 424 */ 425 private int enclosingMethodOwner; 426 427 /** 428 * The constant pool item that contains the name and descriptor of the 429 * enclosing method of this class. 430 */ 431 private int enclosingMethod; 432 433 /** 434 * The runtime visible annotations of this class. 435 */ 436 private AnnotationWriter anns; 437 438 /** 439 * The runtime invisible annotations of this class. 440 */ 441 private AnnotationWriter ianns; 442 443 /** 444 * The non standard attributes of this class. 445 */ 446 private Attribute attrs; 447 448 /** 449 * The number of entries in the InnerClasses attribute. 450 */ 451 private int innerClassesCount; 452 453 /** 454 * The InnerClasses attribute. 455 */ 456 private ByteVector innerClasses; 457 458 /** 459 * The number of entries in the BootstrapMethods attribute. 460 */ 461 int bootstrapMethodsCount; 462 463 /** 464 * The BootstrapMethods attribute. 465 */ 466 ByteVector bootstrapMethods; 467 468 /** 469 * The fields of this class. These fields are stored in a linked list of 470 * {@link FieldWriter} objects, linked to each other by their 471 * {@link FieldWriter#fv} field. This field stores the first element of 472 * this list. 473 */ 474 FieldWriter firstField; 475 476 /** 477 * The fields of this class. These fields are stored in a linked list of 478 * {@link FieldWriter} objects, linked to each other by their 479 * {@link FieldWriter#fv} field. This field stores the last element of 480 * this list. 481 */ 482 FieldWriter lastField; 483 484 /** 485 * The methods of this class. These methods are stored in a linked list of 486 * {@link MethodWriter} objects, linked to each other by their 487 * {@link MethodWriter#mv} field. This field stores the first element of 488 * this list. 489 */ 490 MethodWriter firstMethod; 491 492 /** 493 * The methods of this class. These methods are stored in a linked list of 494 * {@link MethodWriter} objects, linked to each other by their 495 * {@link MethodWriter#mv} field. This field stores the last element of 496 * this list. 497 */ 498 MethodWriter lastMethod; 499 500 /** 501 * <tt>true</tt> if the maximum stack size and number of local variables 502 * must be automatically computed. 503 */ 504 private final boolean computeMaxs; 505 506 /** 507 * <tt>true</tt> if the stack map frames must be recomputed from scratch. 508 */ 509 private final boolean computeFrames; 510 511 /** 512 * <tt>true</tt> if the stack map tables of this class are invalid. The 513 * {@link MethodWriter#resizeInstructions} method cannot transform existing 514 * stack map tables, and so produces potentially invalid classes when it is 515 * executed. In this case the class is reread and rewritten with the 516 * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize 596 // // special instructions 597 // b[Constants.IINC] = IINC_INSN; 598 // b[Constants.TABLESWITCH] = TABL_INSN; 599 // b[Constants.LOOKUPSWITCH] = LOOK_INSN; 600 // b[Constants.MULTIANEWARRAY] = MANA_INSN; 601 // b[196] = WIDE_INSN; // WIDE 602 // 603 // for (i = 0; i < b.length; ++i) { 604 // System.err.print((char)('A' + b[i])); 605 // } 606 // System.err.println(); 607 } 608 609 // ------------------------------------------------------------------------ 610 // Constructor 611 // ------------------------------------------------------------------------ 612 613 /** 614 * Constructs a new {@link ClassWriter} object. 615 * 616 * @param flags option flags that can be used to modify the default behavior 617 * of this class. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}. 618 */ 619 public ClassWriter(final int flags) { 620 super(Opcodes.ASM4); 621 index = 1; 622 pool = new ByteVector(); 623 items = new Item[256]; 624 threshold = (int) (0.75d * items.length); 625 key = new Item(); 626 key2 = new Item(); 627 key3 = new Item(); 628 key4 = new Item(); 629 this.computeMaxs = (flags & COMPUTE_MAXS) != 0; 630 this.computeFrames = (flags & COMPUTE_FRAMES) != 0; 631 } 632 633 /** 634 * Constructs a new {@link ClassWriter} object and enables optimizations for 635 * "mostly add" bytecode transformations. These optimizations are the 636 * following: 637 * 638 * <ul> <li>The constant pool from the original class is copied as is in the 639 * new class, which saves time. New constant pool entries will be added at 640 * the end if necessary, but unused constant pool entries <i>won't be 641 * removed</i>.</li> <li>Methods that are not transformed are copied as is 642 * in the new class, directly from the original class bytecode (i.e. without 643 * emitting visit events for all the method instructions), which saves a 644 * <i>lot</i> of time. Untransformed methods are detected by the fact that 645 * the {@link ClassReader} receives {@link MethodVisitor} objects that come 646 * from a {@link ClassWriter} (and not from any other {@link ClassVisitor} 647 * instance).</li> </ul> 648 * 649 * @param classReader the {@link ClassReader} used to read the original 650 * class. It will be used to copy the entire constant pool from the 651 * original class and also to copy other fragments of original 652 * bytecode where applicable. 653 * @param flags option flags that can be used to modify the default behavior 654 * of this class. <i>These option flags do not affect methods that 655 * are copied as is in the new class. This means that the maximum 656 * stack size nor the stack frames will be computed for these 657 * methods</i>. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}. 658 */ 659 public ClassWriter(final ClassReader classReader, final int flags) { 660 this(flags); 661 classReader.copyPool(this); 662 this.cr = classReader; 663 } 664 665 // ------------------------------------------------------------------------ 666 // Implementation of the ClassVisitor abstract class 667 // ------------------------------------------------------------------------ 668 669 @Override 670 public final void visit( 671 final int version, 672 final int access, 673 final String name, 674 final String signature, 675 final String superName, 676 final String[] interfaces) 677 { 678 this.version = version; 679 this.access = access; 680 this.name = newClass(name); 681 thisName = name; 682 if (ClassReader.SIGNATURES && signature != null) { 683 this.signature = newUTF8(signature); 684 } 685 this.superName = superName == null ? 0 : newClass(superName); 686 if (interfaces != null && interfaces.length > 0) { 687 interfaceCount = interfaces.length; 688 this.interfaces = new int[interfaceCount]; 689 for (int i = 0; i < interfaceCount; ++i) { 690 this.interfaces[i] = newClass(interfaces[i]); 691 } 692 } 693 } 694 695 @Override 696 public final void visitSource(final String file, final String debug) { 697 if (file != null) { 698 sourceFile = newUTF8(file); 699 } 700 if (debug != null) { 701 sourceDebug = new ByteVector().putUTF8(debug); 702 } 703 } 704 705 @Override 706 public final void visitOuterClass( 707 final String owner, 708 final String name, 709 final String desc) 710 { 711 enclosingMethodOwner = newClass(owner); 712 if (name != null && desc != null) { 713 enclosingMethod = newNameType(name, desc); 714 } 715 } 716 717 @Override 718 public final AnnotationVisitor visitAnnotation( 719 final String desc, 720 final boolean visible) 721 { 722 if (!ClassReader.ANNOTATIONS) { 723 return null; 724 } 725 ByteVector bv = new ByteVector(); 726 // write type, and reserve space for values count 727 bv.putShort(newUTF8(desc)).putShort(0); 728 AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2); 729 if (visible) { 730 aw.next = anns; 731 anns = aw; 732 } else { 733 aw.next = ianns; 734 ianns = aw; 735 } 736 return aw; 737 } 738 739 @Override 740 public final void visitAttribute(final Attribute attr) { 741 attr.next = attrs; 742 attrs = attr; 743 } 744 745 @Override 746 public final void visitInnerClass( 747 final String name, 748 final String outerName, 749 final String innerName, 750 final int access) 751 { 752 if (innerClasses == null) { 753 innerClasses = new ByteVector(); 754 } 755 ++innerClassesCount; 756 innerClasses.putShort(name == null ? 0 : newClass(name)); 757 innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); 758 innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); 759 innerClasses.putShort(access); 760 } 761 762 @Override 763 public final FieldVisitor visitField( 764 final int access, 765 final String name, 766 final String desc, 767 final String signature, 768 final Object value) 769 { 770 return new FieldWriter(this, access, name, desc, signature, value); 771 } 772 773 @Override 774 public final MethodVisitor visitMethod( 775 final int access, 776 final String name, 777 final String desc, 778 final String signature, 779 final String[] exceptions) 780 { 781 return new MethodWriter(this, 782 access, 783 name, 784 desc, 785 signature, 786 exceptions, 787 computeMaxs, 788 computeFrames); 789 } 790 791 @Override 792 public final void visitEnd() { 793 } 794 795 // ------------------------------------------------------------------------ 796 // Other public methods 797 // ------------------------------------------------------------------------ 798 799 /** 800 * Returns the bytecode of the class that was build with this class writer. 801 * 802 * @return the bytecode of the class that was build with this class writer. 803 */ 804 public byte[] toByteArray() { 805 if (index > Short.MAX_VALUE) { 806 throw new RuntimeException("Class file too large!"); 807 } 808 // computes the real size of the bytecode of this class 809 int size = 24 + 2 * interfaceCount; 810 int nbFields = 0; 811 FieldWriter fb = firstField; 812 while (fb != null) { 813 ++nbFields; 814 size += fb.getSize(); 815 fb = (FieldWriter) fb.fv; 816 } 817 int nbMethods = 0; 818 MethodWriter mb = firstMethod; 819 while (mb != null) { 820 ++nbMethods; 821 size += mb.getSize(); 822 mb = (MethodWriter) mb.mv; 823 } 824 int attributeCount = 0; 825 if (bootstrapMethods != null) { // we put it as first argument in order 826 // to improve a bit ClassReader.copyBootstrapMethods 827 ++attributeCount; 828 size += 8 + bootstrapMethods.length; 829 newUTF8("BootstrapMethods"); 830 } 831 if (ClassReader.SIGNATURES && signature != 0) { 832 ++attributeCount; 833 size += 8; 834 newUTF8("Signature"); 835 } 836 if (sourceFile != 0) { 837 ++attributeCount; 838 size += 8; 839 newUTF8("SourceFile"); 840 } 841 if (sourceDebug != null) { 842 ++attributeCount; 843 size += sourceDebug.length + 4; 844 newUTF8("SourceDebugExtension"); 845 } 846 if (enclosingMethodOwner != 0) { 847 ++attributeCount; 848 size += 10; 849 newUTF8("EnclosingMethod"); 850 } 851 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 852 ++attributeCount; 853 size += 6; 854 newUTF8("Deprecated"); 855 } 856 if ((access & Opcodes.ACC_SYNTHETIC) != 0 857 && ((version & 0xFFFF) < Opcodes.V1_5 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0)) 858 { 859 ++attributeCount; 860 size += 6; 861 newUTF8("Synthetic"); 862 } 863 if (innerClasses != null) { 864 ++attributeCount; 865 size += 8 + innerClasses.length; 866 newUTF8("InnerClasses"); 867 } 868 if (ClassReader.ANNOTATIONS && anns != null) { 869 ++attributeCount; 870 size += 8 + anns.getSize(); 871 newUTF8("RuntimeVisibleAnnotations"); 872 } 873 if (ClassReader.ANNOTATIONS && ianns != null) { 874 ++attributeCount; 875 size += 8 + ianns.getSize(); 876 newUTF8("RuntimeInvisibleAnnotations"); 877 } 878 if (attrs != null) { 879 attributeCount += attrs.getCount(); 880 size += attrs.getSize(this, null, 0, -1, -1); 881 } 882 size += pool.length; 883 // allocates a byte vector of this size, in order to avoid unnecessary 884 // arraycopy operations in the ByteVector.enlarge() method 885 ByteVector out = new ByteVector(size); 886 out.putInt(0xCAFEBABE).putInt(version); 887 out.putShort(index).putByteArray(pool.data, 0, pool.length); 888 int mask = Opcodes.ACC_DEPRECATED 889 | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE 890 | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC)); 891 out.putShort(access & ~mask).putShort(name).putShort(superName); 892 out.putShort(interfaceCount); 893 for (int i = 0; i < interfaceCount; ++i) { 894 out.putShort(interfaces[i]); 895 } 896 out.putShort(nbFields); 897 fb = firstField; 898 while (fb != null) { 899 fb.put(out); 900 fb = (FieldWriter) fb.fv; 901 } 902 out.putShort(nbMethods); 903 mb = firstMethod; 904 while (mb != null) { 905 mb.put(out); 906 mb = (MethodWriter) mb.mv; 907 } 908 out.putShort(attributeCount); 909 if (bootstrapMethods != null) { // should be the first class attribute ? 910 out.putShort(newUTF8("BootstrapMethods")); 911 out.putInt(bootstrapMethods.length + 2).putShort(bootstrapMethodsCount); 912 out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length); 913 } 914 if (ClassReader.SIGNATURES && signature != 0) { 915 out.putShort(newUTF8("Signature")).putInt(2).putShort(signature); 916 } 917 if (sourceFile != 0) { 918 out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile); 919 } 920 if (sourceDebug != null) { 921 int len = sourceDebug.length - 2; 922 out.putShort(newUTF8("SourceDebugExtension")).putInt(len); 923 out.putByteArray(sourceDebug.data, 2, len); 924 } 925 if (enclosingMethodOwner != 0) { 926 out.putShort(newUTF8("EnclosingMethod")).putInt(4); 927 out.putShort(enclosingMethodOwner).putShort(enclosingMethod); 928 } 929 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 930 out.putShort(newUTF8("Deprecated")).putInt(0); 931 } 932 if ((access & Opcodes.ACC_SYNTHETIC) != 0 933 && ((version & 0xFFFF) < Opcodes.V1_5 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0)) 934 { 935 out.putShort(newUTF8("Synthetic")).putInt(0); 936 } 937 if (innerClasses != null) { 938 out.putShort(newUTF8("InnerClasses")); 939 out.putInt(innerClasses.length + 2).putShort(innerClassesCount); 940 out.putByteArray(innerClasses.data, 0, innerClasses.length); 941 } 942 if (ClassReader.ANNOTATIONS && anns != null) { 943 out.putShort(newUTF8("RuntimeVisibleAnnotations")); 944 anns.put(out); 945 } 946 if (ClassReader.ANNOTATIONS && ianns != null) { 947 out.putShort(newUTF8("RuntimeInvisibleAnnotations")); 948 ianns.put(out); 949 } 950 if (attrs != null) { 951 attrs.put(this, null, 0, -1, -1, out); 952 } 953 if (invalidFrames) { 954 ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); 955 new ClassReader(out.data).accept(cw, ClassReader.SKIP_FRAMES); 956 return cw.toByteArray(); 957 } 958 return out.data; 959 } 960 961 // ------------------------------------------------------------------------ 962 // Utility methods: constant pool management 963 // ------------------------------------------------------------------------ 964 965 /** 966 * Adds a number or string constant to the constant pool of the class being 967 * build. Does nothing if the constant pool already contains a similar item. 968 * 969 * @param cst the value of the constant to be added to the constant pool. 970 * This parameter must be an {@link Integer}, a {@link Float}, a 971 * {@link Long}, a {@link Double}, a {@link String} or a 972 * {@link Type}. 973 * @return a new or already existing constant item with the given value. 974 */ 975 Item newConstItem(final Object cst) { 976 if (cst instanceof Integer) { 977 int val = ((Integer) cst).intValue(); 978 return newInteger(val); 979 } else if (cst instanceof Byte) { 980 int val = ((Byte) cst).intValue(); 981 return newInteger(val); 982 } else if (cst instanceof Character) { 983 int val = ((Character) cst).charValue(); 984 return newInteger(val); 985 } else if (cst instanceof Short) { 986 int val = ((Short) cst).intValue(); 987 return newInteger(val); 988 } else if (cst instanceof Boolean) { 989 int val = ((Boolean) cst).booleanValue() ? 1 : 0; 990 return newInteger(val); 991 } else if (cst instanceof Float) { 992 float val = ((Float) cst).floatValue(); 993 return newFloat(val); 994 } else if (cst instanceof Long) { 995 long val = ((Long) cst).longValue(); 996 return newLong(val); 997 } else if (cst instanceof Double) { 998 double val = ((Double) cst).doubleValue(); 999 return newDouble(val); 1000 } else if (cst instanceof String) { 1001 return newString((String) cst); 1002 } else if (cst instanceof Type) { 1003 Type t = (Type) cst; 1004 int s = t.getSort(); 1005 if (s == Type.ARRAY) { 1006 return newClassItem(t.getDescriptor()); 1007 } else if (s == Type.OBJECT) { 1008 return newClassItem(t.getInternalName()); 1009 } else { // s == Type.METHOD 1010 return newMethodTypeItem(t.getDescriptor()); 1011 } 1012 } else if (cst instanceof Handle) { 1013 Handle h = (Handle) cst; 1014 return newHandleItem(h.tag, h.owner, h.name, h.desc); 1015 } else { 1016 throw new IllegalArgumentException("value " + cst); 1017 } 1018 } 1019 1020 /** 1021 * Adds a number or string constant to the constant pool of the class being 1022 * build. Does nothing if the constant pool already contains a similar item. 1023 * <i>This method is intended for {@link Attribute} sub classes, and is 1024 * normally not needed by class generators or adapters.</i> 1025 * 1026 * @param cst the value of the constant to be added to the constant pool. 1027 * This parameter must be an {@link Integer}, a {@link Float}, a 1028 * {@link Long}, a {@link Double} or a {@link String}. 1029 * @return the index of a new or already existing constant item with the 1030 * given value. 1031 */ 1032 public int newConst(final Object cst) { 1033 return newConstItem(cst).index; 1034 } 1035 1036 /** 1037 * Adds an UTF8 string to the constant pool of the class being build. Does 1038 * nothing if the constant pool already contains a similar item. <i>This 1039 * method is intended for {@link Attribute} sub classes, and is normally not 1040 * needed by class generators or adapters.</i> 1041 * 1042 * @param value the String value. 1043 * @return the index of a new or already existing UTF8 item. 1044 */ 1045 public int newUTF8(final String value) { 1046 key.set(UTF8, value, null, null); 1047 Item result = get(key); 1048 if (result == null) { 1049 pool.putByte(UTF8).putUTF8(value); 1050 result = new Item(index++, key); 1051 put(result); 1052 } 1053 return result.index; 1054 } 1055 1056 /** 1057 * Adds a class reference to the constant pool of the class being build. 1058 * Does nothing if the constant pool already contains a similar item. 1059 * <i>This method is intended for {@link Attribute} sub classes, and is 1060 * normally not needed by class generators or adapters.</i> 1061 * 1062 * @param value the internal name of the class. 1063 * @return a new or already existing class reference item. 1064 */ 1065 Item newClassItem(final String value) { 1066 key2.set(CLASS, value, null, null); 1067 Item result = get(key2); 1068 if (result == null) { 1069 pool.put12(CLASS, newUTF8(value)); 1070 result = new Item(index++, key2); 1071 put(result); 1072 } 1073 return result; 1074 } 1075 1076 /** 1077 * Adds a class reference to the constant pool of the class being build. 1078 * Does nothing if the constant pool already contains a similar item. 1079 * <i>This method is intended for {@link Attribute} sub classes, and is 1080 * normally not needed by class generators or adapters.</i> 1081 * 1082 * @param value the internal name of the class. 1083 * @return the index of a new or already existing class reference item. 1084 */ 1085 public int newClass(final String value) { 1086 return newClassItem(value).index; 1087 } 1088 1089 /** 1090 * Adds a method type reference to the constant pool of the class being 1091 * build. Does nothing if the constant pool already contains a similar item. 1092 * <i>This method is intended for {@link Attribute} sub classes, and is 1093 * normally not needed by class generators or adapters.</i> 1094 * 1095 * @param methodDesc method descriptor of the method type. 1096 * @return a new or already existing method type reference item. 1097 */ 1098 Item newMethodTypeItem(final String methodDesc) { 1099 key2.set(MTYPE, methodDesc, null, null); 1100 Item result = get(key2); 1101 if (result == null) { 1102 pool.put12(MTYPE, newUTF8(methodDesc)); 1103 result = new Item(index++, key2); 1104 put(result); 1105 } 1106 return result; 1107 } 1108 1109 /** 1110 * Adds a method type reference to the constant pool of the class being 1111 * build. Does nothing if the constant pool already contains a similar item. 1112 * <i>This method is intended for {@link Attribute} sub classes, and is 1113 * normally not needed by class generators or adapters.</i> 1114 * 1115 * @param methodDesc method descriptor of the method type. 1116 * @return the index of a new or already existing method type reference 1117 * item. 1118 */ 1119 public int newMethodType(final String methodDesc) { 1120 return newMethodTypeItem(methodDesc).index; 1121 } 1122 1123 /** 1124 * Adds a handle to the constant pool of the class being build. Does nothing 1125 * if the constant pool already contains a similar item. <i>This method is 1126 * intended for {@link Attribute} sub classes, and is normally not needed by 1127 * class generators or adapters.</i> 1128 * 1129 * @param tag the kind of this handle. Must be {@link Opcodes#H_GETFIELD}, 1130 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, 1131 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, 1132 * {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, 1133 * {@link Opcodes#H_NEWINVOKESPECIAL} or 1134 * {@link Opcodes#H_INVOKEINTERFACE}. 1135 * @param owner the internal name of the field or method owner class. 1136 * @param name the name of the field or method. 1137 * @param desc the descriptor of the field or method. 1138 * @return a new or an already existing method type reference item. 1139 */ 1140 Item newHandleItem( 1141 final int tag, 1142 final String owner, 1143 final String name, 1144 final String desc) 1145 { 1146 key4.set(HANDLE_BASE + tag, owner, name, desc); 1147 Item result = get(key4); 1148 if (result == null) { 1149 if (tag <= Opcodes.H_PUTSTATIC) { 1150 put112(HANDLE, tag, newField(owner, name, desc)); 1151 } else { 1152 put112(HANDLE, tag, newMethod(owner, 1153 name, 1154 desc, 1155 tag == Opcodes.H_INVOKEINTERFACE)); 1156 } 1157 result = new Item(index++, key4); 1158 put(result); 1159 } 1160 return result; 1161 } 1162 1163 /** 1164 * Adds a handle to the constant pool of the class being 1165 * build. Does nothing if the constant pool already contains a similar item. 1166 * <i>This method is intended for {@link Attribute} sub classes, and is 1167 * normally not needed by class generators or adapters.</i> 1168 * 1169 * @param tag the kind of this handle. Must be {@link Opcodes#H_GETFIELD}, 1170 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, 1171 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, 1172 * {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, 1173 * {@link Opcodes#H_NEWINVOKESPECIAL} or 1174 * {@link Opcodes#H_INVOKEINTERFACE}. 1175 * @param owner the internal name of the field or method owner class. 1176 * @param name the name of the field or method. 1177 * @param desc the descriptor of the field or method. 1178 * @return the index of a new or already existing method type reference 1179 * item. 1180 */ 1181 public int newHandle( 1182 final int tag, 1183 final String owner, 1184 final String name, 1185 final String desc) 1186 { 1187 return newHandleItem(tag, owner, name, desc).index; 1188 } 1189 1190 /** 1191 * Adds an invokedynamic reference to the constant pool of the class being 1192 * build. Does nothing if the constant pool already contains a similar item. 1193 * <i>This method is intended for {@link Attribute} sub classes, and is 1194 * normally not needed by class generators or adapters.</i> 1195 * 1196 * @param name name of the invoked method. 1197 * @param desc descriptor of the invoke method. 1198 * @param bsm the bootstrap method. 1199 * @param bsmArgs the bootstrap method constant arguments. 1200 * 1201 * @return a new or an already existing invokedynamic type reference item. 1202 */ 1203 Item newInvokeDynamicItem( 1204 final String name, 1205 final String desc, 1206 final Handle bsm, 1207 final Object... bsmArgs) 1208 { 1209 // cache for performance 1210 ByteVector bootstrapMethods = this.bootstrapMethods; 1211 if (bootstrapMethods == null) { 1212 bootstrapMethods = this.bootstrapMethods = new ByteVector(); 1213 } 1214 1215 int position = bootstrapMethods.length; // record current position 1216 1217 int hashCode = bsm.hashCode(); 1218 bootstrapMethods.putShort(newHandle(bsm.tag, 1219 bsm.owner, 1220 bsm.name, 1221 bsm.desc)); 1222 1223 int argsLength = bsmArgs.length; 1224 bootstrapMethods.putShort(argsLength); 1225 1226 for (int i = 0; i < argsLength; i++) { 1227 Object bsmArg = bsmArgs[i]; 1228 hashCode ^= bsmArg.hashCode(); 1229 bootstrapMethods.putShort(newConst(bsmArg)); 1230 } 1231 1232 byte[] data = bootstrapMethods.data; 1233 int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments) 1234 hashCode &= 0x7FFFFFFF; 1235 Item result = items[hashCode % items.length]; 1236 loop: while (result != null) { 1237 if (result.type != BSM || result.hashCode != hashCode) { 1238 result = result.next; 1239 continue; 1240 } 1262 put(result); 1263 } 1264 1265 // now, create the InvokeDynamic constant 1266 key3.set(name, desc, bootstrapMethodIndex); 1267 result = get(key3); 1268 if (result == null) { 1269 put122(INDY, bootstrapMethodIndex, newNameType(name, desc)); 1270 result = new Item(index++, key3); 1271 put(result); 1272 } 1273 return result; 1274 } 1275 1276 /** 1277 * Adds an invokedynamic reference to the constant pool of the class being 1278 * build. Does nothing if the constant pool already contains a similar item. 1279 * <i>This method is intended for {@link Attribute} sub classes, and is 1280 * normally not needed by class generators or adapters.</i> 1281 * 1282 * @param name name of the invoked method. 1283 * @param desc descriptor of the invoke method. 1284 * @param bsm the bootstrap method. 1285 * @param bsmArgs the bootstrap method constant arguments. 1286 * 1287 * @return the index of a new or already existing invokedynamic 1288 * reference item. 1289 */ 1290 public int newInvokeDynamic( 1291 final String name, 1292 final String desc, 1293 final Handle bsm, 1294 final Object... bsmArgs) 1295 { 1296 return newInvokeDynamicItem(name, desc, bsm, bsmArgs).index; 1297 } 1298 1299 /** 1300 * Adds a field reference to the constant pool of the class being build. 1301 * Does nothing if the constant pool already contains a similar item. 1302 * 1303 * @param owner the internal name of the field's owner class. 1304 * @param name the field's name. 1305 * @param desc the field's descriptor. 1306 * @return a new or already existing field reference item. 1307 */ 1308 Item newFieldItem(final String owner, final String name, final String desc) 1309 { 1310 key3.set(FIELD, owner, name, desc); 1311 Item result = get(key3); 1312 if (result == null) { 1313 put122(FIELD, newClass(owner), newNameType(name, desc)); 1314 result = new Item(index++, key3); 1315 put(result); 1316 } 1317 return result; 1318 } 1319 1320 /** 1321 * Adds a field reference to the constant pool of the class being build. 1322 * Does nothing if the constant pool already contains a similar item. 1323 * <i>This method is intended for {@link Attribute} sub classes, and is 1324 * normally not needed by class generators or adapters.</i> 1325 * 1326 * @param owner the internal name of the field's owner class. 1327 * @param name the field's name. 1328 * @param desc the field's descriptor. 1329 * @return the index of a new or already existing field reference item. 1330 */ 1331 public int newField(final String owner, final String name, final String desc) 1332 { 1333 return newFieldItem(owner, name, desc).index; 1334 } 1335 1336 /** 1337 * Adds a method reference to the constant pool of the class being build. 1338 * Does nothing if the constant pool already contains a similar item. 1339 * 1340 * @param owner the internal name of the method's owner class. 1341 * @param name the method's name. 1342 * @param desc the method's descriptor. 1343 * @param itf <tt>true</tt> if <tt>owner</tt> is an interface. 1344 * @return a new or already existing method reference item. 1345 */ 1346 Item newMethodItem( 1347 final String owner, 1348 final String name, 1349 final String desc, 1350 final boolean itf) 1351 { 1352 int type = itf ? IMETH : METH; 1353 key3.set(type, owner, name, desc); 1354 Item result = get(key3); 1355 if (result == null) { 1356 put122(type, newClass(owner), newNameType(name, desc)); 1357 result = new Item(index++, key3); 1358 put(result); 1359 } 1360 return result; 1361 } 1362 1363 /** 1364 * Adds a method reference to the constant pool of the class being build. 1365 * Does nothing if the constant pool already contains a similar item. 1366 * <i>This method is intended for {@link Attribute} sub classes, and is 1367 * normally not needed by class generators or adapters.</i> 1368 * 1369 * @param owner the internal name of the method's owner class. 1370 * @param name the method's name. 1371 * @param desc the method's descriptor. 1372 * @param itf <tt>true</tt> if <tt>owner</tt> is an interface. 1373 * @return the index of a new or already existing method reference item. 1374 */ 1375 public int newMethod( 1376 final String owner, 1377 final String name, 1378 final String desc, 1379 final boolean itf) 1380 { 1381 return newMethodItem(owner, name, desc, itf).index; 1382 } 1383 1384 /** 1385 * Adds an integer to the constant pool of the class being build. Does 1386 * nothing if the constant pool already contains a similar item. 1387 * 1388 * @param value the int value. 1389 * @return a new or already existing int item. 1390 */ 1391 Item newInteger(final int value) { 1392 key.set(value); 1393 Item result = get(key); 1394 if (result == null) { 1395 pool.putByte(INT).putInt(value); 1396 result = new Item(index++, key); 1397 put(result); 1398 } 1399 return result; 1400 } 1401 1402 /** 1403 * Adds a float to the constant pool of the class being build. Does nothing 1404 * if the constant pool already contains a similar item. 1405 * 1406 * @param value the float value. 1407 * @return a new or already existing float item. 1408 */ 1409 Item newFloat(final float value) { 1410 key.set(value); 1411 Item result = get(key); 1412 if (result == null) { 1413 pool.putByte(FLOAT).putInt(key.intVal); 1414 result = new Item(index++, key); 1415 put(result); 1416 } 1417 return result; 1418 } 1419 1420 /** 1421 * Adds a long to the constant pool of the class being build. Does nothing 1422 * if the constant pool already contains a similar item. 1423 * 1424 * @param value the long value. 1425 * @return a new or already existing long item. 1426 */ 1427 Item newLong(final long value) { 1428 key.set(value); 1429 Item result = get(key); 1430 if (result == null) { 1431 pool.putByte(LONG).putLong(value); 1432 result = new Item(index, key); 1433 index += 2; 1434 put(result); 1435 } 1436 return result; 1437 } 1438 1439 /** 1440 * Adds a double to the constant pool of the class being build. Does nothing 1441 * if the constant pool already contains a similar item. 1442 * 1443 * @param value the double value. 1444 * @return a new or already existing double item. 1445 */ 1446 Item newDouble(final double value) { 1447 key.set(value); 1448 Item result = get(key); 1449 if (result == null) { 1450 pool.putByte(DOUBLE).putLong(key.longVal); 1451 result = new Item(index, key); 1452 index += 2; 1453 put(result); 1454 } 1455 return result; 1456 } 1457 1458 /** 1459 * Adds a string to the constant pool of the class being build. Does nothing 1460 * if the constant pool already contains a similar item. 1461 * 1462 * @param value the String value. 1463 * @return a new or already existing string item. 1464 */ 1465 private Item newString(final String value) { 1466 key2.set(STR, value, null, null); 1467 Item result = get(key2); 1468 if (result == null) { 1469 pool.put12(STR, newUTF8(value)); 1470 result = new Item(index++, key2); 1471 put(result); 1472 } 1473 return result; 1474 } 1475 1476 /** 1477 * Adds a name and type to the constant pool of the class being build. Does 1478 * nothing if the constant pool already contains a similar item. <i>This 1479 * method is intended for {@link Attribute} sub classes, and is normally not 1480 * needed by class generators or adapters.</i> 1481 * 1482 * @param name a name. 1483 * @param desc a type descriptor. 1484 * @return the index of a new or already existing name and type item. 1485 */ 1486 public int newNameType(final String name, final String desc) { 1487 return newNameTypeItem(name, desc).index; 1488 } 1489 1490 /** 1491 * Adds a name and type to the constant pool of the class being build. Does 1492 * nothing if the constant pool already contains a similar item. 1493 * 1494 * @param name a name. 1495 * @param desc a type descriptor. 1496 * @return a new or already existing name and type item. 1497 */ 1498 Item newNameTypeItem(final String name, final String desc) { 1499 key2.set(NAME_TYPE, name, desc, null); 1500 Item result = get(key2); 1501 if (result == null) { 1502 put122(NAME_TYPE, newUTF8(name), newUTF8(desc)); 1503 result = new Item(index++, key2); 1504 put(result); 1505 } 1506 return result; 1507 } 1508 1509 /** 1510 * Adds the given internal name to {@link #typeTable} and returns its index. 1511 * Does nothing if the type table already contains this internal name. 1512 * 1513 * @param type the internal name to be added to the type table. 1514 * @return the index of this internal name in the type table. 1515 */ 1516 int addType(final String type) { 1517 key.set(TYPE_NORMAL, type, null, null); 1518 Item result = get(key); 1519 if (result == null) { 1520 result = addType(key); 1521 } 1522 return result.index; 1523 } 1524 1525 /** 1526 * Adds the given "uninitialized" type to {@link #typeTable} and returns its 1527 * index. This method is used for UNINITIALIZED types, made of an internal 1528 * name and a bytecode offset. 1529 * 1530 * @param type the internal name to be added to the type table. 1531 * @param offset the bytecode offset of the NEW instruction that created 1532 * this UNINITIALIZED type value. 1533 * @return the index of this internal name in the type table. 1534 */ 1535 int addUninitializedType(final String type, final int offset) { 1536 key.type = TYPE_UNINIT; 1537 key.intVal = offset; 1538 key.strVal1 = type; 1539 key.hashCode = 0x7FFFFFFF & (TYPE_UNINIT + type.hashCode() + offset); 1540 Item result = get(key); 1541 if (result == null) { 1542 result = addType(key); 1543 } 1544 return result.index; 1545 } 1546 1547 /** 1548 * Adds the given Item to {@link #typeTable}. 1549 * 1550 * @param item the value to be added to the type table. 1551 * @return the added Item, which a new Item instance with the same value as 1552 * the given Item. 1553 */ 1554 private Item addType(final Item item) { 1555 ++typeCount; 1556 Item result = new Item(typeCount, key); 1557 put(result); 1558 if (typeTable == null) { 1559 typeTable = new Item[16]; 1560 } 1561 if (typeCount == typeTable.length) { 1562 Item[] newTable = new Item[2 * typeTable.length]; 1563 System.arraycopy(typeTable, 0, newTable, 0, typeTable.length); 1564 typeTable = newTable; 1565 } 1566 typeTable[typeCount] = result; 1567 return result; 1568 } 1569 1570 /** 1571 * Returns the index of the common super type of the two given types. This 1572 * method calls {@link #getCommonSuperClass} and caches the result in the 1573 * {@link #items} hash table to speedup future calls with the same 1574 * parameters. 1575 * 1576 * @param type1 index of an internal name in {@link #typeTable}. 1577 * @param type2 index of an internal name in {@link #typeTable}. 1578 * @return the index of the common super type of the two given types. 1579 */ 1580 int getMergedType(final int type1, final int type2) { 1581 key2.type = TYPE_MERGED; 1582 key2.longVal = type1 | (((long) type2) << 32); 1583 key2.hashCode = 0x7FFFFFFF & (TYPE_MERGED + type1 + type2); 1584 Item result = get(key2); 1585 if (result == null) { 1586 String t = typeTable[type1].strVal1; 1587 String u = typeTable[type2].strVal1; 1588 key2.intVal = addType(getCommonSuperClass(t, u)); 1589 result = new Item((short) 0, key2); 1590 put(result); 1591 } 1592 return result.intVal; 1593 } 1594 1595 /** 1596 * Returns the common super type of the two given types. The default 1597 * implementation of this method <i>loads<i> the two given classes and uses 1598 * the java.lang.Class methods to find the common super class. It can be 1599 * overridden to compute this common super type in other ways, in particular 1600 * without actually loading any class, or to take into account the class 1601 * that is currently being generated by this ClassWriter, which can of 1602 * course not be loaded since it is under construction. 1603 * 1604 * @param type1 the internal name of a class. 1605 * @param type2 the internal name of another class. 1606 * @return the internal name of the common super class of the two given 1607 * classes. 1608 */ 1609 protected String getCommonSuperClass(final String type1, final String type2) 1610 { 1611 Class<?> c, d; 1612 ClassLoader classLoader = getClass().getClassLoader(); 1613 try { 1614 c = Class.forName(type1.replace('/', '.'), false, classLoader); 1615 d = Class.forName(type2.replace('/', '.'), false, classLoader); 1616 } catch (Exception e) { 1617 throw new RuntimeException(e.toString()); 1618 } 1619 if (c.isAssignableFrom(d)) { 1620 return type1; 1621 } 1622 if (d.isAssignableFrom(c)) { 1623 return type2; 1624 } 1625 if (c.isInterface() || d.isInterface()) { 1626 return "java/lang/Object"; 1627 } else { 1628 do { 1629 c = c.getSuperclass(); 1630 } while (!c.isAssignableFrom(d)); 1631 return c.getName().replace('.', '/'); 1632 } 1633 } 1634 1635 /** 1636 * Returns the constant pool's hash table item which is equal to the given 1637 * item. 1638 * 1639 * @param key a constant pool item. 1640 * @return the constant pool's hash table item which is equal to the given 1641 * item, or <tt>null</tt> if there is no such item. 1642 */ 1643 private Item get(final Item key) { 1644 Item i = items[key.hashCode % items.length]; 1645 while (i != null && (i.type != key.type || !key.isEqualTo(i))) { 1646 i = i.next; 1647 } 1648 return i; 1649 } 1650 1651 /** 1652 * Puts the given item in the constant pool's hash table. The hash table 1653 * <i>must</i> not already contains this item. 1654 * 1655 * @param i the item to be added to the constant pool's hash table. 1656 */ 1657 private void put(final Item i) { 1658 if (index + typeCount > threshold) { 1659 int ll = items.length; 1660 int nl = ll * 2 + 1; 1661 Item[] newItems = new Item[nl]; 1662 for (int l = ll - 1; l >= 0; --l) { 1663 Item j = items[l]; 1664 while (j != null) { 1665 int index = j.hashCode % newItems.length; 1666 Item k = j.next; 1667 j.next = newItems[index]; 1668 newItems[index] = j; 1669 j = k; 1670 } 1671 } 1672 items = newItems; 1673 threshold = (int) (nl * 0.75); 1674 } 1675 int index = i.hashCode % items.length; 1676 i.next = items[index]; 1677 items[index] = i; 1678 } 1679 1680 /** 1681 * Puts one byte and two shorts into the constant pool. 1682 * 1683 * @param b a byte. 1684 * @param s1 a short. 1685 * @param s2 another short. 1686 */ 1687 private void put122(final int b, final int s1, final int s2) { 1688 pool.put12(b, s1).putShort(s2); 1689 } 1690 1691 /** 1692 * Puts two bytes and one short into the constant pool. 1693 * 1694 * @param b1 a byte. 1695 * @param b2 another byte. 1696 * @param s a short. 1697 */ 1698 private void put112(final int b1, final int b2, final int s) { 1699 pool.put11(b1, b2).putShort(s); 1700 } 1701 } | 78 * the bytecode of each method. 79 * 80 * @see #ClassWriter(int) 81 */ 82 public static final int COMPUTE_MAXS = 1; 83 84 /** 85 * Flag to automatically compute the stack map frames of methods from 86 * scratch. If this flag is set, then the calls to the 87 * {@link MethodVisitor#visitFrame} method are ignored, and the stack map 88 * frames are recomputed from the methods bytecode. The arguments of the 89 * {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and 90 * recomputed from the bytecode. In other words, computeFrames implies 91 * computeMaxs. 92 * 93 * @see #ClassWriter(int) 94 */ 95 public static final int COMPUTE_FRAMES = 2; 96 97 /** 98 * Pseudo access flag to distinguish between the synthetic attribute and the 99 * synthetic access flag. 100 */ 101 static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000; 102 103 /** 104 * Factor to convert from ACC_SYNTHETIC_ATTRIBUTE to Opcode.ACC_SYNTHETIC. 105 */ 106 static final int TO_ACC_SYNTHETIC = ACC_SYNTHETIC_ATTRIBUTE 107 / Opcodes.ACC_SYNTHETIC; 108 109 /** 110 * The type of instructions without any argument. 111 */ 112 static final int NOARG_INSN = 0; 113 114 /** 115 * The type of instructions with an signed byte argument. 116 */ 117 static final int SBYTE_INSN = 1; 118 119 /** 120 * The type of instructions with an signed short argument. 121 */ 122 static final int SHORT_INSN = 2; 123 124 /** 125 * The type of instructions with a local variable index argument. 126 */ 127 static final int VAR_INSN = 3; 128 129 /** 256 */ 257 static final int UTF8 = 1; 258 259 /** 260 * The type of CONSTANT_MethodType constant pool items. 261 */ 262 static final int MTYPE = 16; 263 264 /** 265 * The type of CONSTANT_MethodHandle constant pool items. 266 */ 267 static final int HANDLE = 15; 268 269 /** 270 * The type of CONSTANT_InvokeDynamic constant pool items. 271 */ 272 static final int INDY = 18; 273 274 /** 275 * The base value for all CONSTANT_MethodHandle constant pool items. 276 * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9 277 * different items. 278 */ 279 static final int HANDLE_BASE = 20; 280 281 /** 282 * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable}, 283 * instead of the constant pool, in order to avoid clashes with normal 284 * constant pool items in the ClassWriter constant pool's hash table. 285 */ 286 static final int TYPE_NORMAL = 30; 287 288 /** 289 * Uninitialized type Item stored in the ClassWriter 290 * {@link ClassWriter#typeTable}, instead of the constant pool, in order to 291 * avoid clashes with normal constant pool items in the ClassWriter constant 292 * pool's hash table. 293 */ 294 static final int TYPE_UNINIT = 31; 295 296 /** 297 * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable}, 298 * instead of the constant pool, in order to avoid clashes with normal 299 * constant pool items in the ClassWriter constant pool's hash table. 300 */ 301 static final int TYPE_MERGED = 32; 302 303 /** 304 * The type of BootstrapMethods items. These items are stored in a special 305 * class attribute named BootstrapMethods and not in the constant pool. 306 */ 307 static final int BSM = 33; 308 309 /** 310 * The class reader from which this class writer was constructed, if any. 311 */ 312 ClassReader cr; 313 314 /** 315 * Minor and major version numbers of the class to be generated. 316 */ 317 int version; 318 319 /** 320 * Index of the next item to be added in the constant pool. 321 */ 322 int index; 323 324 /** 325 * The constant pool of this class. 344 /** 345 * A reusable key used to look for items in the {@link #items} hash table. 346 */ 347 final Item key2; 348 349 /** 350 * A reusable key used to look for items in the {@link #items} hash table. 351 */ 352 final Item key3; 353 354 /** 355 * A reusable key used to look for items in the {@link #items} hash table. 356 */ 357 final Item key4; 358 359 /** 360 * A type table used to temporarily store internal names that will not 361 * necessarily be stored in the constant pool. This type table is used by 362 * the control flow and data flow analysis algorithm used to compute stack 363 * map frames from scratch. This array associates to each index <tt>i</tt> 364 * the Item whose index is <tt>i</tt>. All Item objects stored in this array 365 * are also stored in the {@link #items} hash table. These two arrays allow 366 * to retrieve an Item from its index or, conversely, to get the index of an 367 * Item from its value. Each Item stores an internal name in its 368 * {@link Item#strVal1} field. 369 */ 370 Item[] typeTable; 371 372 /** 373 * Number of elements in the {@link #typeTable} array. 374 */ 375 private short typeCount; 376 377 /** 378 * The access flags of this class. 379 */ 380 private int access; 381 382 /** 383 * The constant pool item that contains the internal name of this class. 384 */ 385 private int name; 386 387 /** 429 */ 430 private int enclosingMethodOwner; 431 432 /** 433 * The constant pool item that contains the name and descriptor of the 434 * enclosing method of this class. 435 */ 436 private int enclosingMethod; 437 438 /** 439 * The runtime visible annotations of this class. 440 */ 441 private AnnotationWriter anns; 442 443 /** 444 * The runtime invisible annotations of this class. 445 */ 446 private AnnotationWriter ianns; 447 448 /** 449 * The runtime visible type annotations of this class. 450 */ 451 private AnnotationWriter tanns; 452 453 /** 454 * The runtime invisible type annotations of this class. 455 */ 456 private AnnotationWriter itanns; 457 458 /** 459 * The non standard attributes of this class. 460 */ 461 private Attribute attrs; 462 463 /** 464 * The number of entries in the InnerClasses attribute. 465 */ 466 private int innerClassesCount; 467 468 /** 469 * The InnerClasses attribute. 470 */ 471 private ByteVector innerClasses; 472 473 /** 474 * The number of entries in the BootstrapMethods attribute. 475 */ 476 int bootstrapMethodsCount; 477 478 /** 479 * The BootstrapMethods attribute. 480 */ 481 ByteVector bootstrapMethods; 482 483 /** 484 * The fields of this class. These fields are stored in a linked list of 485 * {@link FieldWriter} objects, linked to each other by their 486 * {@link FieldWriter#fv} field. This field stores the first element of this 487 * list. 488 */ 489 FieldWriter firstField; 490 491 /** 492 * The fields of this class. These fields are stored in a linked list of 493 * {@link FieldWriter} objects, linked to each other by their 494 * {@link FieldWriter#fv} field. This field stores the last element of this 495 * list. 496 */ 497 FieldWriter lastField; 498 499 /** 500 * The methods of this class. These methods are stored in a linked list of 501 * {@link MethodWriter} objects, linked to each other by their 502 * {@link MethodWriter#mv} field. This field stores the first element of 503 * this list. 504 */ 505 MethodWriter firstMethod; 506 507 /** 508 * The methods of this class. These methods are stored in a linked list of 509 * {@link MethodWriter} objects, linked to each other by their 510 * {@link MethodWriter#mv} field. This field stores the last element of this 511 * list. 512 */ 513 MethodWriter lastMethod; 514 515 /** 516 * <tt>true</tt> if the maximum stack size and number of local variables 517 * must be automatically computed. 518 */ 519 private final boolean computeMaxs; 520 521 /** 522 * <tt>true</tt> if the stack map frames must be recomputed from scratch. 523 */ 524 private final boolean computeFrames; 525 526 /** 527 * <tt>true</tt> if the stack map tables of this class are invalid. The 528 * {@link MethodWriter#resizeInstructions} method cannot transform existing 529 * stack map tables, and so produces potentially invalid classes when it is 530 * executed. In this case the class is reread and rewritten with the 531 * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize 611 // // special instructions 612 // b[Constants.IINC] = IINC_INSN; 613 // b[Constants.TABLESWITCH] = TABL_INSN; 614 // b[Constants.LOOKUPSWITCH] = LOOK_INSN; 615 // b[Constants.MULTIANEWARRAY] = MANA_INSN; 616 // b[196] = WIDE_INSN; // WIDE 617 // 618 // for (i = 0; i < b.length; ++i) { 619 // System.err.print((char)('A' + b[i])); 620 // } 621 // System.err.println(); 622 } 623 624 // ------------------------------------------------------------------------ 625 // Constructor 626 // ------------------------------------------------------------------------ 627 628 /** 629 * Constructs a new {@link ClassWriter} object. 630 * 631 * @param flags 632 * option flags that can be used to modify the default behavior 633 * of this class. See {@link #COMPUTE_MAXS}, 634 * {@link #COMPUTE_FRAMES}. 635 */ 636 public ClassWriter(final int flags) { 637 super(Opcodes.ASM5); 638 index = 1; 639 pool = new ByteVector(); 640 items = new Item[256]; 641 threshold = (int) (0.75d * items.length); 642 key = new Item(); 643 key2 = new Item(); 644 key3 = new Item(); 645 key4 = new Item(); 646 this.computeMaxs = (flags & COMPUTE_MAXS) != 0; 647 this.computeFrames = (flags & COMPUTE_FRAMES) != 0; 648 } 649 650 /** 651 * Constructs a new {@link ClassWriter} object and enables optimizations for 652 * "mostly add" bytecode transformations. These optimizations are the 653 * following: 654 * 655 * <ul> 656 * <li>The constant pool from the original class is copied as is in the new 657 * class, which saves time. New constant pool entries will be added at the 658 * end if necessary, but unused constant pool entries <i>won't be 659 * removed</i>.</li> 660 * <li>Methods that are not transformed are copied as is in the new class, 661 * directly from the original class bytecode (i.e. without emitting visit 662 * events for all the method instructions), which saves a <i>lot</i> of 663 * time. Untransformed methods are detected by the fact that the 664 * {@link ClassReader} receives {@link MethodVisitor} objects that come from 665 * a {@link ClassWriter} (and not from any other {@link ClassVisitor} 666 * instance).</li> 667 * </ul> 668 * 669 * @param classReader 670 * the {@link ClassReader} used to read the original class. It 671 * will be used to copy the entire constant pool from the 672 * original class and also to copy other fragments of original 673 * bytecode where applicable. 674 * @param flags 675 * option flags that can be used to modify the default behavior 676 * of this class. <i>These option flags do not affect methods 677 * that are copied as is in the new class. This means that the 678 * maximum stack size nor the stack frames will be computed for 679 * these methods</i>. See {@link #COMPUTE_MAXS}, 680 * {@link #COMPUTE_FRAMES}. 681 */ 682 public ClassWriter(final ClassReader classReader, final int flags) { 683 this(flags); 684 classReader.copyPool(this); 685 this.cr = classReader; 686 } 687 688 // ------------------------------------------------------------------------ 689 // Implementation of the ClassVisitor abstract class 690 // ------------------------------------------------------------------------ 691 692 @Override 693 public final void visit(final int version, final int access, 694 final String name, final String signature, final String superName, 695 final String[] interfaces) { 696 this.version = version; 697 this.access = access; 698 this.name = newClass(name); 699 thisName = name; 700 if (ClassReader.SIGNATURES && signature != null) { 701 this.signature = newUTF8(signature); 702 } 703 this.superName = superName == null ? 0 : newClass(superName); 704 if (interfaces != null && interfaces.length > 0) { 705 interfaceCount = interfaces.length; 706 this.interfaces = new int[interfaceCount]; 707 for (int i = 0; i < interfaceCount; ++i) { 708 this.interfaces[i] = newClass(interfaces[i]); 709 } 710 } 711 } 712 713 @Override 714 public final void visitSource(final String file, final String debug) { 715 if (file != null) { 716 sourceFile = newUTF8(file); 717 } 718 if (debug != null) { 719 sourceDebug = new ByteVector().putUTF8(debug); 720 } 721 } 722 723 @Override 724 public final void visitOuterClass(final String owner, final String name, 725 final String desc) { 726 enclosingMethodOwner = newClass(owner); 727 if (name != null && desc != null) { 728 enclosingMethod = newNameType(name, desc); 729 } 730 } 731 732 @Override 733 public final AnnotationVisitor visitAnnotation(final String desc, 734 final boolean visible) { 735 if (!ClassReader.ANNOTATIONS) { 736 return null; 737 } 738 ByteVector bv = new ByteVector(); 739 // write type, and reserve space for values count 740 bv.putShort(newUTF8(desc)).putShort(0); 741 AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2); 742 if (visible) { 743 aw.next = anns; 744 anns = aw; 745 } else { 746 aw.next = ianns; 747 ianns = aw; 748 } 749 return aw; 750 } 751 752 @Override 753 public final AnnotationVisitor visitTypeAnnotation(int typeRef, 754 TypePath typePath, final String desc, final boolean visible) { 755 if (!ClassReader.ANNOTATIONS) { 756 return null; 757 } 758 ByteVector bv = new ByteVector(); 759 // write target_type and target_info 760 AnnotationWriter.putTarget(typeRef, typePath, bv); 761 // write type, and reserve space for values count 762 bv.putShort(newUTF8(desc)).putShort(0); 763 AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 764 bv.length - 2); 765 if (visible) { 766 aw.next = tanns; 767 tanns = aw; 768 } else { 769 aw.next = itanns; 770 itanns = aw; 771 } 772 return aw; 773 } 774 775 @Override 776 public final void visitAttribute(final Attribute attr) { 777 attr.next = attrs; 778 attrs = attr; 779 } 780 781 @Override 782 public final void visitInnerClass(final String name, 783 final String outerName, final String innerName, final int access) { 784 if (innerClasses == null) { 785 innerClasses = new ByteVector(); 786 } 787 ++innerClassesCount; 788 innerClasses.putShort(name == null ? 0 : newClass(name)); 789 innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); 790 innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); 791 innerClasses.putShort(access); 792 } 793 794 @Override 795 public final FieldVisitor visitField(final int access, final String name, 796 final String desc, final String signature, final Object value) { 797 return new FieldWriter(this, access, name, desc, signature, value); 798 } 799 800 @Override 801 public final MethodVisitor visitMethod(final int access, final String name, 802 final String desc, final String signature, final String[] exceptions) { 803 return new MethodWriter(this, access, name, desc, signature, 804 exceptions, computeMaxs, computeFrames); 805 } 806 807 @Override 808 public final void visitEnd() { 809 } 810 811 // ------------------------------------------------------------------------ 812 // Other public methods 813 // ------------------------------------------------------------------------ 814 815 /** 816 * Returns the bytecode of the class that was build with this class writer. 817 * 818 * @return the bytecode of the class that was build with this class writer. 819 */ 820 public byte[] toByteArray() { 821 if (index > 0xFFFF) { 822 throw new RuntimeException("Class file too large!"); 823 } 824 // computes the real size of the bytecode of this class 825 int size = 24 + 2 * interfaceCount; 826 int nbFields = 0; 827 FieldWriter fb = firstField; 828 while (fb != null) { 829 ++nbFields; 830 size += fb.getSize(); 831 fb = (FieldWriter) fb.fv; 832 } 833 int nbMethods = 0; 834 MethodWriter mb = firstMethod; 835 while (mb != null) { 836 ++nbMethods; 837 size += mb.getSize(); 838 mb = (MethodWriter) mb.mv; 839 } 840 int attributeCount = 0; 841 if (bootstrapMethods != null) { 842 // we put it as first attribute in order to improve a bit 843 // ClassReader.copyBootstrapMethods 844 ++attributeCount; 845 size += 8 + bootstrapMethods.length; 846 newUTF8("BootstrapMethods"); 847 } 848 if (ClassReader.SIGNATURES && signature != 0) { 849 ++attributeCount; 850 size += 8; 851 newUTF8("Signature"); 852 } 853 if (sourceFile != 0) { 854 ++attributeCount; 855 size += 8; 856 newUTF8("SourceFile"); 857 } 858 if (sourceDebug != null) { 859 ++attributeCount; 860 size += sourceDebug.length + 4; 861 newUTF8("SourceDebugExtension"); 862 } 863 if (enclosingMethodOwner != 0) { 864 ++attributeCount; 865 size += 10; 866 newUTF8("EnclosingMethod"); 867 } 868 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 869 ++attributeCount; 870 size += 6; 871 newUTF8("Deprecated"); 872 } 873 if ((access & Opcodes.ACC_SYNTHETIC) != 0) { 874 if ((version & 0xFFFF) < Opcodes.V1_5 875 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) { 876 ++attributeCount; 877 size += 6; 878 newUTF8("Synthetic"); 879 } 880 } 881 if (innerClasses != null) { 882 ++attributeCount; 883 size += 8 + innerClasses.length; 884 newUTF8("InnerClasses"); 885 } 886 if (ClassReader.ANNOTATIONS && anns != null) { 887 ++attributeCount; 888 size += 8 + anns.getSize(); 889 newUTF8("RuntimeVisibleAnnotations"); 890 } 891 if (ClassReader.ANNOTATIONS && ianns != null) { 892 ++attributeCount; 893 size += 8 + ianns.getSize(); 894 newUTF8("RuntimeInvisibleAnnotations"); 895 } 896 if (ClassReader.ANNOTATIONS && tanns != null) { 897 ++attributeCount; 898 size += 8 + tanns.getSize(); 899 newUTF8("RuntimeVisibleTypeAnnotations"); 900 } 901 if (ClassReader.ANNOTATIONS && itanns != null) { 902 ++attributeCount; 903 size += 8 + itanns.getSize(); 904 newUTF8("RuntimeInvisibleTypeAnnotations"); 905 } 906 if (attrs != null) { 907 attributeCount += attrs.getCount(); 908 size += attrs.getSize(this, null, 0, -1, -1); 909 } 910 size += pool.length; 911 // allocates a byte vector of this size, in order to avoid unnecessary 912 // arraycopy operations in the ByteVector.enlarge() method 913 ByteVector out = new ByteVector(size); 914 out.putInt(0xCAFEBABE).putInt(version); 915 out.putShort(index).putByteArray(pool.data, 0, pool.length); 916 int mask = Opcodes.ACC_DEPRECATED | ACC_SYNTHETIC_ATTRIBUTE 917 | ((access & ACC_SYNTHETIC_ATTRIBUTE) / TO_ACC_SYNTHETIC); 918 out.putShort(access & ~mask).putShort(name).putShort(superName); 919 out.putShort(interfaceCount); 920 for (int i = 0; i < interfaceCount; ++i) { 921 out.putShort(interfaces[i]); 922 } 923 out.putShort(nbFields); 924 fb = firstField; 925 while (fb != null) { 926 fb.put(out); 927 fb = (FieldWriter) fb.fv; 928 } 929 out.putShort(nbMethods); 930 mb = firstMethod; 931 while (mb != null) { 932 mb.put(out); 933 mb = (MethodWriter) mb.mv; 934 } 935 out.putShort(attributeCount); 936 if (bootstrapMethods != null) { 937 out.putShort(newUTF8("BootstrapMethods")); 938 out.putInt(bootstrapMethods.length + 2).putShort( 939 bootstrapMethodsCount); 940 out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length); 941 } 942 if (ClassReader.SIGNATURES && signature != 0) { 943 out.putShort(newUTF8("Signature")).putInt(2).putShort(signature); 944 } 945 if (sourceFile != 0) { 946 out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile); 947 } 948 if (sourceDebug != null) { 949 int len = sourceDebug.length - 2; 950 out.putShort(newUTF8("SourceDebugExtension")).putInt(len); 951 out.putByteArray(sourceDebug.data, 2, len); 952 } 953 if (enclosingMethodOwner != 0) { 954 out.putShort(newUTF8("EnclosingMethod")).putInt(4); 955 out.putShort(enclosingMethodOwner).putShort(enclosingMethod); 956 } 957 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 958 out.putShort(newUTF8("Deprecated")).putInt(0); 959 } 960 if ((access & Opcodes.ACC_SYNTHETIC) != 0) { 961 if ((version & 0xFFFF) < Opcodes.V1_5 962 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) { 963 out.putShort(newUTF8("Synthetic")).putInt(0); 964 } 965 } 966 if (innerClasses != null) { 967 out.putShort(newUTF8("InnerClasses")); 968 out.putInt(innerClasses.length + 2).putShort(innerClassesCount); 969 out.putByteArray(innerClasses.data, 0, innerClasses.length); 970 } 971 if (ClassReader.ANNOTATIONS && anns != null) { 972 out.putShort(newUTF8("RuntimeVisibleAnnotations")); 973 anns.put(out); 974 } 975 if (ClassReader.ANNOTATIONS && ianns != null) { 976 out.putShort(newUTF8("RuntimeInvisibleAnnotations")); 977 ianns.put(out); 978 } 979 if (ClassReader.ANNOTATIONS && tanns != null) { 980 out.putShort(newUTF8("RuntimeVisibleTypeAnnotations")); 981 tanns.put(out); 982 } 983 if (ClassReader.ANNOTATIONS && itanns != null) { 984 out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations")); 985 itanns.put(out); 986 } 987 if (attrs != null) { 988 attrs.put(this, null, 0, -1, -1, out); 989 } 990 if (invalidFrames) { 991 ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); 992 new ClassReader(out.data).accept(cw, ClassReader.SKIP_FRAMES); 993 return cw.toByteArray(); 994 } 995 return out.data; 996 } 997 998 // ------------------------------------------------------------------------ 999 // Utility methods: constant pool management 1000 // ------------------------------------------------------------------------ 1001 1002 /** 1003 * Adds a number or string constant to the constant pool of the class being 1004 * build. Does nothing if the constant pool already contains a similar item. 1005 * 1006 * @param cst 1007 * the value of the constant to be added to the constant pool. 1008 * This parameter must be an {@link Integer}, a {@link Float}, a 1009 * {@link Long}, a {@link Double}, a {@link String} or a 1010 * {@link Type}. 1011 * @return a new or already existing constant item with the given value. 1012 */ 1013 Item newConstItem(final Object cst) { 1014 if (cst instanceof Integer) { 1015 int val = ((Integer) cst).intValue(); 1016 return newInteger(val); 1017 } else if (cst instanceof Byte) { 1018 int val = ((Byte) cst).intValue(); 1019 return newInteger(val); 1020 } else if (cst instanceof Character) { 1021 int val = ((Character) cst).charValue(); 1022 return newInteger(val); 1023 } else if (cst instanceof Short) { 1024 int val = ((Short) cst).intValue(); 1025 return newInteger(val); 1026 } else if (cst instanceof Boolean) { 1027 int val = ((Boolean) cst).booleanValue() ? 1 : 0; 1028 return newInteger(val); 1029 } else if (cst instanceof Float) { 1030 float val = ((Float) cst).floatValue(); 1031 return newFloat(val); 1032 } else if (cst instanceof Long) { 1033 long val = ((Long) cst).longValue(); 1034 return newLong(val); 1035 } else if (cst instanceof Double) { 1036 double val = ((Double) cst).doubleValue(); 1037 return newDouble(val); 1038 } else if (cst instanceof String) { 1039 return newString((String) cst); 1040 } else if (cst instanceof Type) { 1041 Type t = (Type) cst; 1042 int s = t.getSort(); 1043 if (s == Type.OBJECT) { 1044 return newClassItem(t.getInternalName()); 1045 } else if (s == Type.METHOD) { 1046 return newMethodTypeItem(t.getDescriptor()); 1047 } else { // s == primitive type or array 1048 return newClassItem(t.getDescriptor()); 1049 } 1050 } else if (cst instanceof Handle) { 1051 Handle h = (Handle) cst; 1052 return newHandleItem(h.tag, h.owner, h.name, h.desc); 1053 } else { 1054 throw new IllegalArgumentException("value " + cst); 1055 } 1056 } 1057 1058 /** 1059 * Adds a number or string constant to the constant pool of the class being 1060 * build. Does nothing if the constant pool already contains a similar item. 1061 * <i>This method is intended for {@link Attribute} sub classes, and is 1062 * normally not needed by class generators or adapters.</i> 1063 * 1064 * @param cst 1065 * the value of the constant to be added to the constant pool. 1066 * This parameter must be an {@link Integer}, a {@link Float}, a 1067 * {@link Long}, a {@link Double} or a {@link String}. 1068 * @return the index of a new or already existing constant item with the 1069 * given value. 1070 */ 1071 public int newConst(final Object cst) { 1072 return newConstItem(cst).index; 1073 } 1074 1075 /** 1076 * Adds an UTF8 string to the constant pool of the class being build. Does 1077 * nothing if the constant pool already contains a similar item. <i>This 1078 * method is intended for {@link Attribute} sub classes, and is normally not 1079 * needed by class generators or adapters.</i> 1080 * 1081 * @param value 1082 * the String value. 1083 * @return the index of a new or already existing UTF8 item. 1084 */ 1085 public int newUTF8(final String value) { 1086 key.set(UTF8, value, null, null); 1087 Item result = get(key); 1088 if (result == null) { 1089 pool.putByte(UTF8).putUTF8(value); 1090 result = new Item(index++, key); 1091 put(result); 1092 } 1093 return result.index; 1094 } 1095 1096 /** 1097 * Adds a class reference to the constant pool of the class being build. 1098 * Does nothing if the constant pool already contains a similar item. 1099 * <i>This method is intended for {@link Attribute} sub classes, and is 1100 * normally not needed by class generators or adapters.</i> 1101 * 1102 * @param value 1103 * the internal name of the class. 1104 * @return a new or already existing class reference item. 1105 */ 1106 Item newClassItem(final String value) { 1107 key2.set(CLASS, value, null, null); 1108 Item result = get(key2); 1109 if (result == null) { 1110 pool.put12(CLASS, newUTF8(value)); 1111 result = new Item(index++, key2); 1112 put(result); 1113 } 1114 return result; 1115 } 1116 1117 /** 1118 * Adds a class reference to the constant pool of the class being build. 1119 * Does nothing if the constant pool already contains a similar item. 1120 * <i>This method is intended for {@link Attribute} sub classes, and is 1121 * normally not needed by class generators or adapters.</i> 1122 * 1123 * @param value 1124 * the internal name of the class. 1125 * @return the index of a new or already existing class reference item. 1126 */ 1127 public int newClass(final String value) { 1128 return newClassItem(value).index; 1129 } 1130 1131 /** 1132 * Adds a method type reference to the constant pool of the class being 1133 * build. Does nothing if the constant pool already contains a similar item. 1134 * <i>This method is intended for {@link Attribute} sub classes, and is 1135 * normally not needed by class generators or adapters.</i> 1136 * 1137 * @param methodDesc 1138 * method descriptor of the method type. 1139 * @return a new or already existing method type reference item. 1140 */ 1141 Item newMethodTypeItem(final String methodDesc) { 1142 key2.set(MTYPE, methodDesc, null, null); 1143 Item result = get(key2); 1144 if (result == null) { 1145 pool.put12(MTYPE, newUTF8(methodDesc)); 1146 result = new Item(index++, key2); 1147 put(result); 1148 } 1149 return result; 1150 } 1151 1152 /** 1153 * Adds a method type reference to the constant pool of the class being 1154 * build. Does nothing if the constant pool already contains a similar item. 1155 * <i>This method is intended for {@link Attribute} sub classes, and is 1156 * normally not needed by class generators or adapters.</i> 1157 * 1158 * @param methodDesc 1159 * method descriptor of the method type. 1160 * @return the index of a new or already existing method type reference 1161 * item. 1162 */ 1163 public int newMethodType(final String methodDesc) { 1164 return newMethodTypeItem(methodDesc).index; 1165 } 1166 1167 /** 1168 * Adds a handle to the constant pool of the class being build. Does nothing 1169 * if the constant pool already contains a similar item. <i>This method is 1170 * intended for {@link Attribute} sub classes, and is normally not needed by 1171 * class generators or adapters.</i> 1172 * 1173 * @param tag 1174 * the kind of this handle. Must be {@link Opcodes#H_GETFIELD}, 1175 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, 1176 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, 1177 * {@link Opcodes#H_INVOKESTATIC}, 1178 * {@link Opcodes#H_INVOKESPECIAL}, 1179 * {@link Opcodes#H_NEWINVOKESPECIAL} or 1180 * {@link Opcodes#H_INVOKEINTERFACE}. 1181 * @param owner 1182 * the internal name of the field or method owner class. 1183 * @param name 1184 * the name of the field or method. 1185 * @param desc 1186 * the descriptor of the field or method. 1187 * @return a new or an already existing method type reference item. 1188 */ 1189 Item newHandleItem(final int tag, final String owner, final String name, 1190 final String desc) { 1191 key4.set(HANDLE_BASE + tag, owner, name, desc); 1192 Item result = get(key4); 1193 if (result == null) { 1194 if (tag <= Opcodes.H_PUTSTATIC) { 1195 put112(HANDLE, tag, newField(owner, name, desc)); 1196 } else { 1197 put112(HANDLE, 1198 tag, 1199 newMethod(owner, name, desc, 1200 tag == Opcodes.H_INVOKEINTERFACE)); 1201 } 1202 result = new Item(index++, key4); 1203 put(result); 1204 } 1205 return result; 1206 } 1207 1208 /** 1209 * Adds a handle to the constant pool of the class being build. Does nothing 1210 * if the constant pool already contains a similar item. <i>This method is 1211 * intended for {@link Attribute} sub classes, and is normally not needed by 1212 * class generators or adapters.</i> 1213 * 1214 * @param tag 1215 * the kind of this handle. Must be {@link Opcodes#H_GETFIELD}, 1216 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, 1217 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, 1218 * {@link Opcodes#H_INVOKESTATIC}, 1219 * {@link Opcodes#H_INVOKESPECIAL}, 1220 * {@link Opcodes#H_NEWINVOKESPECIAL} or 1221 * {@link Opcodes#H_INVOKEINTERFACE}. 1222 * @param owner 1223 * the internal name of the field or method owner class. 1224 * @param name 1225 * the name of the field or method. 1226 * @param desc 1227 * the descriptor of the field or method. 1228 * @return the index of a new or already existing method type reference 1229 * item. 1230 */ 1231 public int newHandle(final int tag, final String owner, final String name, 1232 final String desc) { 1233 return newHandleItem(tag, owner, name, desc).index; 1234 } 1235 1236 /** 1237 * Adds an invokedynamic reference to the constant pool of the class being 1238 * build. Does nothing if the constant pool already contains a similar item. 1239 * <i>This method is intended for {@link Attribute} sub classes, and is 1240 * normally not needed by class generators or adapters.</i> 1241 * 1242 * @param name 1243 * name of the invoked method. 1244 * @param desc 1245 * descriptor of the invoke method. 1246 * @param bsm 1247 * the bootstrap method. 1248 * @param bsmArgs 1249 * the bootstrap method constant arguments. 1250 * 1251 * @return a new or an already existing invokedynamic type reference item. 1252 */ 1253 Item newInvokeDynamicItem(final String name, final String desc, 1254 final Handle bsm, final Object... bsmArgs) { 1255 // cache for performance 1256 ByteVector bootstrapMethods = this.bootstrapMethods; 1257 if (bootstrapMethods == null) { 1258 bootstrapMethods = this.bootstrapMethods = new ByteVector(); 1259 } 1260 1261 int position = bootstrapMethods.length; // record current position 1262 1263 int hashCode = bsm.hashCode(); 1264 bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name, 1265 bsm.desc)); 1266 1267 int argsLength = bsmArgs.length; 1268 bootstrapMethods.putShort(argsLength); 1269 1270 for (int i = 0; i < argsLength; i++) { 1271 Object bsmArg = bsmArgs[i]; 1272 hashCode ^= bsmArg.hashCode(); 1273 bootstrapMethods.putShort(newConst(bsmArg)); 1274 } 1275 1276 byte[] data = bootstrapMethods.data; 1277 int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments) 1278 hashCode &= 0x7FFFFFFF; 1279 Item result = items[hashCode % items.length]; 1280 loop: while (result != null) { 1281 if (result.type != BSM || result.hashCode != hashCode) { 1282 result = result.next; 1283 continue; 1284 } 1306 put(result); 1307 } 1308 1309 // now, create the InvokeDynamic constant 1310 key3.set(name, desc, bootstrapMethodIndex); 1311 result = get(key3); 1312 if (result == null) { 1313 put122(INDY, bootstrapMethodIndex, newNameType(name, desc)); 1314 result = new Item(index++, key3); 1315 put(result); 1316 } 1317 return result; 1318 } 1319 1320 /** 1321 * Adds an invokedynamic reference to the constant pool of the class being 1322 * build. Does nothing if the constant pool already contains a similar item. 1323 * <i>This method is intended for {@link Attribute} sub classes, and is 1324 * normally not needed by class generators or adapters.</i> 1325 * 1326 * @param name 1327 * name of the invoked method. 1328 * @param desc 1329 * descriptor of the invoke method. 1330 * @param bsm 1331 * the bootstrap method. 1332 * @param bsmArgs 1333 * the bootstrap method constant arguments. 1334 * 1335 * @return the index of a new or already existing invokedynamic reference 1336 * item. 1337 */ 1338 public int newInvokeDynamic(final String name, final String desc, 1339 final Handle bsm, final Object... bsmArgs) { 1340 return newInvokeDynamicItem(name, desc, bsm, bsmArgs).index; 1341 } 1342 1343 /** 1344 * Adds a field reference to the constant pool of the class being build. 1345 * Does nothing if the constant pool already contains a similar item. 1346 * 1347 * @param owner 1348 * the internal name of the field's owner class. 1349 * @param name 1350 * the field's name. 1351 * @param desc 1352 * the field's descriptor. 1353 * @return a new or already existing field reference item. 1354 */ 1355 Item newFieldItem(final String owner, final String name, final String desc) { 1356 key3.set(FIELD, owner, name, desc); 1357 Item result = get(key3); 1358 if (result == null) { 1359 put122(FIELD, newClass(owner), newNameType(name, desc)); 1360 result = new Item(index++, key3); 1361 put(result); 1362 } 1363 return result; 1364 } 1365 1366 /** 1367 * Adds a field reference to the constant pool of the class being build. 1368 * Does nothing if the constant pool already contains a similar item. 1369 * <i>This method is intended for {@link Attribute} sub classes, and is 1370 * normally not needed by class generators or adapters.</i> 1371 * 1372 * @param owner 1373 * the internal name of the field's owner class. 1374 * @param name 1375 * the field's name. 1376 * @param desc 1377 * the field's descriptor. 1378 * @return the index of a new or already existing field reference item. 1379 */ 1380 public int newField(final String owner, final String name, final String desc) { 1381 return newFieldItem(owner, name, desc).index; 1382 } 1383 1384 /** 1385 * Adds a method reference to the constant pool of the class being build. 1386 * Does nothing if the constant pool already contains a similar item. 1387 * 1388 * @param owner 1389 * the internal name of the method's owner class. 1390 * @param name 1391 * the method's name. 1392 * @param desc 1393 * the method's descriptor. 1394 * @param itf 1395 * <tt>true</tt> if <tt>owner</tt> is an interface. 1396 * @return a new or already existing method reference item. 1397 */ 1398 Item newMethodItem(final String owner, final String name, 1399 final String desc, final boolean itf) { 1400 int type = itf ? IMETH : METH; 1401 key3.set(type, owner, name, desc); 1402 Item result = get(key3); 1403 if (result == null) { 1404 put122(type, newClass(owner), newNameType(name, desc)); 1405 result = new Item(index++, key3); 1406 put(result); 1407 } 1408 return result; 1409 } 1410 1411 /** 1412 * Adds a method reference to the constant pool of the class being build. 1413 * Does nothing if the constant pool already contains a similar item. 1414 * <i>This method is intended for {@link Attribute} sub classes, and is 1415 * normally not needed by class generators or adapters.</i> 1416 * 1417 * @param owner 1418 * the internal name of the method's owner class. 1419 * @param name 1420 * the method's name. 1421 * @param desc 1422 * the method's descriptor. 1423 * @param itf 1424 * <tt>true</tt> if <tt>owner</tt> is an interface. 1425 * @return the index of a new or already existing method reference item. 1426 */ 1427 public int newMethod(final String owner, final String name, 1428 final String desc, final boolean itf) { 1429 return newMethodItem(owner, name, desc, itf).index; 1430 } 1431 1432 /** 1433 * Adds an integer to the constant pool of the class being build. Does 1434 * nothing if the constant pool already contains a similar item. 1435 * 1436 * @param value 1437 * the int value. 1438 * @return a new or already existing int item. 1439 */ 1440 Item newInteger(final int value) { 1441 key.set(value); 1442 Item result = get(key); 1443 if (result == null) { 1444 pool.putByte(INT).putInt(value); 1445 result = new Item(index++, key); 1446 put(result); 1447 } 1448 return result; 1449 } 1450 1451 /** 1452 * Adds a float to the constant pool of the class being build. Does nothing 1453 * if the constant pool already contains a similar item. 1454 * 1455 * @param value 1456 * the float value. 1457 * @return a new or already existing float item. 1458 */ 1459 Item newFloat(final float value) { 1460 key.set(value); 1461 Item result = get(key); 1462 if (result == null) { 1463 pool.putByte(FLOAT).putInt(key.intVal); 1464 result = new Item(index++, key); 1465 put(result); 1466 } 1467 return result; 1468 } 1469 1470 /** 1471 * Adds a long to the constant pool of the class being build. Does nothing 1472 * if the constant pool already contains a similar item. 1473 * 1474 * @param value 1475 * the long value. 1476 * @return a new or already existing long item. 1477 */ 1478 Item newLong(final long value) { 1479 key.set(value); 1480 Item result = get(key); 1481 if (result == null) { 1482 pool.putByte(LONG).putLong(value); 1483 result = new Item(index, key); 1484 index += 2; 1485 put(result); 1486 } 1487 return result; 1488 } 1489 1490 /** 1491 * Adds a double to the constant pool of the class being build. Does nothing 1492 * if the constant pool already contains a similar item. 1493 * 1494 * @param value 1495 * the double value. 1496 * @return a new or already existing double item. 1497 */ 1498 Item newDouble(final double value) { 1499 key.set(value); 1500 Item result = get(key); 1501 if (result == null) { 1502 pool.putByte(DOUBLE).putLong(key.longVal); 1503 result = new Item(index, key); 1504 index += 2; 1505 put(result); 1506 } 1507 return result; 1508 } 1509 1510 /** 1511 * Adds a string to the constant pool of the class being build. Does nothing 1512 * if the constant pool already contains a similar item. 1513 * 1514 * @param value 1515 * the String value. 1516 * @return a new or already existing string item. 1517 */ 1518 private Item newString(final String value) { 1519 key2.set(STR, value, null, null); 1520 Item result = get(key2); 1521 if (result == null) { 1522 pool.put12(STR, newUTF8(value)); 1523 result = new Item(index++, key2); 1524 put(result); 1525 } 1526 return result; 1527 } 1528 1529 /** 1530 * Adds a name and type to the constant pool of the class being build. Does 1531 * nothing if the constant pool already contains a similar item. <i>This 1532 * method is intended for {@link Attribute} sub classes, and is normally not 1533 * needed by class generators or adapters.</i> 1534 * 1535 * @param name 1536 * a name. 1537 * @param desc 1538 * a type descriptor. 1539 * @return the index of a new or already existing name and type item. 1540 */ 1541 public int newNameType(final String name, final String desc) { 1542 return newNameTypeItem(name, desc).index; 1543 } 1544 1545 /** 1546 * Adds a name and type to the constant pool of the class being build. Does 1547 * nothing if the constant pool already contains a similar item. 1548 * 1549 * @param name 1550 * a name. 1551 * @param desc 1552 * a type descriptor. 1553 * @return a new or already existing name and type item. 1554 */ 1555 Item newNameTypeItem(final String name, final String desc) { 1556 key2.set(NAME_TYPE, name, desc, null); 1557 Item result = get(key2); 1558 if (result == null) { 1559 put122(NAME_TYPE, newUTF8(name), newUTF8(desc)); 1560 result = new Item(index++, key2); 1561 put(result); 1562 } 1563 return result; 1564 } 1565 1566 /** 1567 * Adds the given internal name to {@link #typeTable} and returns its index. 1568 * Does nothing if the type table already contains this internal name. 1569 * 1570 * @param type 1571 * the internal name to be added to the type table. 1572 * @return the index of this internal name in the type table. 1573 */ 1574 int addType(final String type) { 1575 key.set(TYPE_NORMAL, type, null, null); 1576 Item result = get(key); 1577 if (result == null) { 1578 result = addType(key); 1579 } 1580 return result.index; 1581 } 1582 1583 /** 1584 * Adds the given "uninitialized" type to {@link #typeTable} and returns its 1585 * index. This method is used for UNINITIALIZED types, made of an internal 1586 * name and a bytecode offset. 1587 * 1588 * @param type 1589 * the internal name to be added to the type table. 1590 * @param offset 1591 * the bytecode offset of the NEW instruction that created this 1592 * UNINITIALIZED type value. 1593 * @return the index of this internal name in the type table. 1594 */ 1595 int addUninitializedType(final String type, final int offset) { 1596 key.type = TYPE_UNINIT; 1597 key.intVal = offset; 1598 key.strVal1 = type; 1599 key.hashCode = 0x7FFFFFFF & (TYPE_UNINIT + type.hashCode() + offset); 1600 Item result = get(key); 1601 if (result == null) { 1602 result = addType(key); 1603 } 1604 return result.index; 1605 } 1606 1607 /** 1608 * Adds the given Item to {@link #typeTable}. 1609 * 1610 * @param item 1611 * the value to be added to the type table. 1612 * @return the added Item, which a new Item instance with the same value as 1613 * the given Item. 1614 */ 1615 private Item addType(final Item item) { 1616 ++typeCount; 1617 Item result = new Item(typeCount, key); 1618 put(result); 1619 if (typeTable == null) { 1620 typeTable = new Item[16]; 1621 } 1622 if (typeCount == typeTable.length) { 1623 Item[] newTable = new Item[2 * typeTable.length]; 1624 System.arraycopy(typeTable, 0, newTable, 0, typeTable.length); 1625 typeTable = newTable; 1626 } 1627 typeTable[typeCount] = result; 1628 return result; 1629 } 1630 1631 /** 1632 * Returns the index of the common super type of the two given types. This 1633 * method calls {@link #getCommonSuperClass} and caches the result in the 1634 * {@link #items} hash table to speedup future calls with the same 1635 * parameters. 1636 * 1637 * @param type1 1638 * index of an internal name in {@link #typeTable}. 1639 * @param type2 1640 * index of an internal name in {@link #typeTable}. 1641 * @return the index of the common super type of the two given types. 1642 */ 1643 int getMergedType(final int type1, final int type2) { 1644 key2.type = TYPE_MERGED; 1645 key2.longVal = type1 | (((long) type2) << 32); 1646 key2.hashCode = 0x7FFFFFFF & (TYPE_MERGED + type1 + type2); 1647 Item result = get(key2); 1648 if (result == null) { 1649 String t = typeTable[type1].strVal1; 1650 String u = typeTable[type2].strVal1; 1651 key2.intVal = addType(getCommonSuperClass(t, u)); 1652 result = new Item((short) 0, key2); 1653 put(result); 1654 } 1655 return result.intVal; 1656 } 1657 1658 /** 1659 * Returns the common super type of the two given types. The default 1660 * implementation of this method <i>loads</i> the two given classes and uses 1661 * the java.lang.Class methods to find the common super class. It can be 1662 * overridden to compute this common super type in other ways, in particular 1663 * without actually loading any class, or to take into account the class 1664 * that is currently being generated by this ClassWriter, which can of 1665 * course not be loaded since it is under construction. 1666 * 1667 * @param type1 1668 * the internal name of a class. 1669 * @param type2 1670 * the internal name of another class. 1671 * @return the internal name of the common super class of the two given 1672 * classes. 1673 */ 1674 protected String getCommonSuperClass(final String type1, final String type2) { 1675 Class<?> c, d; 1676 ClassLoader classLoader = getClass().getClassLoader(); 1677 try { 1678 c = Class.forName(type1.replace('/', '.'), false, classLoader); 1679 d = Class.forName(type2.replace('/', '.'), false, classLoader); 1680 } catch (Exception e) { 1681 throw new RuntimeException(e.toString()); 1682 } 1683 if (c.isAssignableFrom(d)) { 1684 return type1; 1685 } 1686 if (d.isAssignableFrom(c)) { 1687 return type2; 1688 } 1689 if (c.isInterface() || d.isInterface()) { 1690 return "java/lang/Object"; 1691 } else { 1692 do { 1693 c = c.getSuperclass(); 1694 } while (!c.isAssignableFrom(d)); 1695 return c.getName().replace('.', '/'); 1696 } 1697 } 1698 1699 /** 1700 * Returns the constant pool's hash table item which is equal to the given 1701 * item. 1702 * 1703 * @param key 1704 * a constant pool item. 1705 * @return the constant pool's hash table item which is equal to the given 1706 * item, or <tt>null</tt> if there is no such item. 1707 */ 1708 private Item get(final Item key) { 1709 Item i = items[key.hashCode % items.length]; 1710 while (i != null && (i.type != key.type || !key.isEqualTo(i))) { 1711 i = i.next; 1712 } 1713 return i; 1714 } 1715 1716 /** 1717 * Puts the given item in the constant pool's hash table. The hash table 1718 * <i>must</i> not already contains this item. 1719 * 1720 * @param i 1721 * the item to be added to the constant pool's hash table. 1722 */ 1723 private void put(final Item i) { 1724 if (index + typeCount > threshold) { 1725 int ll = items.length; 1726 int nl = ll * 2 + 1; 1727 Item[] newItems = new Item[nl]; 1728 for (int l = ll - 1; l >= 0; --l) { 1729 Item j = items[l]; 1730 while (j != null) { 1731 int index = j.hashCode % newItems.length; 1732 Item k = j.next; 1733 j.next = newItems[index]; 1734 newItems[index] = j; 1735 j = k; 1736 } 1737 } 1738 items = newItems; 1739 threshold = (int) (nl * 0.75); 1740 } 1741 int index = i.hashCode % items.length; 1742 i.next = items[index]; 1743 items[index] = i; 1744 } 1745 1746 /** 1747 * Puts one byte and two shorts into the constant pool. 1748 * 1749 * @param b 1750 * a byte. 1751 * @param s1 1752 * a short. 1753 * @param s2 1754 * another short. 1755 */ 1756 private void put122(final int b, final int s1, final int s2) { 1757 pool.put12(b, s1).putShort(s2); 1758 } 1759 1760 /** 1761 * Puts two bytes and one short into the constant pool. 1762 * 1763 * @param b1 1764 * a byte. 1765 * @param b2 1766 * another byte. 1767 * @param s 1768 * a short. 1769 */ 1770 private void put112(final int b1, final int b2, final int s) { 1771 pool.put11(b1, b2).putShort(s); 1772 } 1773 } |