• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000-2005 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  *    contributors may be used to endorse or promote products derived from
16  *    this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 package org.objectweb.asm;
31 
32 /**
33  * A {@link ClassVisitor} that generates classes in bytecode form. More
34  * precisely this visitor generates a byte array conforming to the Java class
35  * file format. It can be used alone, to generate a Java class "from scratch",
36  * or with one or more {@link ClassReader ClassReader} and adapter class visitor
37  * to generate a modified class from one or more existing Java classes.
38  *
39  * @author Eric Bruneton
40  */
41 public class ClassWriter implements ClassVisitor {
42 
43     /**
44      * The type of instructions without any argument.
45      */
46     final static int NOARG_INSN = 0;
47 
48     /**
49      * The type of instructions with an signed byte argument.
50      */
51     final static int SBYTE_INSN = 1;
52 
53     /**
54      * The type of instructions with an signed short argument.
55      */
56     final static int SHORT_INSN = 2;
57 
58     /**
59      * The type of instructions with a local variable index argument.
60      */
61     final static int VAR_INSN = 3;
62 
63     /**
64      * The type of instructions with an implicit local variable index argument.
65      */
66     final static int IMPLVAR_INSN = 4;
67 
68     /**
69      * The type of instructions with a type descriptor argument.
70      */
71     final static int TYPE_INSN = 5;
72 
73     /**
74      * The type of field and method invocations instructions.
75      */
76     final static int FIELDORMETH_INSN = 6;
77 
78     /**
79      * The type of the INVOKEINTERFACE instruction.
80      */
81     final static int ITFMETH_INSN = 7;
82 
83     /**
84      * The type of instructions with a 2 bytes bytecode offset label.
85      */
86     final static int LABEL_INSN = 8;
87 
88     /**
89      * The type of instructions with a 4 bytes bytecode offset label.
90      */
91     final static int LABELW_INSN = 9;
92 
93     /**
94      * The type of the LDC instruction.
95      */
96     final static int LDC_INSN = 10;
97 
98     /**
99      * The type of the LDC_W and LDC2_W instructions.
100      */
101     final static int LDCW_INSN = 11;
102 
103     /**
104      * The type of the IINC instruction.
105      */
106     final static int IINC_INSN = 12;
107 
108     /**
109      * The type of the TABLESWITCH instruction.
110      */
111     final static int TABL_INSN = 13;
112 
113     /**
114      * The type of the LOOKUPSWITCH instruction.
115      */
116     final static int LOOK_INSN = 14;
117 
118     /**
119      * The type of the MULTIANEWARRAY instruction.
120      */
121     final static int MANA_INSN = 15;
122 
123     /**
124      * The type of the WIDE instruction.
125      */
126     final static int WIDE_INSN = 16;
127 
128     /**
129      * The instruction types of all JVM opcodes.
130      */
131     static final byte[] TYPE;
132 
133     /**
134      * The type of CONSTANT_Class constant pool items.
135      */
136     static final int CLASS = 7;
137 
138     /**
139      * The type of CONSTANT_Fieldref constant pool items.
140      */
141     static final int FIELD = 9;
142 
143     /**
144      * The type of CONSTANT_Methodref constant pool items.
145      */
146     static final int METH = 10;
147 
148     /**
149      * The type of CONSTANT_InterfaceMethodref constant pool items.
150      */
151     static final int IMETH = 11;
152 
153     /**
154      * The type of CONSTANT_String constant pool items.
155      */
156     static final int STR = 8;
157 
158     /**
159      * The type of CONSTANT_Integer constant pool items.
160      */
161     static final int INT = 3;
162 
163     /**
164      * The type of CONSTANT_Float constant pool items.
165      */
166     static final int FLOAT = 4;
167 
168     /**
169      * The type of CONSTANT_Long constant pool items.
170      */
171     static final int LONG = 5;
172 
173     /**
174      * The type of CONSTANT_Double constant pool items.
175      */
176     static final int DOUBLE = 6;
177 
178     /**
179      * The type of CONSTANT_NameAndType constant pool items.
180      */
181     static final int NAME_TYPE = 12;
182 
183     /**
184      * The type of CONSTANT_Utf8 constant pool items.
185      */
186     static final int UTF8 = 1;
187 
188     /**
189      * The type of CONSTANT_MethodType constant pool items.
190      */
191     static final int MTYPE = 16;
192 
193     /**
194      * The type of CONSTANT_MethodHandle constant pool items.
195      */
196     static final int HANDLE = 15;
197 
198     /**
199      * The type of CONSTANT_InvokeDynamic constant pool items.
200      */
201     static final int INDY = 18;
202 
203     /**
204      * The base value for all CONSTANT_MethodHandle constant pool items.
205      * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
206      * different items.
207      */
208     static final int HANDLE_BASE = 20;
209 
210     /**
211      * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable},
212      * instead of the constant pool, in order to avoid clashes with normal
213      * constant pool items in the ClassWriter constant pool's hash table.
214      */
215     static final int TYPE_NORMAL = 30;
216 
217     /**
218      * Uninitialized type Item stored in the ClassWriter
219      * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
220      * avoid clashes with normal constant pool items in the ClassWriter constant
221      * pool's hash table.
222      */
223     static final int TYPE_UNINIT = 31;
224 
225     /**
226      * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable},
227      * instead of the constant pool, in order to avoid clashes with normal
228      * constant pool items in the ClassWriter constant pool's hash table.
229      */
230     static final int TYPE_MERGED = 32;
231 
232     /**
233      * The type of BootstrapMethods items. These items are stored in a special
234      * class attribute named BootstrapMethods and not in the constant pool.
235      */
236     static final int BSM = 33;
237 
238     /**
239      * The class reader from which this class writer was constructed, if any.
240      */
241     ClassReader cr;
242 
243     /**
244      * Minor and major version numbers of the class to be generated.
245      */
246     int version;
247 
248     /**
249      * Index of the next item to be added in the constant pool.
250      */
251     int index;
252 
253     /**
254      * The constant pool of this class.
255      */
256     ByteVector pool;
257 
258     /**
259      * The constant pool's hash table data.
260      */
261     Item[] items;
262 
263     /**
264      * The threshold of the constant pool's hash table.
265      */
266     int threshold;
267 
268     /**
269      * A reusable key used to look for items in the hash {@link #items items}.
270      */
271     Item key;
272 
273     /**
274      * A reusable key used to look for items in the hash {@link #items items}.
275      */
276     Item key2;
277 
278     /**
279      * A reusable key used to look for items in the hash {@link #items items}.
280      */
281     Item key3;
282 
283     /**
284      * A reusable key used to look for items in the hash {@link #items items}.
285      */
286     Item key4;
287 
288     /**
289      * The access flags of this class.
290      */
291     private int access;
292 
293     /**
294      * The constant pool item that contains the internal name of this class.
295      */
296     private int name;
297 
298     /**
299      * The constant pool item that contains the signature of this class.
300      */
301     private int signature;
302 
303     /**
304      * The constant pool item that contains the internal name of the super class
305      * of this class.
306      */
307     private int superName;
308 
309     /**
310      * Number of interfaces implemented or extended by this class or interface.
311      */
312     private int interfaceCount;
313 
314     /**
315      * The interfaces implemented or extended by this class or interface. More
316      * precisely, this array contains the indexes of the constant pool items
317      * that contain the internal names of these interfaces.
318      */
319     private int[] interfaces;
320 
321     /**
322      * The index of the constant pool item that contains the name of the source
323      * file from which this class was compiled.
324      */
325     private int sourceFile;
326 
327     /**
328      * The SourceDebug attribute of this class.
329      */
330     private ByteVector sourceDebug;
331 
332     /**
333      * The constant pool item that contains the name of the enclosing class of
334      * this class.
335      */
336     private int enclosingMethodOwner;
337 
338     /**
339      * The constant pool item that contains the name and descriptor of the
340      * enclosing method of this class.
341      */
342     private int enclosingMethod;
343 
344     /**
345      * The runtime visible annotations of this class.
346      */
347     private AnnotationWriter anns;
348 
349     /**
350      * The runtime invisible annotations of this class.
351      */
352     private AnnotationWriter ianns;
353 
354     //jaime
355     private TypeAnnotationWriter xanns;
356     private TypeAnnotationWriter ixanns;
357     //end jaime
358 
359     /**
360      * The non standard attributes of this class.
361      */
362     private Attribute attrs;
363 
364     /**
365      * The number of entries in the InnerClasses attribute.
366      */
367     private int innerClassesCount;
368 
369     /**
370      * The InnerClasses attribute.
371      */
372     private ByteVector innerClasses;
373 
374     /**
375      * The number of entries in the BootstrapMethods attribute.
376      */
377     int bootstrapMethodsCount;
378 
379     /**
380      * The BootstrapMethods attribute.
381      */
382     ByteVector bootstrapMethods;
383 
384     /**
385      * The fields of this class. These fields are stored in a linked list of
386      * {@link FieldWriter} objects, linked to each other by their
387      * {@link FieldWriter#next} field. This field stores the first element of
388      * this list.
389      */
390     FieldWriter firstField;
391 
392     /**
393      * The fields of this class. These fields are stored in a linked list of
394      * {@link FieldWriter} objects, linked to each other by their
395      * {@link FieldWriter#next} field. This field stores the last element of
396      * this list.
397      */
398     FieldWriter lastField;
399 
400     /**
401      * The methods of this class. These methods are stored in a linked list of
402      * {@link MethodWriter} objects, linked to each other by their
403      * {@link MethodWriter#next} field. This field stores the first element of
404      * this list.
405      */
406     MethodWriter firstMethod;
407 
408     /**
409      * The methods of this class. These methods are stored in a linked list of
410      * {@link MethodWriter} objects, linked to each other by their
411      * {@link MethodWriter#next} field. This field stores the last element of
412      * this list.
413      */
414     MethodWriter lastMethod;
415 
416     /**
417      * <tt>true</tt> if the maximum stack size and number of local variables
418      * must be automatically computed.
419      */
420     private final boolean computeMaxs;
421 
422     // ------------------------------------------------------------------------
423     // Static initializer
424     // ------------------------------------------------------------------------
425 
426     /**
427      * Computes the instruction types of JVM opcodes.
428      */
429     static {
430         int i;
431         byte[] b = new byte[220];
432         String s = "AAAAAAAAAAAAAAAABCKLLDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
433                 + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
434                 + "AAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAIIIIIIIIIIIIIIIIDNOAA"
435                 + "AAAAGGGGGGGHSFBFAAFFAAQPIIJJIIIIIIIIIIIIIIIIII";
436         for (i = 0; i < b.length; ++i) {
437             b[i] = (byte) (s.charAt(i) - 'A');
438         }
439         TYPE = b;
440 
441         // code to generate the above string
442         //
443         // // SBYTE_INSN instructions
444         // b[Constants.NEWARRAY] = SBYTE_INSN;
445         // b[Constants.BIPUSH] = SBYTE_INSN;
446         //
447         // // SHORT_INSN instructions
448         // b[Constants.SIPUSH] = SHORT_INSN;
449         //
450         // // (IMPL)VAR_INSN instructions
451         // b[Constants.RET] = VAR_INSN;
452         // for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) {
453         // b[i] = VAR_INSN;
454         // }
455         // for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) {
456         // b[i] = VAR_INSN;
457         // }
458         // for (i = 26; i <= 45; ++i) { // ILOAD_0 to ALOAD_3
459         // b[i] = IMPLVAR_INSN;
460         // }
461         // for (i = 59; i <= 78; ++i) { // ISTORE_0 to ASTORE_3
462         // b[i] = IMPLVAR_INSN;
463         // }
464         //
465         // // TYPE_INSN instructions
466         // b[Constants.NEW] = TYPE_INSN;
467         // b[Constants.ANEWARRAY] = TYPE_INSN;
468         // b[Constants.CHECKCAST] = TYPE_INSN;
469         // b[Constants.INSTANCEOF] = TYPE_INSN;
470         //
471         // // (Set)FIELDORMETH_INSN instructions
472         // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) {
473         // b[i] = FIELDORMETH_INSN;
474         // }
475         // b[Constants.INVOKEINTERFACE] = ITFMETH_INSN;
476         //
477         // b[Constants.INVOKEDYNAMIC] = INDY;
478         //
479         // // LABEL(W)_INSN instructions
480         // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) {
481         // b[i] = LABEL_INSN;
482         // }
483         // b[Constants.IFNULL] = LABEL_INSN;
484         // b[Constants.IFNONNULL] = LABEL_INSN;
485         // b[200] = LABELW_INSN; // GOTO_W
486         // b[201] = LABELW_INSN; // JSR_W
487         // // temporary opcodes used internally by ASM - see Label and
488         // MethodWriter
489         // for (i = 202; i < 220; ++i) {
490         // b[i] = LABEL_INSN;
491         // }
492         //
493         // // LDC(_W) instructions
494         // b[Constants.LDC] = LDC_INSN;
495         // b[19] = LDCW_INSN; // LDC_W
496         // b[20] = LDCW_INSN; // LDC2_W
497         //
498         // // special instructions
499         // b[Constants.IINC] = IINC_INSN;
500         // b[Constants.TABLESWITCH] = TABL_INSN;
501         // b[Constants.LOOKUPSWITCH] = LOOK_INSN;
502         // b[Constants.MULTIANEWARRAY] = MANA_INSN;
503         // b[196] = WIDE_INSN; // WIDE
504         //
505         // for (i = 0; i < b.length; ++i) {
506         // System.err.print((char)('A' + b[i]));
507         // }
508         // System.err.println();
509     }
510 
511     // ------------------------------------------------------------------------
512     // Constructor
513     // ------------------------------------------------------------------------
514 
515     /**
516      * Constructs a new {@link ClassWriter ClassWriter} object.
517      *
518      * @param computeMaxs <tt>true</tt> if the maximum stack size and the
519      *        maximum number of local variables must be automatically computed.
520      *        If this flag is <tt>true</tt>, then the arguments of the
521      *        {@link MethodVisitor#visitMaxs visitMaxs} method of the
522      *        {@link MethodVisitor} returned by the
523      *        {@link #visitMethod visitMethod} method will be ignored, and
524      *        computed automatically from the signature and the bytecode of each
525      *        method.
526      */
ClassWriter(final boolean computeMaxs)527     public ClassWriter(final boolean computeMaxs) {
528         this(computeMaxs, false);
529     }
530 
531     /**
532      * Constructs a new {@link ClassWriter} object.
533      *
534      * @param computeMaxs <tt>true</tt> if the maximum stack size and the
535      *        maximum number of local variables must be automatically computed.
536      *        If this flag is <tt>true</tt>, then the arguments of the
537      *        {@link MethodVisitor#visitMaxs visitMaxs} method of the
538      *        {@link MethodVisitor} returned by the
539      *        {@link #visitMethod visitMethod} method will be ignored, and
540      *        computed automatically from the signature and the bytecode of each
541      *        method.
542      * @param skipUnknownAttributes <b>Deprecated</b>. The value of this
543      *        parameter is ignored.
544      */
ClassWriter( final boolean computeMaxs, final boolean skipUnknownAttributes)545     public ClassWriter(
546         final boolean computeMaxs,
547         final boolean skipUnknownAttributes)
548     {
549         index = 1;
550         pool = new ByteVector();
551         items = new Item[256];
552         threshold = (int) (0.75d * items.length);
553         key = new Item();
554         key2 = new Item();
555         key3 = new Item();
556         key4 = new Item();
557         this.computeMaxs = computeMaxs;
558     }
559 
560     /**
561      * Constructs a new {@link ClassWriter} object and enables optimizations for
562      * "mostly add" bytecode transformations. These optimizations are the
563      * following:
564      *
565      * <ul> <li>The constant pool from the original class is copied as is in
566      * the new class, which saves time. New constant pool entries will be added
567      * at the end if necessary, but unused constant pool entries <i>won't be
568      * removed</i>.</li> <li>Methods that are not transformed are copied as
569      * is in the new class, directly from the original class bytecode (i.e.
570      * without emitting visit events for all the method instructions), which
571      * saves a <i>lot</i> of time. Untransformed methods are detected by the
572      * fact that the {@link ClassReader} receives {@link MethodVisitor} objects
573      * that come from a {@link ClassWriter} (and not from a custom
574      * {@link ClassAdapter} or any other {@link ClassVisitor} instance).</li>
575      * </ul>
576      *
577      * @param classReader the {@link ClassReader} used to read the original
578      *        class. It will be used to copy the entire constant pool from the
579      *        original class and also to copy other fragments of original
580      *        bytecode where applicable.
581      * @param computeMaxs <tt>true</tt> if the maximum stack size and the
582      *        maximum number of local variables must be automatically computed.
583      *        If this flag is <tt>true</tt>, then the arguments of the
584      *        {@link MethodVisitor#visitMaxs visitMaxs} method of the
585      *        {@link MethodVisitor} returned by the
586      *        {@link #visitMethod visitMethod} method will be ignored, and
587      *        computed automatically from the signature and the bytecode of each
588      *        method.
589      */
ClassWriter( final ClassReader classReader, final boolean computeMaxs)590     public ClassWriter(
591         final ClassReader classReader,
592         final boolean computeMaxs)
593     {
594         this(computeMaxs, false);
595         classReader.copyPool(this);
596         this.cr = classReader;
597     }
598 
599     // ------------------------------------------------------------------------
600     // Implementation of the ClassVisitor interface
601     // ------------------------------------------------------------------------
602 
603     @Override
visit( final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces)604     public void visit(
605         final int version,
606         final int access,
607         final String name,
608         final String signature,
609         final String superName,
610         final String[] interfaces)
611     {
612         this.version = version;
613         this.access = access;
614         this.name = newClass(name);
615         if (signature != null) {
616             this.signature = newUTF8(signature);
617         }
618         this.superName = superName == null ? 0 : newClass(superName);
619         if (interfaces != null && interfaces.length > 0) {
620             interfaceCount = interfaces.length;
621             this.interfaces = new int[interfaceCount];
622             for (int i = 0; i < interfaceCount; ++i) {
623                 this.interfaces[i] = newClass(interfaces[i]);
624             }
625         }
626     }
627 
628     @Override
visitSource(final String file, final String debug)629     public void visitSource(final String file, final String debug) {
630         if (file != null) {
631             sourceFile = newUTF8(file);
632         }
633         if (debug != null) {
634             sourceDebug = new ByteVector().putUTF8(debug);
635         }
636     }
637 
638     @Override
visitOuterClass( final String owner, final String name, final String desc)639     public void visitOuterClass(
640         final String owner,
641         final String name,
642         final String desc)
643     {
644         enclosingMethodOwner = newClass(owner);
645         if (name != null && desc != null) {
646             enclosingMethod = newNameType(name, desc);
647         }
648     }
649 
650     @Override
visitAnnotation(String desc, boolean visible)651     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
652         ByteVector bv = new ByteVector();
653         // write type, and reserve space for values count
654         bv.putShort(newUTF8(desc)).putShort(0);
655         AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2);
656         if (visible) {
657             aw.next = anns;
658             anns = aw;
659         } else {
660             aw.next = ianns;
661             ianns = aw;
662         }
663         return aw;
664     }
665 
666     //jaime
667     @Override
visitTypeAnnotation(String desc, boolean visible, boolean inCode)668     public TypeAnnotationVisitor visitTypeAnnotation(String desc,
669         boolean visible,
670         boolean inCode)
671     {
672         ByteVector bv = new ByteVector();
673         TypeAnnotationWriter xaw = new TypeAnnotationWriter(this, true, bv, bv, desc);
674         if(visible) {
675             xaw.next = xanns;
676             xanns = xaw;
677         } else {
678             xaw.next = ixanns;
679             ixanns = xaw;
680         }
681 
682         return xaw;
683     }
684     //end jaime
685 
686     @Override
visitAttribute(final Attribute attr)687     public void visitAttribute(final Attribute attr) {
688         attr.next = attrs;
689         attrs = attr;
690     }
691 
692     @Override
visitInnerClass( final String name, final String outerName, final String innerName, final int access)693     public void visitInnerClass(
694         final String name,
695         final String outerName,
696         final String innerName,
697         final int access)
698     {
699         if (innerClasses == null) {
700             innerClasses = new ByteVector();
701         }
702         ++innerClassesCount;
703         innerClasses.putShort(name == null ? 0 : newClass(name));
704         innerClasses.putShort(outerName == null ? 0 : newClass(outerName));
705         innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName));
706         innerClasses.putShort(access);
707     }
708 
709     @Override
visitField( final int access, final String name, final String desc, final String signature, final Object value)710     public FieldVisitor visitField(
711         final int access,
712         final String name,
713         final String desc,
714         final String signature,
715         final Object value)
716     {
717         return new FieldWriter(this, access, name, desc, signature, value);
718     }
719 
720     @Override
visitMethod( final int access, final String name, final String desc, final String signature, final String[] exceptions)721     public MethodVisitor visitMethod(
722         final int access,
723         final String name,
724         final String desc,
725         final String signature,
726         final String[] exceptions)
727     {
728         return new MethodWriter(this,
729                 access,
730                 name,
731                 desc,
732                 signature,
733                 exceptions,
734                 computeMaxs);
735     }
736 
737     @Override
visitEnd()738     public void visitEnd() {
739     }
740 
741     // ------------------------------------------------------------------------
742     // Other public methods
743     // ------------------------------------------------------------------------
744 
745     /**
746      * Returns the bytecode of the class that was build with this class writer.
747      *
748      * @return the bytecode of the class that was build with this class writer.
749      */
toByteArray()750     public byte[] toByteArray() {
751         // computes the real size of the bytecode of this class
752         int size = 24 + 2 * interfaceCount;
753         int nbFields = 0;
754         FieldWriter fb = firstField;
755         while (fb != null) {
756             ++nbFields;
757             size += fb.getSize();
758             fb = fb.next;
759         }
760         int nbMethods = 0;
761         MethodWriter mb = firstMethod;
762         while (mb != null) {
763             ++nbMethods;
764             size += mb.getSize();
765             mb = mb.next;
766         }
767         int attributeCount = 0;
768         if (bootstrapMethods != null) {
769             // we put it as first attribute in order to improve a bit
770             // ClassReader.copyBootstrapMethods
771             ++attributeCount;
772             size += 8 + bootstrapMethods.length;
773             newUTF8("BootstrapMethods");
774         }
775         if (signature != 0) {
776             ++attributeCount;
777             size += 8;
778             newUTF8("Signature");
779         }
780         if (sourceFile != 0) {
781             ++attributeCount;
782             size += 8;
783             newUTF8("SourceFile");
784         }
785         if (sourceDebug != null) {
786             ++attributeCount;
787             size += sourceDebug.length + 4;
788             newUTF8("SourceDebugExtension");
789         }
790         if (enclosingMethodOwner != 0) {
791             ++attributeCount;
792             size += 10;
793             newUTF8("EnclosingMethod");
794         }
795         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
796             ++attributeCount;
797             size += 6;
798             newUTF8("Deprecated");
799         }
800         if ((access & Opcodes.ACC_SYNTHETIC) != 0
801                 && (version & 0xffff) < Opcodes.V1_5)
802         {
803             ++attributeCount;
804             size += 6;
805             newUTF8("Synthetic");
806         }
807         if (version == Opcodes.V1_4) {
808             if ((access & Opcodes.ACC_ANNOTATION) != 0) {
809                 ++attributeCount;
810                 size += 6;
811                 newUTF8("Annotation");
812             }
813             if ((access & Opcodes.ACC_ENUM) != 0) {
814                 ++attributeCount;
815                 size += 6;
816                 newUTF8("Enum");
817             }
818         }
819         if (innerClasses != null) {
820             ++attributeCount;
821             size += 8 + innerClasses.length;
822             newUTF8("InnerClasses");
823         }
824         if (anns != null) {
825             ++attributeCount;
826             size += 8 + anns.getSize();
827             newUTF8("RuntimeVisibleAnnotations");
828         }
829         if (ianns != null) {
830             ++attributeCount;
831             size += 8 + ianns.getSize();
832             newUTF8("RuntimeInvisibleAnnotations");
833         }
834 
835         if(xanns != null) {
836           ++attributeCount;
837           size += 8 + xanns.getSize();
838           newUTF8("RuntimeVisibleTypeAnnotations");
839         }
840         if(ixanns != null) {
841           ++attributeCount;
842           size += 8 + ixanns.getSize();
843           newUTF8("RuntimeInvisibleTypeAnnotations");
844         }
845 
846         if (attrs != null) {
847             attributeCount += attrs.getCount();
848             size += attrs.getSize(this, null, 0, -1, -1);
849         }
850         size += pool.length;
851         // allocates a byte vector of this size, in order to avoid unnecessary
852         // arraycopy operations in the ByteVector.enlarge() method
853         ByteVector out = new ByteVector(size);
854         out.putInt(0xCAFEBABE).putInt(version);
855         out.putShort(index).putByteArray(pool.data, 0, pool.length);
856         out.putShort(access).putShort(name).putShort(superName);
857         out.putShort(interfaceCount);
858         for (int i = 0; i < interfaceCount; ++i) {
859             out.putShort(interfaces[i]);
860         }
861         out.putShort(nbFields);
862         fb = firstField;
863         while (fb != null) {
864             fb.put(out);
865             fb = fb.next;
866         }
867         out.putShort(nbMethods);
868         mb = firstMethod;
869         while (mb != null) {
870             mb.put(out);
871             mb = mb.next;
872         }
873         out.putShort(attributeCount);
874         if (bootstrapMethods != null) {
875             out.putShort(newUTF8("BootstrapMethods"));
876             out.putInt(bootstrapMethods.length + 2).putShort(
877                     bootstrapMethodsCount);
878             out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
879         }
880         if (signature != 0) {
881             out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
882         }
883         if (sourceFile != 0) {
884             out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile);
885         }
886         if (sourceDebug != null) {
887             int len = sourceDebug.length - 2;
888             out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
889             out.putByteArray(sourceDebug.data, 2, len);
890         }
891         if (enclosingMethodOwner != 0) {
892             out.putShort(newUTF8("EnclosingMethod")).putInt(4);
893             out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
894         }
895         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
896             out.putShort(newUTF8("Deprecated")).putInt(0);
897         }
898         if ((access & Opcodes.ACC_SYNTHETIC) != 0
899                 && (version & 0xffff) < Opcodes.V1_5)
900         {
901             out.putShort(newUTF8("Synthetic")).putInt(0);
902         }
903         if (version == Opcodes.V1_4) {
904             if ((access & Opcodes.ACC_ANNOTATION) != 0) {
905                 out.putShort(newUTF8("Annotation")).putInt(0);
906             }
907             if ((access & Opcodes.ACC_ENUM) != 0) {
908                 out.putShort(newUTF8("Enum")).putInt(0);
909             }
910         }
911         if (innerClasses != null) {
912             out.putShort(newUTF8("InnerClasses"));
913             out.putInt(innerClasses.length + 2).putShort(innerClassesCount);
914             out.putByteArray(innerClasses.data, 0, innerClasses.length);
915         }
916         if (anns != null) {
917             out.putShort(newUTF8("RuntimeVisibleAnnotations"));
918             anns.put(out);
919         }
920         if (ianns != null) {
921             out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
922             ianns.put(out);
923         }
924         if(xanns != null) {
925           out.putShort(newUTF8("RuntimeVisibleTypeAnnotations"));
926           xanns.put(out);
927         }
928         if(ixanns != null) {
929           out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations"));
930           ixanns.put(out);
931         }
932         if (attrs != null) {
933             attrs.put(this, null, 0, -1, -1, out);
934         }
935         return out.data;
936     }
937 
938     // ------------------------------------------------------------------------
939     // Utility methods: constant pool management
940     // ------------------------------------------------------------------------
941 
942     /**
943      * Adds a number or string constant to the constant pool of the class being
944      * build. Does nothing if the constant pool already contains a similar item.
945      *
946      * @param cst
947      *            the value of the constant to be added to the constant pool.
948      *            This parameter must be an {@link Integer}, a {@link Float}, a
949      *            {@link Long}, a {@link Double}, a {@link String} or a
950      *            {@link Type}.
951      * @return a new or already existing constant item with the given value.
952      */
newConstItem(final Object cst)953     Item newConstItem(final Object cst) {
954         if (cst instanceof Integer) {
955             int val = ((Integer) cst).intValue();
956             return newInteger(val);
957         } else if (cst instanceof Byte) {
958             int val = ((Byte) cst).intValue();
959             return newInteger(val);
960         } else if (cst instanceof Character) {
961             int val = ((Character) cst).charValue();
962             return newInteger(val);
963         } else if (cst instanceof Short) {
964             int val = ((Short) cst).intValue();
965             return newInteger(val);
966         } else if (cst instanceof Boolean) {
967             int val = ((Boolean) cst).booleanValue() ? 1 : 0;
968             return newInteger(val);
969         } else if (cst instanceof Float) {
970             float val = ((Float) cst).floatValue();
971             return newFloat(val);
972         } else if (cst instanceof Long) {
973             long val = ((Long) cst).longValue();
974             return newLong(val);
975         } else if (cst instanceof Double) {
976             double val = ((Double) cst).doubleValue();
977             return newDouble(val);
978         } else if (cst instanceof String) {
979             return newString((String) cst);
980         } else if (cst instanceof Type) {
981             Type t = (Type) cst;
982             int s = t.getSort();
983             if (s == Type.OBJECT) {
984                 return newClassItem(t.getInternalName());
985             } else if (s == Type.METHOD) {
986                 return newMethodTypeItem(t.getDescriptor());
987             } else { // s == primitive type or array
988                 return newClassItem(t.getDescriptor());
989             }
990         } else if (cst instanceof Handle) {
991             Handle h = (Handle) cst;
992             return newHandleItem(h.tag, h.owner, h.name, h.desc);
993         } else {
994             throw new IllegalArgumentException("value " + cst);
995         }
996     }
997 
998     /**
999      * Adds a number or string constant to the constant pool of the class being
1000      * build. Does nothing if the constant pool already contains a similar item.
1001      * <i>This method is intended for {@link Attribute} sub classes, and is
1002      * normally not needed by class generators or adapters.</i>
1003      *
1004      * @param cst the value of the constant to be added to the constant pool.
1005      *        This parameter must be an {@link Integer}, a {@link Float}, a
1006      *        {@link Long}, a {@link Double} or a {@link String}.
1007      * @return the index of a new or already existing constant item with the
1008      *         given value.
1009      */
newConst(final Object cst)1010     public int newConst(final Object cst) {
1011         return newConstItem(cst).index;
1012     }
1013 
1014     /**
1015      * Adds an UTF8 string to the constant pool of the class being build. Does
1016      * nothing if the constant pool already contains a similar item. <i>This
1017      * method is intended for {@link Attribute} sub classes, and is normally not
1018      * needed by class generators or adapters.</i>
1019      *
1020      * @param value the String value.
1021      * @return the index of a new or already existing UTF8 item.
1022      */
newUTF8(final String value)1023     public int newUTF8(final String value) {
1024         key.set(UTF8, value, null, null);
1025         Item result = get(key);
1026         if (result == null) {
1027             pool.putByte(UTF8).putUTF8(value);
1028             result = new Item(index++, key);
1029             put(result);
1030         }
1031         return result.index;
1032     }
1033 
1034     /**
1035      * Adds a class reference to the constant pool of the class being build.
1036      * Does nothing if the constant pool already contains a similar item.
1037      * <i>This method is intended for {@link Attribute} sub classes, and is
1038      * normally not needed by class generators or adapters.</i>
1039      *
1040      * @param value the internal name of the class.
1041      * @return the index of a new or already existing class reference item.
1042      */
newClass(final String value)1043     public int newClass(final String value) {
1044         return newClassItem(value).index;
1045     }
1046 
1047     /**
1048      * Adds a class reference to the constant pool of the class being build.
1049      * Does nothing if the constant pool already contains a similar item.
1050      * <i>This method is intended for {@link Attribute} sub classes, and is
1051      * normally not needed by class generators or adapters.</i>
1052      *
1053      * @param value the internal name of the class.
1054      * @return a new or already existing class reference item.
1055      */
newClassItem(final String value)1056     private Item newClassItem(final String value) {
1057         key2.set(CLASS, value, null, null);
1058         Item result = get(key2);
1059         if (result == null) {
1060             pool.put12(CLASS, newUTF8(value));
1061             result = new Item(index++, key2);
1062             put(result);
1063         }
1064         return result;
1065     }
1066 
1067     /**
1068      * Adds a method type reference to the constant pool of the class being
1069      * build. Does nothing if the constant pool already contains a similar item.
1070      * <i>This method is intended for {@link Attribute} sub classes, and is
1071      * normally not needed by class generators or adapters.</i>
1072      *
1073      * @param methodDesc
1074      *            method descriptor of the method type.
1075      * @return a new or already existing method type reference item.
1076      */
newMethodTypeItem(final String methodDesc)1077     Item newMethodTypeItem(final String methodDesc) {
1078         key2.set(MTYPE, methodDesc, null, null);
1079         Item result = get(key2);
1080         if (result == null) {
1081             pool.put12(MTYPE, newUTF8(methodDesc));
1082             result = new Item(index++, key2);
1083             put(result);
1084         }
1085         return result;
1086     }
1087 
1088     /**
1089      * Adds a method type reference to the constant pool of the class being
1090      * build. Does nothing if the constant pool already contains a similar item.
1091      * <i>This method is intended for {@link Attribute} sub classes, and is
1092      * normally not needed by class generators or adapters.</i>
1093      *
1094      * @param methodDesc
1095      *            method descriptor of the method type.
1096      * @return the index of a new or already existing method type reference
1097      *         item.
1098      */
newMethodType(final String methodDesc)1099     public int newMethodType(final String methodDesc) {
1100         return newMethodTypeItem(methodDesc).index;
1101     }
1102 
1103     /**
1104      * Adds a handle to the constant pool of the class being build. Does nothing
1105      * if the constant pool already contains a similar item. <i>This method is
1106      * intended for {@link Attribute} sub classes, and is normally not needed by
1107      * class generators or adapters.</i>
1108      *
1109      * @param tag
1110      *            the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
1111      *            {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
1112      *            {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
1113      *            {@link Opcodes#H_INVOKESTATIC},
1114      *            {@link Opcodes#H_INVOKESPECIAL},
1115      *            {@link Opcodes#H_NEWINVOKESPECIAL} or
1116      *            {@link Opcodes#H_INVOKEINTERFACE}.
1117      * @param owner
1118      *            the internal name of the field or method owner class.
1119      * @param name
1120      *            the name of the field or method.
1121      * @param desc
1122      *            the descriptor of the field or method.
1123      * @return a new or an already existing method type reference item.
1124      */
newHandleItem(final int tag, final String owner, final String name, final String desc)1125     Item newHandleItem(final int tag, final String owner, final String name,
1126             final String desc) {
1127         key4.set(HANDLE_BASE + tag, owner, name, desc);
1128         Item result = get(key4);
1129         if (result == null) {
1130             if (tag <= Opcodes.H_PUTSTATIC) {
1131                 put112(HANDLE, tag, newField(owner, name, desc));
1132             } else {
1133                 put112(HANDLE,
1134                         tag,
1135                         newMethod(owner, name, desc,
1136                                 tag == Opcodes.H_INVOKEINTERFACE));
1137             }
1138             result = new Item(index++, key4);
1139             put(result);
1140         }
1141         return result;
1142     }
1143 
1144     /**
1145      * Adds a handle to the constant pool of the class being build. Does nothing
1146      * if the constant pool already contains a similar item. <i>This method is
1147      * intended for {@link Attribute} sub classes, and is normally not needed by
1148      * class generators or adapters.</i>
1149      *
1150      * @param tag
1151      *            the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
1152      *            {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
1153      *            {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
1154      *            {@link Opcodes#H_INVOKESTATIC},
1155      *            {@link Opcodes#H_INVOKESPECIAL},
1156      *            {@link Opcodes#H_NEWINVOKESPECIAL} or
1157      *            {@link Opcodes#H_INVOKEINTERFACE}.
1158      * @param owner
1159      *            the internal name of the field or method owner class.
1160      * @param name
1161      *            the name of the field or method.
1162      * @param desc
1163      *            the descriptor of the field or method.
1164      * @return the index of a new or already existing method type reference
1165      *         item.
1166      */
newHandle(final int tag, final String owner, final String name, final String desc)1167     public int newHandle(final int tag, final String owner, final String name,
1168             final String desc) {
1169         return newHandleItem(tag, owner, name, desc).index;
1170     }
1171 
1172     /**
1173      * Adds an invokedynamic reference to the constant pool of the class being
1174      * build. Does nothing if the constant pool already contains a similar item.
1175      * <i>This method is intended for {@link Attribute} sub classes, and is
1176      * normally not needed by class generators or adapters.</i>
1177      *
1178      * @param name
1179      *            name of the invoked method.
1180      * @param desc
1181      *            descriptor of the invoke method.
1182      * @param bsm
1183      *            the bootstrap method.
1184      * @param bsmArgs
1185      *            the bootstrap method constant arguments.
1186      *
1187      * @return a new or an already existing invokedynamic type reference item.
1188      */
newInvokeDynamicItem(final String name, final String desc, final Handle bsm, final Object... bsmArgs)1189     Item newInvokeDynamicItem(final String name, final String desc,
1190             final Handle bsm, final Object... bsmArgs) {
1191         // cache for performance
1192         ByteVector bootstrapMethods = this.bootstrapMethods;
1193         if (bootstrapMethods == null) {
1194             bootstrapMethods = this.bootstrapMethods = new ByteVector();
1195         }
1196 
1197         int position = bootstrapMethods.length; // record current position
1198 
1199         int hashCode = bsm.hashCode();
1200         bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
1201                 bsm.desc));
1202 
1203         int argsLength = bsmArgs.length;
1204         bootstrapMethods.putShort(argsLength);
1205 
1206         for (int i = 0; i < argsLength; i++) {
1207             Object bsmArg = bsmArgs[i];
1208             hashCode ^= bsmArg.hashCode();
1209             bootstrapMethods.putShort(newConst(bsmArg));
1210         }
1211 
1212         byte[] data = bootstrapMethods.data;
1213         int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments)
1214         hashCode &= 0x7FFFFFFF;
1215         Item result = items[hashCode % items.length];
1216         loop: while (result != null) {
1217             if (result.type != BSM || result.hashCode != hashCode) {
1218                 result = result.next;
1219                 continue;
1220             }
1221 
1222             // because the data encode the size of the argument
1223             // we don't need to test if these size are equals
1224             int resultPosition = result.intVal;
1225             for (int p = 0; p < length; p++) {
1226                 if (data[position + p] != data[resultPosition + p]) {
1227                     result = result.next;
1228                     continue loop;
1229                 }
1230             }
1231             break;
1232         }
1233 
1234         int bootstrapMethodIndex;
1235         if (result != null) {
1236             bootstrapMethodIndex = result.index;
1237             bootstrapMethods.length = position; // revert to old position
1238         } else {
1239             bootstrapMethodIndex = bootstrapMethodsCount++;
1240             result = new Item(bootstrapMethodIndex);
1241             result.set(position, hashCode);
1242             put(result);
1243         }
1244 
1245         // now, create the InvokeDynamic constant
1246         key3.set(name, desc, bootstrapMethodIndex);
1247         result = get(key3);
1248         if (result == null) {
1249             put122(INDY, bootstrapMethodIndex, newNameType(name, desc));
1250             result = new Item(index++, key3);
1251             put(result);
1252         }
1253         return result;
1254     }
1255 
1256     /**
1257      * Adds a field reference to the constant pool of the class being build.
1258      * Does nothing if the constant pool already contains a similar item.
1259      * <i>This method is intended for {@link Attribute} sub classes, and is
1260      * normally not needed by class generators or adapters.</i>
1261      *
1262      * @param owner the internal name of the field's owner class.
1263      * @param name the field's name.
1264      * @param desc the field's descriptor.
1265      * @return the index of a new or already existing field reference item.
1266      */
newField(final String owner, final String name, final String desc)1267     public int newField(final String owner, final String name, final String desc)
1268     {
1269         key3.set(FIELD, owner, name, desc);
1270         Item result = get(key3);
1271         if (result == null) {
1272             put122(FIELD, newClass(owner), newNameType(name, desc));
1273             result = new Item(index++, key3);
1274             put(result);
1275         }
1276         return result.index;
1277     }
1278 
1279     /**
1280      * Adds a method reference to the constant pool of the class being build.
1281      * Does nothing if the constant pool already contains a similar item.
1282      *
1283      * @param owner the internal name of the method's owner class.
1284      * @param name the method's name.
1285      * @param desc the method's descriptor.
1286      * @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
1287      * @return a new or already existing method reference item.
1288      */
newMethodItem( final String owner, final String name, final String desc, final boolean itf)1289     Item newMethodItem(
1290         final String owner,
1291         final String name,
1292         final String desc,
1293         final boolean itf)
1294     {
1295         int type = itf ? IMETH : METH;
1296         key3.set(type, owner, name, desc);
1297         Item result = get(key3);
1298         if (result == null) {
1299             put122(type, newClass(owner), newNameType(name, desc));
1300             result = new Item(index++, key3);
1301             put(result);
1302         }
1303         return result;
1304     }
1305 
1306     /**
1307      * Adds a method reference to the constant pool of the class being build.
1308      * Does nothing if the constant pool already contains a similar item.
1309      * <i>This method is intended for {@link Attribute} sub classes, and is
1310      * normally not needed by class generators or adapters.</i>
1311      *
1312      * @param owner the internal name of the method's owner class.
1313      * @param name the method's name.
1314      * @param desc the method's descriptor.
1315      * @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
1316      * @return the index of a new or already existing method reference item.
1317      */
newMethod( final String owner, final String name, final String desc, final boolean itf)1318     public int newMethod(
1319         final String owner,
1320         final String name,
1321         final String desc,
1322         final boolean itf)
1323     {
1324         return newMethodItem(owner, name, desc, itf).index;
1325     }
1326 
1327     /**
1328      * Adds an integer to the constant pool of the class being build. Does
1329      * nothing if the constant pool already contains a similar item.
1330      *
1331      * @param value the int value.
1332      * @return a new or already existing int item.
1333      */
newInteger(final int value)1334     Item newInteger(final int value) {
1335         key.set(value);
1336         Item result = get(key);
1337         if (result == null) {
1338             pool.putByte(INT).putInt(value);
1339             result = new Item(index++, key);
1340             put(result);
1341         }
1342         return result;
1343     }
1344 
1345     /**
1346      * Adds a float to the constant pool of the class being build. Does nothing
1347      * if the constant pool already contains a similar item.
1348      *
1349      * @param value the float value.
1350      * @return a new or already existing float item.
1351      */
newFloat(final float value)1352     Item newFloat(final float value) {
1353         key.set(value);
1354         Item result = get(key);
1355         if (result == null) {
1356             pool.putByte(FLOAT).putInt(Float.floatToIntBits(value));
1357             result = new Item(index++, key);
1358             put(result);
1359         }
1360         return result;
1361     }
1362 
1363     /**
1364      * Adds a long to the constant pool of the class being build. Does nothing
1365      * if the constant pool already contains a similar item.
1366      *
1367      * @param value the long value.
1368      * @return a new or already existing long item.
1369      */
newLong(final long value)1370     Item newLong(final long value) {
1371         key.set(value);
1372         Item result = get(key);
1373         if (result == null) {
1374             pool.putByte(LONG).putLong(value);
1375             result = new Item(index, key);
1376             put(result);
1377             index += 2;
1378         }
1379         return result;
1380     }
1381 
1382     /**
1383      * Adds a double to the constant pool of the class being build. Does nothing
1384      * if the constant pool already contains a similar item.
1385      *
1386      * @param value the double value.
1387      * @return a new or already existing double item.
1388      */
newDouble(final double value)1389     Item newDouble(final double value) {
1390         key.set(value);
1391         Item result = get(key);
1392         if (result == null) {
1393             pool.putByte(DOUBLE).putLong(Double.doubleToLongBits(value));
1394             result = new Item(index, key);
1395             put(result);
1396             index += 2;
1397         }
1398         return result;
1399     }
1400 
1401     /**
1402      * Adds a string to the constant pool of the class being build. Does nothing
1403      * if the constant pool already contains a similar item.
1404      *
1405      * @param value the String value.
1406      * @return a new or already existing string item.
1407      */
newString(final String value)1408     private Item newString(final String value) {
1409         key2.set(STR, value, null, null);
1410         Item result = get(key2);
1411         if (result == null) {
1412             pool.put12(STR, newUTF8(value));
1413             result = new Item(index++, key2);
1414             put(result);
1415         }
1416         return result;
1417     }
1418 
1419     /**
1420      * Adds a name and type to the constant pool of the class being build. Does
1421      * nothing if the constant pool already contains a similar item. <i>This
1422      * method is intended for {@link Attribute} sub classes, and is normally not
1423      * needed by class generators or adapters.</i>
1424      *
1425      * @param name a name.
1426      * @param desc a type descriptor.
1427      * @return the index of a new or already existing name and type item.
1428      */
newNameType(final String name, final String desc)1429     public int newNameType(final String name, final String desc) {
1430         key2.set(NAME_TYPE, name, desc, null);
1431         Item result = get(key2);
1432         if (result == null) {
1433             put122(NAME_TYPE, newUTF8(name), newUTF8(desc));
1434             result = new Item(index++, key2);
1435             put(result);
1436         }
1437         return result.index;
1438     }
1439 
1440     /**
1441      * Returns the constant pool's hash table item which is equal to the given
1442      * item.
1443      *
1444      * @param key a constant pool item.
1445      * @return the constant pool's hash table item which is equal to the given
1446      *         item, or <tt>null</tt> if there is no such item.
1447      */
get(final Item key)1448     private Item get(final Item key) {
1449         Item i = items[key.hashCode % items.length];
1450         while (i != null && !key.isEqualTo(i)) {
1451             i = i.next;
1452         }
1453         return i;
1454     }
1455 
1456     /**
1457      * Puts the given item in the constant pool's hash table. The hash table
1458      * <i>must</i> not already contains this item.
1459      *
1460      * @param i the item to be added to the constant pool's hash table.
1461      */
put(final Item i)1462     private void put(final Item i) {
1463         if (index > threshold) {
1464             int ll = items.length;
1465             int nl = ll * 2 + 1;
1466             Item[] newItems = new Item[nl];
1467             for (int l = ll - 1; l >= 0; --l) {
1468                 Item j = items[l];
1469                 while (j != null) {
1470                     int index = j.hashCode % newItems.length;
1471                     Item k = j.next;
1472                     j.next = newItems[index];
1473                     newItems[index] = j;
1474                     j = k;
1475                 }
1476             }
1477             items = newItems;
1478             threshold = (int) (nl * 0.75);
1479         }
1480         int index = i.hashCode % items.length;
1481         i.next = items[index];
1482         items[index] = i;
1483     }
1484 
1485     /**
1486      * Puts two bytes and one short into the constant pool.
1487      *
1488      * @param b a byte.
1489      * @param s1 a short.
1490      * @param s2 another short.
1491      */
put112(final int b1, final int b2, final int s)1492     private void put112(final int b1, final int b2, final int s) {
1493         pool.put11(b1, b2).putShort(s);
1494     }
1495 
1496     /**
1497      * Puts one byte and two shorts into the constant pool.
1498      *
1499      * @param b a byte.
1500      * @param s1 a short.
1501      * @param s2 another short.
1502      */
put122(final int b, final int s1, final int s2)1503     private void put122(final int b, final int s1, final int s2) {
1504         pool.put12(b, s1).putShort(s2);
1505     }
1506 }
1507