70 public class ClassWriter extends ClassVisitor {
71
72 /**
73 * Flag to automatically compute the maximum stack size and the maximum
74 * number of local variables of methods. If this flag is set, then the
75 * arguments of the {@link MethodVisitor#visitMaxs visitMaxs} method of the
76 * {@link MethodVisitor} returned by the {@link #visitMethod visitMethod}
77 * method will be ignored, and computed automatically from the signature and
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 */
180 * The type of the TABLESWITCH instruction.
181 */
182 static final int TABL_INSN = 14;
183
184 /**
185 * The type of the LOOKUPSWITCH instruction.
186 */
187 static final int LOOK_INSN = 15;
188
189 /**
190 * The type of the MULTIANEWARRAY instruction.
191 */
192 static final int MANA_INSN = 16;
193
194 /**
195 * The type of the WIDE instruction.
196 */
197 static final int WIDE_INSN = 17;
198
199 /**
200 * The instruction types of all JVM opcodes.
201 */
202 static final byte[] TYPE;
203
204 /**
205 * The type of CONSTANT_Class constant pool items.
206 */
207 static final int CLASS = 7;
208
209 /**
210 * The type of CONSTANT_Fieldref constant pool items.
211 */
212 static final int FIELD = 9;
213
214 /**
215 * The type of CONSTANT_Methodref constant pool items.
216 */
217 static final int METH = 10;
218
219 /**
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 type of CONSTANT_Module constant pool items.
276 */
277 static final int MODULE = 19;
278
279 /**
280 * The type of CONSTANT_Package constant pool items.
281 */
282 static final int PACKAGE = 20;
283
284 /**
285 * The base value for all CONSTANT_MethodHandle constant pool items.
286 * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
287 * different items.
288 */
289 static final int HANDLE_BASE = 20;
290
291 /**
292 * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable},
293 * instead of the constant pool, in order to avoid clashes with normal
294 * constant pool items in the ClassWriter constant pool's hash table.
295 */
296 static final int TYPE_NORMAL = 30;
297
298 /**
299 * Uninitialized type Item stored in the ClassWriter
300 * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
301 * avoid clashes with normal constant pool items in the ClassWriter constant
302 * pool's hash table.
303 */
304 static final int TYPE_UNINIT = 31;
305
306 /**
307 * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable},
417
418 /**
419 * The interfaces implemented or extended by this class or interface. More
420 * precisely, this array contains the indexes of the constant pool items
421 * that contain the internal names of these interfaces.
422 */
423 private int[] interfaces;
424
425 /**
426 * The index of the constant pool item that contains the name of the source
427 * file from which this class was compiled.
428 */
429 private int sourceFile;
430
431 /**
432 * The SourceDebug attribute of this class.
433 */
434 private ByteVector sourceDebug;
435
436 /**
437 * The constant pool item that contains the name of the enclosing class of
438 * this class.
439 */
440 private int enclosingMethodOwner;
441
442 /**
443 * The constant pool item that contains the name and descriptor of the
444 * enclosing method of this class.
445 */
446 private int enclosingMethod;
447
448 /**
449 * The runtime visible annotations of this class.
450 */
451 private AnnotationWriter anns;
452
453 /**
454 * The runtime invisible annotations of this class.
455 */
456 private AnnotationWriter ianns;
506 */
507 FieldWriter lastField;
508
509 /**
510 * The methods of this class. These methods are stored in a linked list of
511 * {@link MethodWriter} objects, linked to each other by their
512 * {@link MethodWriter#mv} field. This field stores the first element of
513 * this list.
514 */
515 MethodWriter firstMethod;
516
517 /**
518 * The methods of this class. These methods are stored in a linked list of
519 * {@link MethodWriter} objects, linked to each other by their
520 * {@link MethodWriter#mv} field. This field stores the last element of this
521 * list.
522 */
523 MethodWriter lastMethod;
524
525 /**
526 * <tt>true</tt> if the maximum stack size and number of local variables
527 * must be automatically computed.
528 */
529 private boolean computeMaxs;
530
531 /**
532 * <tt>true</tt> if the stack map frames must be recomputed from scratch.
533 */
534 private boolean computeFrames;
535
536 /**
537 * <tt>true</tt> if the stack map tables of this class are invalid. The
538 * {@link MethodWriter#resizeInstructions} method cannot transform existing
539 * stack map tables, and so produces potentially invalid classes when it is
540 * executed. In this case the class is reread and rewritten with the
541 * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize
542 * stack map tables when this option is used).
543 */
544 boolean invalidFrames;
545
546 // ------------------------------------------------------------------------
547 // Static initializer
548 // ------------------------------------------------------------------------
549
550 /**
551 * Computes the instruction types of JVM opcodes.
552 */
553 static {
554 int i;
555 byte[] b = new byte[220];
556 String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
557 + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
558 + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
559 + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ";
560 for (i = 0; i < b.length; ++i) {
561 b[i] = (byte) (s.charAt(i) - 'A');
562 }
563 TYPE = b;
564
565 // code to generate the above string
566 //
567 // // SBYTE_INSN instructions
568 // b[Constants.NEWARRAY] = SBYTE_INSN;
569 // b[Constants.BIPUSH] = SBYTE_INSN;
570 //
571 // // SHORT_INSN instructions
572 // b[Constants.SIPUSH] = SHORT_INSN;
573 //
574 // // (IMPL)VAR_INSN instructions
575 // b[Constants.RET] = VAR_INSN;
576 // for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) {
577 // b[i] = VAR_INSN;
578 // }
579 // for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) {
593 // b[Constants.INSTANCEOF] = TYPE_INSN;
594 //
595 // // (Set)FIELDORMETH_INSN instructions
596 // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) {
597 // b[i] = FIELDORMETH_INSN;
598 // }
599 // b[Constants.INVOKEINTERFACE] = ITFMETH_INSN;
600 // b[Constants.INVOKEDYNAMIC] = INDYMETH_INSN;
601 //
602 // // LABEL(W)_INSN instructions
603 // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) {
604 // b[i] = LABEL_INSN;
605 // }
606 // b[Constants.IFNULL] = LABEL_INSN;
607 // b[Constants.IFNONNULL] = LABEL_INSN;
608 // b[200] = LABELW_INSN; // GOTO_W
609 // b[201] = LABELW_INSN; // JSR_W
610 // // temporary opcodes used internally by ASM - see Label and
611 // MethodWriter
612 // for (i = 202; i < 220; ++i) {
613 // b[i] = LABEL_INSN;
614 // }
615 //
616 // // LDC(_W) instructions
617 // b[Constants.LDC] = LDC_INSN;
618 // b[19] = LDCW_INSN; // LDC_W
619 // b[20] = LDCW_INSN; // LDC2_W
620 //
621 // // special instructions
622 // b[Constants.IINC] = IINC_INSN;
623 // b[Constants.TABLESWITCH] = TABL_INSN;
624 // b[Constants.LOOKUPSWITCH] = LOOK_INSN;
625 // b[Constants.MULTIANEWARRAY] = MANA_INSN;
626 // b[196] = WIDE_INSN; // WIDE
627 //
628 // for (i = 0; i < b.length; ++i) {
629 // System.err.print((char)('A' + b[i]));
630 // }
631 // System.err.println();
632 }
633
634 // ------------------------------------------------------------------------
635 // Constructor
636 // ------------------------------------------------------------------------
637
638 /**
639 * Constructs a new {@link ClassWriter} object.
640 *
641 * @param flags
642 * option flags that can be used to modify the default behavior
643 * of this class. See {@link #COMPUTE_MAXS},
644 * {@link #COMPUTE_FRAMES}.
645 */
646 public ClassWriter(final int flags) {
647 super(Opcodes.ASM5);
648 index = 1;
649 pool = new ByteVector();
650 items = new Item[256];
651 threshold = (int) (0.75d * items.length);
652 key = new Item();
653 key2 = new Item();
654 key3 = new Item();
655 key4 = new Item();
656 this.computeMaxs = (flags & COMPUTE_MAXS) != 0;
657 this.computeFrames = (flags & COMPUTE_FRAMES) != 0;
658 }
659
660 /**
661 * Constructs a new {@link ClassWriter} object and enables optimizations for
662 * "mostly add" bytecode transformations. These optimizations are the
663 * following:
664 *
665 * <ul>
666 * <li>The constant pool from the original class is copied as is in the new
667 * class, which saves time. New constant pool entries will be added at the
668 * end if necessary, but unused constant pool entries <i>won't be
669 * removed</i>.</li>
670 * <li>Methods that are not transformed are copied as is in the new class,
671 * directly from the original class bytecode (i.e. without emitting visit
672 * events for all the method instructions), which saves a <i>lot</i> of
673 * time. Untransformed methods are detected by the fact that the
674 * {@link ClassReader} receives {@link MethodVisitor} objects that come from
675 * a {@link ClassWriter} (and not from any other {@link ClassVisitor}
676 * instance).</li>
677 * </ul>
678 *
679 * @param classReader
680 * the {@link ClassReader} used to read the original class. It
681 * will be used to copy the entire constant pool from the
682 * original class and also to copy other fragments of original
683 * bytecode where applicable.
684 * @param flags
685 * option flags that can be used to modify the default behavior
686 * of this class. <i>These option flags do not affect methods
687 * that are copied as is in the new class. This means that the
688 * maximum stack size nor the stack frames will be computed for
689 * these methods</i>. See {@link #COMPUTE_MAXS},
690 * {@link #COMPUTE_FRAMES}.
691 */
692 public ClassWriter(final ClassReader classReader, final int flags) {
693 this(flags);
694 classReader.copyPool(this);
695 this.cr = classReader;
696 }
697
698 // ------------------------------------------------------------------------
699 // Implementation of the ClassVisitor abstract class
700 // ------------------------------------------------------------------------
701
702 @Override
703 public final void visit(final int version, final int access,
704 final String name, final String signature, final String superName,
705 final String[] interfaces) {
706 this.version = version;
707 this.access = access;
708 this.name = (name == null) ? 0 : newClass(name);
709 thisName = name;
710 if (ClassReader.SIGNATURES && signature != null) {
711 this.signature = newUTF8(signature);
712 }
713 this.superName = superName == null ? 0 : newClass(superName);
714 if (interfaces != null && interfaces.length > 0) {
715 interfaceCount = interfaces.length;
716 this.interfaces = new int[interfaceCount];
717 for (int i = 0; i < interfaceCount; ++i) {
718 this.interfaces[i] = newClass(interfaces[i]);
719 }
720 }
721 }
722
723 @Override
724 public final void visitSource(final String file, final String debug) {
725 if (file != null) {
726 sourceFile = newUTF8(file);
727 }
728 if (debug != null) {
729 sourceDebug = new ByteVector().encodeUTF8(debug, 0,
730 Integer.MAX_VALUE);
731 }
732 }
733
734 @Override
735 public final void visitOuterClass(final String owner, final String name,
736 final String desc) {
737 enclosingMethodOwner = newClass(owner);
738 if (name != null && desc != null) {
739 enclosingMethod = newNameType(name, desc);
740 }
741 }
742
743 @Override
744 public final AnnotationVisitor visitAnnotation(final String desc,
745 final boolean visible) {
746 if (!ClassReader.ANNOTATIONS) {
747 return null;
748 }
749 ByteVector bv = new ByteVector();
750 // write type, and reserve space for values count
751 bv.putShort(newUTF8(desc)).putShort(0);
752 AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2);
753 if (visible) {
754 aw.next = anns;
755 anns = aw;
756 } else {
757 aw.next = ianns;
758 ianns = aw;
759 }
760 return aw;
761 }
762
763 @Override
764 public final AnnotationVisitor visitTypeAnnotation(int typeRef,
765 TypePath typePath, final String desc, final boolean visible) {
766 if (!ClassReader.ANNOTATIONS) {
767 return null;
768 }
769 ByteVector bv = new ByteVector();
770 // write target_type and target_info
771 AnnotationWriter.putTarget(typeRef, typePath, bv);
772 // write type, and reserve space for values count
773 bv.putShort(newUTF8(desc)).putShort(0);
774 AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv,
775 bv.length - 2);
776 if (visible) {
777 aw.next = tanns;
778 tanns = aw;
779 } else {
780 aw.next = itanns;
781 itanns = aw;
782 }
783 return aw;
784 }
785
786 @Override
787 public final void visitAttribute(final Attribute attr) {
788 attr.next = attrs;
789 attrs = attr;
790 }
791
792 @Override
793 public final void visitInnerClass(final String name,
794 final String outerName, final String innerName, final int access) {
795 if (innerClasses == null) {
796 innerClasses = new ByteVector();
797 }
798 // Sec. 4.7.6 of the JVMS states "Every CONSTANT_Class_info entry in the
799 // constant_pool table which represents a class or interface C that is
800 // not a package member must have exactly one corresponding entry in the
801 // classes array". To avoid duplicates we keep track in the intVal field
802 // of the Item of each CONSTANT_Class_info entry C whether an inner
803 // class entry has already been added for C (this field is unused for
804 // class entries, and changing its value does not change the hashcode
805 // and equality tests). If so we store the index of this inner class
806 // entry (plus one) in intVal. This hack allows duplicate detection in
807 // O(1) time.
808 Item nameItem = newClassItem(name);
809 if (nameItem.intVal == 0) {
810 ++innerClassesCount;
811 innerClasses.putShort(nameItem.index);
812 innerClasses.putShort(outerName == null ? 0 : newClass(outerName));
813 innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName));
814 innerClasses.putShort(access);
815 nameItem.intVal = innerClassesCount;
816 } else {
817 // Compare the inner classes entry nameItem.intVal - 1 with the
818 // arguments of this method and throw an exception if there is a
819 // difference?
820 }
821 }
822
823 @Override
824 public final FieldVisitor visitField(final int access, final String name,
825 final String desc, final String signature, final Object value) {
826 return new FieldWriter(this, access, name, desc, signature, value);
827 }
828
829 @Override
830 public final MethodVisitor visitMethod(final int access, final String name,
831 final String desc, final String signature, final String[] exceptions) {
832 return new MethodWriter(this, access, name, desc, signature,
833 exceptions, computeMaxs, computeFrames);
834 }
835
836 @Override
837 public final void visitEnd() {
838 }
839
840 // ------------------------------------------------------------------------
841 // Other public methods
842 // ------------------------------------------------------------------------
843
844 /**
845 * Returns the bytecode of the class that was build with this class writer.
846 *
847 * @return the bytecode of the class that was build with this class writer.
848 */
849 public byte[] toByteArray() {
850 if (index > 0xFFFF) {
851 throw new RuntimeException("Class file too large!");
852 }
853 // computes the real size of the bytecode of this class
857 while (fb != null) {
858 ++nbFields;
859 size += fb.getSize();
860 fb = (FieldWriter) fb.fv;
861 }
862 int nbMethods = 0;
863 MethodWriter mb = firstMethod;
864 while (mb != null) {
865 ++nbMethods;
866 size += mb.getSize();
867 mb = (MethodWriter) mb.mv;
868 }
869 int attributeCount = 0;
870 if (bootstrapMethods != null) {
871 // we put it as first attribute in order to improve a bit
872 // ClassReader.copyBootstrapMethods
873 ++attributeCount;
874 size += 8 + bootstrapMethods.length;
875 newUTF8("BootstrapMethods");
876 }
877 if (ClassReader.SIGNATURES && signature != 0) {
878 ++attributeCount;
879 size += 8;
880 newUTF8("Signature");
881 }
882 if (sourceFile != 0) {
883 ++attributeCount;
884 size += 8;
885 newUTF8("SourceFile");
886 }
887 if (sourceDebug != null) {
888 ++attributeCount;
889 size += sourceDebug.length + 6;
890 newUTF8("SourceDebugExtension");
891 }
892 if (enclosingMethodOwner != 0) {
893 ++attributeCount;
894 size += 10;
895 newUTF8("EnclosingMethod");
896 }
897 if ((access & Opcodes.ACC_DEPRECATED) != 0) {
898 ++attributeCount;
899 size += 6;
900 newUTF8("Deprecated");
901 }
902 if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
903 if ((version & 0xFFFF) < Opcodes.V1_5
904 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
905 ++attributeCount;
906 size += 6;
907 newUTF8("Synthetic");
908 }
909 }
910 if (innerClasses != null) {
911 ++attributeCount;
912 size += 8 + innerClasses.length;
913 newUTF8("InnerClasses");
914 }
915 if (ClassReader.ANNOTATIONS && anns != null) {
916 ++attributeCount;
917 size += 8 + anns.getSize();
918 newUTF8("RuntimeVisibleAnnotations");
919 }
920 if (ClassReader.ANNOTATIONS && ianns != null) {
921 ++attributeCount;
922 size += 8 + ianns.getSize();
923 newUTF8("RuntimeInvisibleAnnotations");
924 }
925 if (ClassReader.ANNOTATIONS && tanns != null) {
926 ++attributeCount;
927 size += 8 + tanns.getSize();
928 newUTF8("RuntimeVisibleTypeAnnotations");
929 }
930 if (ClassReader.ANNOTATIONS && itanns != null) {
931 ++attributeCount;
932 size += 8 + itanns.getSize();
933 newUTF8("RuntimeInvisibleTypeAnnotations");
934 }
935 if (attrs != null) {
936 attributeCount += attrs.getCount();
937 size += attrs.getSize(this, null, 0, -1, -1);
938 }
939 size += pool.length;
940 // allocates a byte vector of this size, in order to avoid unnecessary
941 // arraycopy operations in the ByteVector.enlarge() method
942 ByteVector out = new ByteVector(size);
943 out.putInt(0xCAFEBABE).putInt(version);
944 out.putShort(index).putByteArray(pool.data, 0, pool.length);
945 int mask = Opcodes.ACC_DEPRECATED | ACC_SYNTHETIC_ATTRIBUTE
946 | ((access & ACC_SYNTHETIC_ATTRIBUTE) / TO_ACC_SYNTHETIC);
947 out.putShort(access & ~mask).putShort(name).putShort(superName);
948 out.putShort(interfaceCount);
949 for (int i = 0; i < interfaceCount; ++i) {
950 out.putShort(interfaces[i]);
951 }
952 out.putShort(nbFields);
953 fb = firstField;
954 while (fb != null) {
955 fb.put(out);
956 fb = (FieldWriter) fb.fv;
957 }
958 out.putShort(nbMethods);
959 mb = firstMethod;
960 while (mb != null) {
961 mb.put(out);
962 mb = (MethodWriter) mb.mv;
963 }
964 out.putShort(attributeCount);
965 if (bootstrapMethods != null) {
966 out.putShort(newUTF8("BootstrapMethods"));
967 out.putInt(bootstrapMethods.length + 2).putShort(
968 bootstrapMethodsCount);
969 out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
970 }
971 if (ClassReader.SIGNATURES && signature != 0) {
972 out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
973 }
974 if (sourceFile != 0) {
975 out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile);
976 }
977 if (sourceDebug != null) {
978 int len = sourceDebug.length;
979 out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
980 out.putByteArray(sourceDebug.data, 0, len);
981 }
982 if (enclosingMethodOwner != 0) {
983 out.putShort(newUTF8("EnclosingMethod")).putInt(4);
984 out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
985 }
986 if ((access & Opcodes.ACC_DEPRECATED) != 0) {
987 out.putShort(newUTF8("Deprecated")).putInt(0);
988 }
989 if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
990 if ((version & 0xFFFF) < Opcodes.V1_5
991 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
992 out.putShort(newUTF8("Synthetic")).putInt(0);
993 }
994 }
995 if (innerClasses != null) {
996 out.putShort(newUTF8("InnerClasses"));
997 out.putInt(innerClasses.length + 2).putShort(innerClassesCount);
998 out.putByteArray(innerClasses.data, 0, innerClasses.length);
999 }
1000 if (ClassReader.ANNOTATIONS && anns != null) {
1001 out.putShort(newUTF8("RuntimeVisibleAnnotations"));
1002 anns.put(out);
1003 }
1004 if (ClassReader.ANNOTATIONS && ianns != null) {
1005 out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
1006 ianns.put(out);
1007 }
1008 if (ClassReader.ANNOTATIONS && tanns != null) {
1009 out.putShort(newUTF8("RuntimeVisibleTypeAnnotations"));
1010 tanns.put(out);
1011 }
1012 if (ClassReader.ANNOTATIONS && itanns != null) {
1013 out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations"));
1014 itanns.put(out);
1015 }
1016 if (attrs != null) {
1017 attrs.put(this, null, 0, -1, -1, out);
1018 }
1019 if (invalidFrames) {
1020 anns = null;
1021 ianns = null;
1022 attrs = null;
1023 innerClassesCount = 0;
1024 innerClasses = null;
1025 bootstrapMethodsCount = 0;
1026 bootstrapMethods = null;
1027 firstField = null;
1028 lastField = null;
1029 firstMethod = null;
1030 lastMethod = null;
1031 computeMaxs = false;
1032 computeFrames = true;
1033 invalidFrames = false;
1034 new ClassReader(out.data).accept(this, ClassReader.SKIP_FRAMES);
1035 return toByteArray();
1036 }
1037 return out.data;
1038 }
1039
1040 // ------------------------------------------------------------------------
1041 // Utility methods: constant pool management
1042 // ------------------------------------------------------------------------
1043
1044 /**
1045 * Adds a number or string constant to the constant pool of the class being
1046 * build. Does nothing if the constant pool already contains a similar item.
1047 *
1048 * @param cst
1049 * the value of the constant to be added to the constant pool.
1050 * This parameter must be an {@link Integer}, a {@link Float}, a
1051 * {@link Long}, a {@link Double}, a {@link String} or a
1052 * {@link Type}.
1053 * @return a new or already existing constant item with the given value.
1054 */
1061 return newInteger(val);
1062 } else if (cst instanceof Character) {
1063 int val = ((Character) cst).charValue();
1064 return newInteger(val);
1065 } else if (cst instanceof Short) {
1066 int val = ((Short) cst).intValue();
1067 return newInteger(val);
1068 } else if (cst instanceof Boolean) {
1069 int val = ((Boolean) cst).booleanValue() ? 1 : 0;
1070 return newInteger(val);
1071 } else if (cst instanceof Float) {
1072 float val = ((Float) cst).floatValue();
1073 return newFloat(val);
1074 } else if (cst instanceof Long) {
1075 long val = ((Long) cst).longValue();
1076 return newLong(val);
1077 } else if (cst instanceof Double) {
1078 double val = ((Double) cst).doubleValue();
1079 return newDouble(val);
1080 } else if (cst instanceof String) {
1081 return newString((String) cst);
1082 } else if (cst instanceof Type) {
1083 Type t = (Type) cst;
1084 int s = t.getSort();
1085 if (s == Type.OBJECT) {
1086 return newClassItem(t.getInternalName());
1087 } else if (s == Type.METHOD) {
1088 return newMethodTypeItem(t.getDescriptor());
1089 } else { // s == primitive type or array
1090 return newClassItem(t.getDescriptor());
1091 }
1092 } else if (cst instanceof Handle) {
1093 Handle h = (Handle) cst;
1094 return newHandleItem(h.tag, h.owner, h.name, h.desc, h.itf);
1095 } else {
1096 throw new IllegalArgumentException("value " + cst);
1097 }
1098 }
1099
1100 /**
1101 * Adds a number or string constant to the constant pool of the class being
1102 * build. Does nothing if the constant pool already contains a similar item.
1103 * <i>This method is intended for {@link Attribute} sub classes, and is
1104 * normally not needed by class generators or adapters.</i>
1105 *
1106 * @param cst
1107 * the value of the constant to be added to the constant pool.
1108 * This parameter must be an {@link Integer}, a {@link Float}, a
1109 * {@link Long}, a {@link Double} or a {@link String}.
1110 * @return the index of a new or already existing constant item with the
1119 * nothing if the constant pool already contains a similar item. <i>This
1120 * method is intended for {@link Attribute} sub classes, and is normally not
1121 * needed by class generators or adapters.</i>
1122 *
1123 * @param value
1124 * the String value.
1125 * @return the index of a new or already existing UTF8 item.
1126 */
1127 public int newUTF8(final String value) {
1128 key.set(UTF8, value, null, null);
1129 Item result = get(key);
1130 if (result == null) {
1131 pool.putByte(UTF8).putUTF8(value);
1132 result = new Item(index++, key);
1133 put(result);
1134 }
1135 return result.index;
1136 }
1137
1138 /**
1139 * Adds a class reference to the constant pool of the class being build.
1140 * Does nothing if the constant pool already contains a similar item.
1141 * <i>This method is intended for {@link Attribute} sub classes, and is
1142 * normally not needed by class generators or adapters.</i>
1143 *
1144 * @param value
1145 * the internal name of the class.
1146 * @return a new or already existing class reference item.
1147 */
1148 Item newClassItem(final String value) {
1149 key2.set(CLASS, value, null, null);
1150 Item result = get(key2);
1151 if (result == null) {
1152 pool.put12(CLASS, newUTF8(value));
1153 result = new Item(index++, key2);
1154 put(result);
1155 }
1156 return result;
1157 }
1158
1159 /**
1160 * Adds a class reference to the constant pool of the class being build.
1161 * Does nothing if the constant pool already contains a similar item.
1162 * <i>This method is intended for {@link Attribute} sub classes, and is
1163 * normally not needed by class generators or adapters.</i>
1164 *
1165 * @param value
1166 * the internal name of the class.
1167 * @return the index of a new or already existing class reference item.
1168 */
1169 public int newClass(final String value) {
1170 return newClassItem(value).index;
1171 }
1172
1173 /**
1174 * Adds a module name to the constant pool.
1175 *
1176 * Does nothing if the constant pool already contains a similar item.
1177 * <i>This method is intended for {@link Attribute} sub classes, and is
1178 * normally not needed by class generators or adapters.</i>
1179 *
1180 * @param value
1181 * the module name
1182 * @return the index of a new or already existing module reference item.
1183 */
1184 public int newModule(String value) {
1185 key2.set(MODULE, value, null, null);
1186 Item result = get(key2);
1187 if (result == null) {
1188 pool.put12(MODULE, newUTF8(value));
1189 result = new Item(index++, key2);
1190 put(result);
1191 }
1192 return result.index;
1193 }
1194
1195 /**
1196 * Adds a package name to the constant pool.
1197 *
1198 * Does nothing if the constant pool already contains a similar item.
1199 * <i>This method is intended for {@link Attribute} sub classes, and is
1200 * normally not needed by class generators or adapters.</i>
1201 *
1202 * @param value
1203 * the internal name of the package.
1204 * @return the index of a new or already existing package reference item.
1205 */
1206 public int newPackage(String value) {
1207 key2.set(PACKAGE, value, null, null);
1208 Item result = get(key2);
1209 if (result == null) {
1210 pool.put12(PACKAGE, newUTF8(value));
1211 result = new Item(index++, key2);
1212 put(result);
1213 }
1214 return result.index;
1215 }
1216
1217 /**
1218 * Adds a method type reference to the constant pool of the class being
1219 * build. Does nothing if the constant pool already contains a similar item.
1220 * <i>This method is intended for {@link Attribute} sub classes, and is
1221 * normally not needed by class generators or adapters.</i>
1222 *
1223 * @param methodDesc
1224 * method descriptor of the method type.
1225 * @return a new or already existing method type reference item.
1226 */
1227 Item newMethodTypeItem(final String methodDesc) {
1228 key2.set(MTYPE, methodDesc, null, null);
1229 Item result = get(key2);
1230 if (result == null) {
1231 pool.put12(MTYPE, newUTF8(methodDesc));
1232 result = new Item(index++, key2);
1233 put(result);
1234 }
1235 return result;
1236 }
1237
1238 /**
1239 * Adds a method type reference to the constant pool of the class being
1240 * build. Does nothing if the constant pool already contains a similar item.
1241 * <i>This method is intended for {@link Attribute} sub classes, and is
1242 * normally not needed by class generators or adapters.</i>
1243 *
1244 * @param methodDesc
1245 * method descriptor of the method type.
1246 * @return the index of a new or already existing method type reference
1247 * item.
1248 */
1249 public int newMethodType(final String methodDesc) {
1250 return newMethodTypeItem(methodDesc).index;
1251 }
1252
1253 /**
1254 * Adds a handle to the constant pool of the class being build. Does nothing
1255 * if the constant pool already contains a similar item. <i>This method is
1256 * intended for {@link Attribute} sub classes, and is normally not needed by
1257 * class generators or adapters.</i>
1258 *
1259 * @param tag
1260 * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
1261 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
1262 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
1263 * {@link Opcodes#H_INVOKESTATIC},
1264 * {@link Opcodes#H_INVOKESPECIAL},
1265 * {@link Opcodes#H_NEWINVOKESPECIAL} or
1266 * {@link Opcodes#H_INVOKEINTERFACE}.
1267 * @param owner
1268 * the internal name of the field or method owner class.
1269 * @param name
1270 * the name of the field or method.
1608 return result;
1609 }
1610
1611 /**
1612 * Adds a double to the constant pool of the class being build. Does nothing
1613 * if the constant pool already contains a similar item.
1614 *
1615 * @param value
1616 * the double value.
1617 * @return a new or already existing double item.
1618 */
1619 Item newDouble(final double value) {
1620 key.set(value);
1621 Item result = get(key);
1622 if (result == null) {
1623 pool.putByte(DOUBLE).putLong(key.longVal);
1624 result = new Item(index, key);
1625 index += 2;
1626 put(result);
1627 }
1628 return result;
1629 }
1630
1631 /**
1632 * Adds a string to the constant pool of the class being build. Does nothing
1633 * if the constant pool already contains a similar item.
1634 *
1635 * @param value
1636 * the String value.
1637 * @return a new or already existing string item.
1638 */
1639 private Item newString(final String value) {
1640 key2.set(STR, value, null, null);
1641 Item result = get(key2);
1642 if (result == null) {
1643 pool.put12(STR, newUTF8(value));
1644 result = new Item(index++, key2);
1645 put(result);
1646 }
1647 return result;
1648 }
1649
1650 /**
1651 * Adds a name and type to the constant pool of the class being build. Does
1652 * nothing if the constant pool already contains a similar item. <i>This
1653 * method is intended for {@link Attribute} sub classes, and is normally not
1654 * needed by class generators or adapters.</i>
1655 *
1656 * @param name
1657 * a name.
1658 * @param desc
1659 * a type descriptor.
1660 * @return the index of a new or already existing name and type item.
1661 */
1662 public int newNameType(final String name, final String desc) {
1663 return newNameTypeItem(name, desc).index;
1664 }
1665
1666 /**
|
70 public class ClassWriter extends ClassVisitor {
71
72 /**
73 * Flag to automatically compute the maximum stack size and the maximum
74 * number of local variables of methods. If this flag is set, then the
75 * arguments of the {@link MethodVisitor#visitMaxs visitMaxs} method of the
76 * {@link MethodVisitor} returned by the {@link #visitMethod visitMethod}
77 * method will be ignored, and computed automatically from the signature and
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, COMPUTE_FRAMES implies
91 * COMPUTE_MAXS.
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 */
180 * The type of the TABLESWITCH instruction.
181 */
182 static final int TABL_INSN = 14;
183
184 /**
185 * The type of the LOOKUPSWITCH instruction.
186 */
187 static final int LOOK_INSN = 15;
188
189 /**
190 * The type of the MULTIANEWARRAY instruction.
191 */
192 static final int MANA_INSN = 16;
193
194 /**
195 * The type of the WIDE instruction.
196 */
197 static final int WIDE_INSN = 17;
198
199 /**
200 * The type of the ASM pseudo instructions with an unsigned 2 bytes offset
201 * label (see Label#resolve).
202 */
203 static final int ASM_LABEL_INSN = 18;
204
205 /**
206 * The type of the ASM pseudo instructions with a 4 bytes offset label.
207 */
208 static final int ASM_LABELW_INSN = 19;
209
210 /**
211 * Represents a frame inserted between already existing frames. This kind of
212 * frame can only be used if the frame content can be computed from the
213 * previous existing frame and from the instructions between this existing
214 * frame and the inserted one, without any knowledge of the type hierarchy.
215 * This kind of frame is only used when an unconditional jump is inserted in
216 * a method while expanding an ASM pseudo instruction (see ClassReader).
217 */
218 static final int F_INSERT = 256;
219
220 /**
221 * The instruction types of all JVM opcodes.
222 */
223 static final byte[] TYPE;
224
225 /**
226 * The type of CONSTANT_Class constant pool items.
227 */
228 static final int CLASS = 7;
229
230 /**
231 * The type of CONSTANT_Fieldref constant pool items.
232 */
233 static final int FIELD = 9;
234
235 /**
236 * The type of CONSTANT_Methodref constant pool items.
237 */
238 static final int METH = 10;
239
240 /**
288 static final int HANDLE = 15;
289
290 /**
291 * The type of CONSTANT_InvokeDynamic constant pool items.
292 */
293 static final int INDY = 18;
294
295 /**
296 * The type of CONSTANT_Module constant pool items.
297 */
298 static final int MODULE = 19;
299
300 /**
301 * The type of CONSTANT_Package constant pool items.
302 */
303 static final int PACKAGE = 20;
304
305 /**
306 * The base value for all CONSTANT_MethodHandle constant pool items.
307 * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
308 * different items (from 21 to 29).
309 */
310 static final int HANDLE_BASE = 20;
311
312 /**
313 * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable},
314 * instead of the constant pool, in order to avoid clashes with normal
315 * constant pool items in the ClassWriter constant pool's hash table.
316 */
317 static final int TYPE_NORMAL = 30;
318
319 /**
320 * Uninitialized type Item stored in the ClassWriter
321 * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
322 * avoid clashes with normal constant pool items in the ClassWriter constant
323 * pool's hash table.
324 */
325 static final int TYPE_UNINIT = 31;
326
327 /**
328 * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable},
438
439 /**
440 * The interfaces implemented or extended by this class or interface. More
441 * precisely, this array contains the indexes of the constant pool items
442 * that contain the internal names of these interfaces.
443 */
444 private int[] interfaces;
445
446 /**
447 * The index of the constant pool item that contains the name of the source
448 * file from which this class was compiled.
449 */
450 private int sourceFile;
451
452 /**
453 * The SourceDebug attribute of this class.
454 */
455 private ByteVector sourceDebug;
456
457 /**
458 * The module attribute of this class.
459 */
460 private ModuleWriter moduleWriter;
461
462 /**
463 * The constant pool item that contains the name of the enclosing class of
464 * this class.
465 */
466 private int enclosingMethodOwner;
467
468 /**
469 * The constant pool item that contains the name and descriptor of the
470 * enclosing method of this class.
471 */
472 private int enclosingMethod;
473
474 /**
475 * The runtime visible annotations of this class.
476 */
477 private AnnotationWriter anns;
478
479 /**
480 * The runtime invisible annotations of this class.
481 */
482 private AnnotationWriter ianns;
532 */
533 FieldWriter lastField;
534
535 /**
536 * The methods of this class. These methods are stored in a linked list of
537 * {@link MethodWriter} objects, linked to each other by their
538 * {@link MethodWriter#mv} field. This field stores the first element of
539 * this list.
540 */
541 MethodWriter firstMethod;
542
543 /**
544 * The methods of this class. These methods are stored in a linked list of
545 * {@link MethodWriter} objects, linked to each other by their
546 * {@link MethodWriter#mv} field. This field stores the last element of this
547 * list.
548 */
549 MethodWriter lastMethod;
550
551 /**
552 * Indicates what must be automatically computed.
553 *
554 * @see MethodWriter#compute
555 */
556 private int compute;
557
558 /**
559 * <tt>true</tt> if some methods have wide forward jumps using ASM pseudo
560 * instructions, which need to be expanded into sequences of standard
561 * bytecode instructions. In this case the class is re-read and re-written
562 * with a ClassReader -> ClassWriter chain to perform this transformation.
563 */
564 boolean hasAsmInsns;
565
566 // ------------------------------------------------------------------------
567 // Static initializer
568 // ------------------------------------------------------------------------
569
570 /**
571 * Computes the instruction types of JVM opcodes.
572 */
573 static {
574 int i;
575 byte[] b = new byte[221];
576 String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
577 + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
578 + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
579 + "AAAAGGGGGGGHIFBFAAFFAARQJJKKSSSSSSSSSSSSSSSSSST";
580 for (i = 0; i < b.length; ++i) {
581 b[i] = (byte) (s.charAt(i) - 'A');
582 }
583 TYPE = b;
584
585 // code to generate the above string
586 //
587 // // SBYTE_INSN instructions
588 // b[Constants.NEWARRAY] = SBYTE_INSN;
589 // b[Constants.BIPUSH] = SBYTE_INSN;
590 //
591 // // SHORT_INSN instructions
592 // b[Constants.SIPUSH] = SHORT_INSN;
593 //
594 // // (IMPL)VAR_INSN instructions
595 // b[Constants.RET] = VAR_INSN;
596 // for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) {
597 // b[i] = VAR_INSN;
598 // }
599 // for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) {
613 // b[Constants.INSTANCEOF] = TYPE_INSN;
614 //
615 // // (Set)FIELDORMETH_INSN instructions
616 // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) {
617 // b[i] = FIELDORMETH_INSN;
618 // }
619 // b[Constants.INVOKEINTERFACE] = ITFMETH_INSN;
620 // b[Constants.INVOKEDYNAMIC] = INDYMETH_INSN;
621 //
622 // // LABEL(W)_INSN instructions
623 // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) {
624 // b[i] = LABEL_INSN;
625 // }
626 // b[Constants.IFNULL] = LABEL_INSN;
627 // b[Constants.IFNONNULL] = LABEL_INSN;
628 // b[200] = LABELW_INSN; // GOTO_W
629 // b[201] = LABELW_INSN; // JSR_W
630 // // temporary opcodes used internally by ASM - see Label and
631 // MethodWriter
632 // for (i = 202; i < 220; ++i) {
633 // b[i] = ASM_LABEL_INSN;
634 // }
635 // b[220] = ASM_LABELW_INSN;
636 //
637 // // LDC(_W) instructions
638 // b[Constants.LDC] = LDC_INSN;
639 // b[19] = LDCW_INSN; // LDC_W
640 // b[20] = LDCW_INSN; // LDC2_W
641 //
642 // // special instructions
643 // b[Constants.IINC] = IINC_INSN;
644 // b[Constants.TABLESWITCH] = TABL_INSN;
645 // b[Constants.LOOKUPSWITCH] = LOOK_INSN;
646 // b[Constants.MULTIANEWARRAY] = MANA_INSN;
647 // b[196] = WIDE_INSN; // WIDE
648 //
649 // for (i = 0; i < b.length; ++i) {
650 // System.err.print((char)('A' + b[i]));
651 // }
652 // System.err.println();
653 }
654
655 // ------------------------------------------------------------------------
656 // Constructor
657 // ------------------------------------------------------------------------
658
659 /**
660 * Constructs a new {@link ClassWriter} object.
661 *
662 * @param flags
663 * option flags that can be used to modify the default behavior
664 * of this class. See {@link #COMPUTE_MAXS},
665 * {@link #COMPUTE_FRAMES}.
666 */
667 public ClassWriter(final int flags) {
668 super(Opcodes.ASM6);
669 index = 1;
670 pool = new ByteVector();
671 items = new Item[256];
672 threshold = (int) (0.75d * items.length);
673 key = new Item();
674 key2 = new Item();
675 key3 = new Item();
676 key4 = new Item();
677 this.compute = (flags & COMPUTE_FRAMES) != 0 ? MethodWriter.FRAMES
678 : ((flags & COMPUTE_MAXS) != 0 ? MethodWriter.MAXS
679 : MethodWriter.NOTHING);
680 }
681
682 /**
683 * Constructs a new {@link ClassWriter} object and enables optimizations for
684 * "mostly add" bytecode transformations. These optimizations are the
685 * following:
686 *
687 * <ul>
688 * <li>The constant pool from the original class is copied as is in the new
689 * class, which saves time. New constant pool entries will be added at the
690 * end if necessary, but unused constant pool entries <i>won't be
691 * removed</i>.</li>
692 * <li>Methods that are not transformed are copied as is in the new class,
693 * directly from the original class bytecode (i.e. without emitting visit
694 * events for all the method instructions), which saves a <i>lot</i> of
695 * time. Untransformed methods are detected by the fact that the
696 * {@link ClassReader} receives {@link MethodVisitor} objects that come from
697 * a {@link ClassWriter} (and not from any other {@link ClassVisitor}
698 * instance).</li>
699 * </ul>
700 *
701 * @param classReader
702 * the {@link ClassReader} used to read the original class. It
703 * will be used to copy the entire constant pool from the
704 * original class and also to copy other fragments of original
705 * bytecode where applicable.
706 * @param flags
707 * option flags that can be used to modify the default behavior
708 * of this class. <i>These option flags do not affect methods
709 * that are copied as is in the new class. This means that
710 * neither the maximum stack size nor the stack frames will be
711 * computed for these methods</i>. See {@link #COMPUTE_MAXS},
712 * {@link #COMPUTE_FRAMES}.
713 */
714 public ClassWriter(final ClassReader classReader, final int flags) {
715 this(flags);
716 classReader.copyPool(this);
717 this.cr = classReader;
718 }
719
720 // ------------------------------------------------------------------------
721 // Implementation of the ClassVisitor abstract class
722 // ------------------------------------------------------------------------
723
724 @Override
725 public final void visit(final int version, final int access,
726 final String name, final String signature, final String superName,
727 final String[] interfaces) {
728 this.version = version;
729 this.access = access;
730 this.name = newClass(name);
731 thisName = name;
732 if (signature != null) {
733 this.signature = newUTF8(signature);
734 }
735 this.superName = superName == null ? 0 : newClass(superName);
736 if (interfaces != null && interfaces.length > 0) {
737 interfaceCount = interfaces.length;
738 this.interfaces = new int[interfaceCount];
739 for (int i = 0; i < interfaceCount; ++i) {
740 this.interfaces[i] = newClass(interfaces[i]);
741 }
742 }
743 }
744
745 @Override
746 public final void visitSource(final String file, final String debug) {
747 if (file != null) {
748 sourceFile = newUTF8(file);
749 }
750 if (debug != null) {
751 sourceDebug = new ByteVector().encodeUTF8(debug, 0,
752 Integer.MAX_VALUE);
753 }
754 }
755
756 @Override
757 public final ModuleVisitor visitModule(final String name,
758 final int access, final String version) {
759 return moduleWriter = new ModuleWriter(this,
760 newModule(name), access,
761 version == null ? 0 : newUTF8(version));
762 }
763
764 @Override
765 public final void visitOuterClass(final String owner, final String name,
766 final String desc) {
767 enclosingMethodOwner = newClass(owner);
768 if (name != null && desc != null) {
769 enclosingMethod = newNameType(name, desc);
770 }
771 }
772
773 @Override
774 public final AnnotationVisitor visitAnnotation(final String desc,
775 final boolean visible) {
776 ByteVector bv = new ByteVector();
777 // write type, and reserve space for values count
778 bv.putShort(newUTF8(desc)).putShort(0);
779 AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2);
780 if (visible) {
781 aw.next = anns;
782 anns = aw;
783 } else {
784 aw.next = ianns;
785 ianns = aw;
786 }
787 return aw;
788 }
789
790 @Override
791 public final AnnotationVisitor visitTypeAnnotation(int typeRef,
792 TypePath typePath, final String desc, final boolean visible) {
793 ByteVector bv = new ByteVector();
794 // write target_type and target_info
795 AnnotationWriter.putTarget(typeRef, typePath, bv);
796 // write type, and reserve space for values count
797 bv.putShort(newUTF8(desc)).putShort(0);
798 AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv,
799 bv.length - 2);
800 if (visible) {
801 aw.next = tanns;
802 tanns = aw;
803 } else {
804 aw.next = itanns;
805 itanns = aw;
806 }
807 return aw;
808 }
809
810 @Override
811 public final void visitAttribute(final Attribute attr) {
812 attr.next = attrs;
813 attrs = attr;
814 }
815
816 @Override
817 public final void visitInnerClass(final String name,
818 final String outerName, final String innerName, final int access) {
819 if (innerClasses == null) {
820 innerClasses = new ByteVector();
821 }
822 // Sec. 4.7.6 of the JVMS states "Every CONSTANT_Class_info entry in the
823 // constant_pool table which represents a class or interface C that is
824 // not a package member must have exactly one corresponding entry in the
825 // classes array". To avoid duplicates we keep track in the intVal field
826 // of the Item of each CONSTANT_Class_info entry C whether an inner
827 // class entry has already been added for C (this field is unused for
828 // class entries, and changing its value does not change the hashcode
829 // and equality tests). If so we store the index of this inner class
830 // entry (plus one) in intVal. This hack allows duplicate detection in
831 // O(1) time.
832 Item nameItem = newStringishItem(CLASS, name);
833 if (nameItem.intVal == 0) {
834 ++innerClassesCount;
835 innerClasses.putShort(nameItem.index);
836 innerClasses.putShort(outerName == null ? 0 : newClass(outerName));
837 innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName));
838 innerClasses.putShort(access);
839 nameItem.intVal = innerClassesCount;
840 } else {
841 // Compare the inner classes entry nameItem.intVal - 1 with the
842 // arguments of this method and throw an exception if there is a
843 // difference?
844 }
845 }
846
847 @Override
848 public final FieldVisitor visitField(final int access, final String name,
849 final String desc, final String signature, final Object value) {
850 return new FieldWriter(this, access, name, desc, signature, value);
851 }
852
853 @Override
854 public final MethodVisitor visitMethod(final int access, final String name,
855 final String desc, final String signature, final String[] exceptions) {
856 return new MethodWriter(this, access, name, desc, signature,
857 exceptions, compute);
858 }
859
860 @Override
861 public final void visitEnd() {
862 }
863
864 // ------------------------------------------------------------------------
865 // Other public methods
866 // ------------------------------------------------------------------------
867
868 /**
869 * Returns the bytecode of the class that was build with this class writer.
870 *
871 * @return the bytecode of the class that was build with this class writer.
872 */
873 public byte[] toByteArray() {
874 if (index > 0xFFFF) {
875 throw new RuntimeException("Class file too large!");
876 }
877 // computes the real size of the bytecode of this class
881 while (fb != null) {
882 ++nbFields;
883 size += fb.getSize();
884 fb = (FieldWriter) fb.fv;
885 }
886 int nbMethods = 0;
887 MethodWriter mb = firstMethod;
888 while (mb != null) {
889 ++nbMethods;
890 size += mb.getSize();
891 mb = (MethodWriter) mb.mv;
892 }
893 int attributeCount = 0;
894 if (bootstrapMethods != null) {
895 // we put it as first attribute in order to improve a bit
896 // ClassReader.copyBootstrapMethods
897 ++attributeCount;
898 size += 8 + bootstrapMethods.length;
899 newUTF8("BootstrapMethods");
900 }
901 if (signature != 0) {
902 ++attributeCount;
903 size += 8;
904 newUTF8("Signature");
905 }
906 if (sourceFile != 0) {
907 ++attributeCount;
908 size += 8;
909 newUTF8("SourceFile");
910 }
911 if (sourceDebug != null) {
912 ++attributeCount;
913 size += sourceDebug.length + 6;
914 newUTF8("SourceDebugExtension");
915 }
916 if (enclosingMethodOwner != 0) {
917 ++attributeCount;
918 size += 10;
919 newUTF8("EnclosingMethod");
920 }
921 if ((access & Opcodes.ACC_DEPRECATED) != 0) {
922 ++attributeCount;
923 size += 6;
924 newUTF8("Deprecated");
925 }
926 if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
927 if ((version & 0xFFFF) < Opcodes.V1_5
928 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
929 ++attributeCount;
930 size += 6;
931 newUTF8("Synthetic");
932 }
933 }
934 if (innerClasses != null) {
935 ++attributeCount;
936 size += 8 + innerClasses.length;
937 newUTF8("InnerClasses");
938 }
939 if (anns != null) {
940 ++attributeCount;
941 size += 8 + anns.getSize();
942 newUTF8("RuntimeVisibleAnnotations");
943 }
944 if (ianns != null) {
945 ++attributeCount;
946 size += 8 + ianns.getSize();
947 newUTF8("RuntimeInvisibleAnnotations");
948 }
949 if (tanns != null) {
950 ++attributeCount;
951 size += 8 + tanns.getSize();
952 newUTF8("RuntimeVisibleTypeAnnotations");
953 }
954 if (itanns != null) {
955 ++attributeCount;
956 size += 8 + itanns.getSize();
957 newUTF8("RuntimeInvisibleTypeAnnotations");
958 }
959 if (moduleWriter != null) {
960 attributeCount += 1 + moduleWriter.attributeCount;
961 size += 6 + moduleWriter.size + moduleWriter.attributesSize;
962 newUTF8("Module");
963 }
964 if (attrs != null) {
965 attributeCount += attrs.getCount();
966 size += attrs.getSize(this, null, 0, -1, -1);
967 }
968 size += pool.length;
969 // allocates a byte vector of this size, in order to avoid unnecessary
970 // arraycopy operations in the ByteVector.enlarge() method
971 ByteVector out = new ByteVector(size);
972 out.putInt(0xCAFEBABE).putInt(version);
973 out.putShort(index).putByteArray(pool.data, 0, pool.length);
974 int mask = Opcodes.ACC_DEPRECATED | ACC_SYNTHETIC_ATTRIBUTE
975 | ((access & ACC_SYNTHETIC_ATTRIBUTE) / TO_ACC_SYNTHETIC);
976 out.putShort(access & ~mask).putShort(name).putShort(superName);
977 out.putShort(interfaceCount);
978 for (int i = 0; i < interfaceCount; ++i) {
979 out.putShort(interfaces[i]);
980 }
981 out.putShort(nbFields);
982 fb = firstField;
983 while (fb != null) {
984 fb.put(out);
985 fb = (FieldWriter) fb.fv;
986 }
987 out.putShort(nbMethods);
988 mb = firstMethod;
989 while (mb != null) {
990 mb.put(out);
991 mb = (MethodWriter) mb.mv;
992 }
993 out.putShort(attributeCount);
994 if (bootstrapMethods != null) {
995 out.putShort(newUTF8("BootstrapMethods"));
996 out.putInt(bootstrapMethods.length + 2).putShort(
997 bootstrapMethodsCount);
998 out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
999 }
1000 if (signature != 0) {
1001 out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
1002 }
1003 if (sourceFile != 0) {
1004 out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile);
1005 }
1006 if (sourceDebug != null) {
1007 int len = sourceDebug.length;
1008 out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
1009 out.putByteArray(sourceDebug.data, 0, len);
1010 }
1011 if (moduleWriter != null) {
1012 out.putShort(newUTF8("Module"));
1013 moduleWriter.put(out);
1014 moduleWriter.putAttributes(out);
1015 }
1016 if (enclosingMethodOwner != 0) {
1017 out.putShort(newUTF8("EnclosingMethod")).putInt(4);
1018 out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
1019 }
1020 if ((access & Opcodes.ACC_DEPRECATED) != 0) {
1021 out.putShort(newUTF8("Deprecated")).putInt(0);
1022 }
1023 if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
1024 if ((version & 0xFFFF) < Opcodes.V1_5
1025 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
1026 out.putShort(newUTF8("Synthetic")).putInt(0);
1027 }
1028 }
1029 if (innerClasses != null) {
1030 out.putShort(newUTF8("InnerClasses"));
1031 out.putInt(innerClasses.length + 2).putShort(innerClassesCount);
1032 out.putByteArray(innerClasses.data, 0, innerClasses.length);
1033 }
1034 if (anns != null) {
1035 out.putShort(newUTF8("RuntimeVisibleAnnotations"));
1036 anns.put(out);
1037 }
1038 if (ianns != null) {
1039 out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
1040 ianns.put(out);
1041 }
1042 if (tanns != null) {
1043 out.putShort(newUTF8("RuntimeVisibleTypeAnnotations"));
1044 tanns.put(out);
1045 }
1046 if (itanns != null) {
1047 out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations"));
1048 itanns.put(out);
1049 }
1050 if (attrs != null) {
1051 attrs.put(this, null, 0, -1, -1, out);
1052 }
1053 if (hasAsmInsns) {
1054 boolean hasFrames = false;
1055 mb = firstMethod;
1056 while (mb != null) {
1057 hasFrames |= mb.frameCount > 0;
1058 mb = (MethodWriter) mb.mv;
1059 }
1060 anns = null;
1061 ianns = null;
1062 attrs = null;
1063 moduleWriter = null;
1064 firstField = null;
1065 lastField = null;
1066 firstMethod = null;
1067 lastMethod = null;
1068 compute =
1069 hasFrames ? MethodWriter.INSERTED_FRAMES : MethodWriter.NOTHING;
1070 hasAsmInsns = false;
1071 new ClassReader(out.data).accept(this,
1072 (hasFrames ? ClassReader.EXPAND_FRAMES : 0)
1073 | ClassReader.EXPAND_ASM_INSNS);
1074 return toByteArray();
1075 }
1076 return out.data;
1077 }
1078
1079 // ------------------------------------------------------------------------
1080 // Utility methods: constant pool management
1081 // ------------------------------------------------------------------------
1082
1083 /**
1084 * Adds a number or string constant to the constant pool of the class being
1085 * build. Does nothing if the constant pool already contains a similar item.
1086 *
1087 * @param cst
1088 * the value of the constant to be added to the constant pool.
1089 * This parameter must be an {@link Integer}, a {@link Float}, a
1090 * {@link Long}, a {@link Double}, a {@link String} or a
1091 * {@link Type}.
1092 * @return a new or already existing constant item with the given value.
1093 */
1100 return newInteger(val);
1101 } else if (cst instanceof Character) {
1102 int val = ((Character) cst).charValue();
1103 return newInteger(val);
1104 } else if (cst instanceof Short) {
1105 int val = ((Short) cst).intValue();
1106 return newInteger(val);
1107 } else if (cst instanceof Boolean) {
1108 int val = ((Boolean) cst).booleanValue() ? 1 : 0;
1109 return newInteger(val);
1110 } else if (cst instanceof Float) {
1111 float val = ((Float) cst).floatValue();
1112 return newFloat(val);
1113 } else if (cst instanceof Long) {
1114 long val = ((Long) cst).longValue();
1115 return newLong(val);
1116 } else if (cst instanceof Double) {
1117 double val = ((Double) cst).doubleValue();
1118 return newDouble(val);
1119 } else if (cst instanceof String) {
1120 return newStringishItem(STR, (String) cst);
1121 } else if (cst instanceof Type) {
1122 Type t = (Type) cst;
1123 int s = t.getSort();
1124 if (s == Type.OBJECT) {
1125 return newStringishItem(CLASS, t.getInternalName());
1126 } else if (s == Type.METHOD) {
1127 return newStringishItem(MTYPE, t.getDescriptor());
1128 } else { // s == primitive type or array
1129 return newStringishItem(CLASS, t.getDescriptor());
1130 }
1131 } else if (cst instanceof Handle) {
1132 Handle h = (Handle) cst;
1133 return newHandleItem(h.tag, h.owner, h.name, h.desc, h.itf);
1134 } else {
1135 throw new IllegalArgumentException("value " + cst);
1136 }
1137 }
1138
1139 /**
1140 * Adds a number or string constant to the constant pool of the class being
1141 * build. Does nothing if the constant pool already contains a similar item.
1142 * <i>This method is intended for {@link Attribute} sub classes, and is
1143 * normally not needed by class generators or adapters.</i>
1144 *
1145 * @param cst
1146 * the value of the constant to be added to the constant pool.
1147 * This parameter must be an {@link Integer}, a {@link Float}, a
1148 * {@link Long}, a {@link Double} or a {@link String}.
1149 * @return the index of a new or already existing constant item with the
1158 * nothing if the constant pool already contains a similar item. <i>This
1159 * method is intended for {@link Attribute} sub classes, and is normally not
1160 * needed by class generators or adapters.</i>
1161 *
1162 * @param value
1163 * the String value.
1164 * @return the index of a new or already existing UTF8 item.
1165 */
1166 public int newUTF8(final String value) {
1167 key.set(UTF8, value, null, null);
1168 Item result = get(key);
1169 if (result == null) {
1170 pool.putByte(UTF8).putUTF8(value);
1171 result = new Item(index++, key);
1172 put(result);
1173 }
1174 return result.index;
1175 }
1176
1177 /**
1178 * Adds a string reference, a class reference, a method type, a module
1179 * or a package to the constant pool of the class being build.
1180 * Does nothing if the constant pool already contains a similar item.
1181 *
1182 * @param type
1183 * a type among STR, CLASS, MTYPE, MODULE or PACKAGE
1184 * @param value
1185 * string value of the reference.
1186 * @return a new or already existing reference item.
1187 */
1188 Item newStringishItem(final int type, final String value) {
1189 key2.set(type, value, null, null);
1190 Item result = get(key2);
1191 if (result == null) {
1192 pool.put12(type, newUTF8(value));
1193 result = new Item(index++, key2);
1194 put(result);
1195 }
1196 return result;
1197 }
1198
1199 /**
1200 * Adds a class reference to the constant pool of the class being build.
1201 * Does nothing if the constant pool already contains a similar item.
1202 * <i>This method is intended for {@link Attribute} sub classes, and is
1203 * normally not needed by class generators or adapters.</i>
1204 *
1205 * @param value
1206 * the internal name of the class.
1207 * @return the index of a new or already existing class reference item.
1208 */
1209 public int newClass(final String value) {
1210 return newStringishItem(CLASS, value).index;
1211 }
1212
1213 /**
1214 * Adds a method type reference to the constant pool of the class being
1215 * build. Does nothing if the constant pool already contains a similar item.
1216 * <i>This method is intended for {@link Attribute} sub classes, and is
1217 * normally not needed by class generators or adapters.</i>
1218 *
1219 * @param methodDesc
1220 * method descriptor of the method type.
1221 * @return the index of a new or already existing method type reference
1222 * item.
1223 */
1224 public int newMethodType(final String methodDesc) {
1225 return newStringishItem(MTYPE, methodDesc).index;
1226 }
1227
1228 /**
1229 * Adds a module reference to the constant pool of the class being
1230 * build. Does nothing if the constant pool already contains a similar item.
1231 * <i>This method is intended for {@link Attribute} sub classes, and is
1232 * normally not needed by class generators or adapters.</i>
1233 *
1234 * @param moduleName
1235 * name of the module.
1236 * @return the index of a new or already existing module reference
1237 * item.
1238 */
1239 public int newModule(final String moduleName) {
1240 return newStringishItem(MODULE, moduleName).index;
1241 }
1242
1243 /**
1244 * Adds a package reference to the constant pool of the class being
1245 * build. Does nothing if the constant pool already contains a similar item.
1246 * <i>This method is intended for {@link Attribute} sub classes, and is
1247 * normally not needed by class generators or adapters.</i>
1248 *
1249 * @param packageName
1250 * name of the package in its internal form.
1251 * @return the index of a new or already existing module reference
1252 * item.
1253 */
1254 public int newPackage(final String packageName) {
1255 return newStringishItem(PACKAGE, packageName).index;
1256 }
1257
1258 /**
1259 * Adds a handle to the constant pool of the class being build. Does nothing
1260 * if the constant pool already contains a similar item. <i>This method is
1261 * intended for {@link Attribute} sub classes, and is normally not needed by
1262 * class generators or adapters.</i>
1263 *
1264 * @param tag
1265 * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
1266 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
1267 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
1268 * {@link Opcodes#H_INVOKESTATIC},
1269 * {@link Opcodes#H_INVOKESPECIAL},
1270 * {@link Opcodes#H_NEWINVOKESPECIAL} or
1271 * {@link Opcodes#H_INVOKEINTERFACE}.
1272 * @param owner
1273 * the internal name of the field or method owner class.
1274 * @param name
1275 * the name of the field or method.
1613 return result;
1614 }
1615
1616 /**
1617 * Adds a double to the constant pool of the class being build. Does nothing
1618 * if the constant pool already contains a similar item.
1619 *
1620 * @param value
1621 * the double value.
1622 * @return a new or already existing double item.
1623 */
1624 Item newDouble(final double value) {
1625 key.set(value);
1626 Item result = get(key);
1627 if (result == null) {
1628 pool.putByte(DOUBLE).putLong(key.longVal);
1629 result = new Item(index, key);
1630 index += 2;
1631 put(result);
1632 }
1633 return result;
1634 }
1635
1636 /**
1637 * Adds a name and type to the constant pool of the class being build. Does
1638 * nothing if the constant pool already contains a similar item. <i>This
1639 * method is intended for {@link Attribute} sub classes, and is normally not
1640 * needed by class generators or adapters.</i>
1641 *
1642 * @param name
1643 * a name.
1644 * @param desc
1645 * a type descriptor.
1646 * @return the index of a new or already existing name and type item.
1647 */
1648 public int newNameType(final String name, final String desc) {
1649 return newNameTypeItem(name, desc).index;
1650 }
1651
1652 /**
|