• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000-2007 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.mockito.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      * Flag to automatically compute the maximum stack size and the maximum
45      * number of local variables of methods. If this flag is set, then the
46      * arguments of the {@link MethodVisitor#visitMaxs visitMaxs} method of the
47      * {@link MethodVisitor} returned by the {@link #visitMethod visitMethod}
48      * method will be ignored, and computed automatically from the signature and
49      * the bytecode of each method.
50      *
51      * @see #ClassWriter(int)
52      */
53     public static final int COMPUTE_MAXS = 1;
54 
55     /**
56      * Flag to automatically compute the stack map frames of methods from
57      * scratch. If this flag is set, then the calls to the
58      * {@link MethodVisitor#visitFrame} method are ignored, and the stack map
59      * frames are recomputed from the methods bytecode. The arguments of the
60      * {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and
61      * recomputed from the bytecode. In other words, computeFrames implies
62      * computeMaxs.
63      *
64      * @see #ClassWriter(int)
65      */
66     public static final int COMPUTE_FRAMES = 2;
67 
68     /**
69      * The type of instructions without any argument.
70      */
71     static final int NOARG_INSN = 0;
72 
73     /**
74      * The type of instructions with an signed byte argument.
75      */
76     static final int SBYTE_INSN = 1;
77 
78     /**
79      * The type of instructions with an signed short argument.
80      */
81     static final int SHORT_INSN = 2;
82 
83     /**
84      * The type of instructions with a local variable index argument.
85      */
86     static final int VAR_INSN = 3;
87 
88     /**
89      * The type of instructions with an implicit local variable index argument.
90      */
91     static final int IMPLVAR_INSN = 4;
92 
93     /**
94      * The type of instructions with a type descriptor argument.
95      */
96     static final int TYPE_INSN = 5;
97 
98     /**
99      * The type of field and method invocations instructions.
100      */
101     static final int FIELDORMETH_INSN = 6;
102 
103     /**
104      * The type of the INVOKEINTERFACE instruction.
105      */
106     static final int ITFMETH_INSN = 7;
107 
108     /**
109      * The type of instructions with a 2 bytes bytecode offset label.
110      */
111     static final int LABEL_INSN = 8;
112 
113     /**
114      * The type of instructions with a 4 bytes bytecode offset label.
115      */
116     static final int LABELW_INSN = 9;
117 
118     /**
119      * The type of the LDC instruction.
120      */
121     static final int LDC_INSN = 10;
122 
123     /**
124      * The type of the LDC_W and LDC2_W instructions.
125      */
126     static final int LDCW_INSN = 11;
127 
128     /**
129      * The type of the IINC instruction.
130      */
131     static final int IINC_INSN = 12;
132 
133     /**
134      * The type of the TABLESWITCH instruction.
135      */
136     static final int TABL_INSN = 13;
137 
138     /**
139      * The type of the LOOKUPSWITCH instruction.
140      */
141     static final int LOOK_INSN = 14;
142 
143     /**
144      * The type of the MULTIANEWARRAY instruction.
145      */
146     static final int MANA_INSN = 15;
147 
148     /**
149      * The type of the WIDE instruction.
150      */
151     static final int WIDE_INSN = 16;
152 
153     /**
154      * The instruction types of all JVM opcodes.
155      */
156     static final byte[] TYPE;
157 
158     /**
159      * The type of CONSTANT_Class constant pool items.
160      */
161     static final int CLASS = 7;
162 
163     /**
164      * The type of CONSTANT_Fieldref constant pool items.
165      */
166     static final int FIELD = 9;
167 
168     /**
169      * The type of CONSTANT_Methodref constant pool items.
170      */
171     static final int METH = 10;
172 
173     /**
174      * The type of CONSTANT_InterfaceMethodref constant pool items.
175      */
176     static final int IMETH = 11;
177 
178     /**
179      * The type of CONSTANT_String constant pool items.
180      */
181     static final int STR = 8;
182 
183     /**
184      * The type of CONSTANT_Integer constant pool items.
185      */
186     static final int INT = 3;
187 
188     /**
189      * The type of CONSTANT_Float constant pool items.
190      */
191     static final int FLOAT = 4;
192 
193     /**
194      * The type of CONSTANT_Long constant pool items.
195      */
196     static final int LONG = 5;
197 
198     /**
199      * The type of CONSTANT_Double constant pool items.
200      */
201     static final int DOUBLE = 6;
202 
203     /**
204      * The type of CONSTANT_NameAndType constant pool items.
205      */
206     static final int NAME_TYPE = 12;
207 
208     /**
209      * The type of CONSTANT_Utf8 constant pool items.
210      */
211     static final int UTF8 = 1;
212 
213     /**
214      * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable},
215      * instead of the constant pool, in order to avoid clashes with normal
216      * constant pool items in the ClassWriter constant pool's hash table.
217      */
218     static final int TYPE_NORMAL = 13;
219 
220     /**
221      * Uninitialized type Item stored in the ClassWriter
222      * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
223      * avoid clashes with normal constant pool items in the ClassWriter constant
224      * pool's hash table.
225      */
226     static final int TYPE_UNINIT = 14;
227 
228     /**
229      * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable},
230      * instead of the constant pool, in order to avoid clashes with normal
231      * constant pool items in the ClassWriter constant pool's hash table.
232      */
233     static final int TYPE_MERGED = 15;
234 
235     /**
236      * The class reader from which this class writer was constructed, if any.
237      */
238     ClassReader cr;
239 
240     /**
241      * Minor and major version numbers of the class to be generated.
242      */
243     int version;
244 
245     /**
246      * Index of the next item to be added in the constant pool.
247      */
248     int index;
249 
250     /**
251      * The constant pool of this class.
252      */
253     final ByteVector pool;
254 
255     /**
256      * The constant pool's hash table data.
257      */
258     Item[] items;
259 
260     /**
261      * The threshold of the constant pool's hash table.
262      */
263     int threshold;
264 
265     /**
266      * A reusable key used to look for items in the {@link #items} hash table.
267      */
268     final Item key;
269 
270     /**
271      * A reusable key used to look for items in the {@link #items} hash table.
272      */
273     final Item key2;
274 
275     /**
276      * A reusable key used to look for items in the {@link #items} hash table.
277      */
278     final Item key3;
279 
280     /**
281      * A type table used to temporarily store internal names that will not
282      * necessarily be stored in the constant pool. This type table is used by
283      * the control flow and data flow analysis algorithm used to compute stack
284      * map frames from scratch. This array associates to each index <tt>i</tt>
285      * the Item whose index is <tt>i</tt>. All Item objects stored in this
286      * array are also stored in the {@link #items} hash table. These two arrays
287      * allow to retrieve an Item from its index or, conversely, to get the index
288      * of an Item from its value. Each Item stores an internal name in its
289      * {@link Item#strVal1} field.
290      */
291     Item[] typeTable;
292 
293     /**
294      * Number of elements in the {@link #typeTable} array.
295      */
296     private short typeCount;
297 
298     /**
299      * The access flags of this class.
300      */
301     private int access;
302 
303     /**
304      * The constant pool item that contains the internal name of this class.
305      */
306     private int name;
307 
308     /**
309      * The internal name of this class.
310      */
311     String thisName;
312 
313     /**
314      * The constant pool item that contains the signature of this class.
315      */
316     private int signature;
317 
318     /**
319      * The constant pool item that contains the internal name of the super class
320      * of this class.
321      */
322     private int superName;
323 
324     /**
325      * Number of interfaces implemented or extended by this class or interface.
326      */
327     private int interfaceCount;
328 
329     /**
330      * The interfaces implemented or extended by this class or interface. More
331      * precisely, this array contains the indexes of the constant pool items
332      * that contain the internal names of these interfaces.
333      */
334     private int[] interfaces;
335 
336     /**
337      * The index of the constant pool item that contains the name of the source
338      * file from which this class was compiled.
339      */
340     private int sourceFile;
341 
342     /**
343      * The SourceDebug attribute of this class.
344      */
345     private ByteVector sourceDebug;
346 
347     /**
348      * The constant pool item that contains the name of the enclosing class of
349      * this class.
350      */
351     private int enclosingMethodOwner;
352 
353     /**
354      * The constant pool item that contains the name and descriptor of the
355      * enclosing method of this class.
356      */
357     private int enclosingMethod;
358 
359     /**
360      * The runtime visible annotations of this class.
361      */
362     private AnnotationWriter anns;
363 
364     /**
365      * The runtime invisible annotations of this class.
366      */
367     private AnnotationWriter ianns;
368 
369     /**
370      * The non standard attributes of this class.
371      */
372     private Attribute attrs;
373 
374     /**
375      * The number of entries in the InnerClasses attribute.
376      */
377     private int innerClassesCount;
378 
379     /**
380      * The InnerClasses attribute.
381      */
382     private ByteVector innerClasses;
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      * <tt>true</tt> if the stack map frames must be recomputed from scratch.
424      */
425     private final boolean computeFrames;
426 
427     /**
428      * <tt>true</tt> if the stack map tables of this class are invalid. The
429      * {@link MethodWriter#resizeInstructions} method cannot transform existing
430      * stack map tables, and so produces potentially invalid classes when it is
431      * executed. In this case the class is reread and rewritten with the
432      * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize
433      * stack map tables when this option is used).
434      */
435     boolean invalidFrames;
436 
437     // ------------------------------------------------------------------------
438     // Static initializer
439     // ------------------------------------------------------------------------
440 
441     /**
442      * Computes the instruction types of JVM opcodes.
443      */
444     static {
445         int i;
446         byte[] b = new byte[220];
447         String s = "AAAAAAAAAAAAAAAABCKLLDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
448                 + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
449                 + "AAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAIIIIIIIIIIIIIIIIDNOAA"
450                 + "AAAAGGGGGGGHAFBFAAFFAAQPIIJJIIIIIIIIIIIIIIIIII";
451         for (i = 0; i < b.length; ++i) {
452             b[i] = (byte) (s.charAt(i) - 'A');
453         }
454         TYPE = b;
455 
456         // code to generate the above string
457         //
458         // // SBYTE_INSN instructions
459         // b[Constants.NEWARRAY] = SBYTE_INSN;
460         // b[Constants.BIPUSH] = SBYTE_INSN;
461         //
462         // // SHORT_INSN instructions
463         // b[Constants.SIPUSH] = SHORT_INSN;
464         //
465         // // (IMPL)VAR_INSN instructions
466         // b[Constants.RET] = VAR_INSN;
467         // for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) {
468         // b[i] = VAR_INSN;
469         // }
470         // for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) {
471         // b[i] = VAR_INSN;
472         // }
473         // for (i = 26; i <= 45; ++i) { // ILOAD_0 to ALOAD_3
474         // b[i] = IMPLVAR_INSN;
475         // }
476         // for (i = 59; i <= 78; ++i) { // ISTORE_0 to ASTORE_3
477         // b[i] = IMPLVAR_INSN;
478         // }
479         //
480         // // TYPE_INSN instructions
481         // b[Constants.NEW] = TYPE_INSN;
482         // b[Constants.ANEWARRAY] = TYPE_INSN;
483         // b[Constants.CHECKCAST] = TYPE_INSN;
484         // b[Constants.INSTANCEOF] = TYPE_INSN;
485         //
486         // // (Set)FIELDORMETH_INSN instructions
487         // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) {
488         // b[i] = FIELDORMETH_INSN;
489         // }
490         // b[Constants.INVOKEINTERFACE] = ITFMETH_INSN;
491         //
492         // // LABEL(W)_INSN instructions
493         // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) {
494         // b[i] = LABEL_INSN;
495         // }
496         // b[Constants.IFNULL] = LABEL_INSN;
497         // b[Constants.IFNONNULL] = LABEL_INSN;
498         // b[200] = LABELW_INSN; // GOTO_W
499         // b[201] = LABELW_INSN; // JSR_W
500         // // temporary opcodes used internally by ASM - see Label and
501         // MethodWriter
502         // for (i = 202; i < 220; ++i) {
503         // b[i] = LABEL_INSN;
504         // }
505         //
506         // // LDC(_W) instructions
507         // b[Constants.LDC] = LDC_INSN;
508         // b[19] = LDCW_INSN; // LDC_W
509         // b[20] = LDCW_INSN; // LDC2_W
510         //
511         // // special instructions
512         // b[Constants.IINC] = IINC_INSN;
513         // b[Constants.TABLESWITCH] = TABL_INSN;
514         // b[Constants.LOOKUPSWITCH] = LOOK_INSN;
515         // b[Constants.MULTIANEWARRAY] = MANA_INSN;
516         // b[196] = WIDE_INSN; // WIDE
517         //
518         // for (i = 0; i < b.length; ++i) {
519         // System.err.print((char)('A' + b[i]));
520         // }
521         // System.err.println();
522     }
523 
524     // ------------------------------------------------------------------------
525     // Constructor
526     // ------------------------------------------------------------------------
527 
528     /**
529      * Constructs a new {@link ClassWriter} object.
530      *
531      * @param flags option flags that can be used to modify the default behavior
532      *        of this class. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}.
533      */
ClassWriter(final int flags)534     public ClassWriter(final int flags) {
535         index = 1;
536         pool = new ByteVector();
537         items = new Item[256];
538         threshold = (int) (0.75d * items.length);
539         key = new Item();
540         key2 = new Item();
541         key3 = new Item();
542         this.computeMaxs = (flags & COMPUTE_MAXS) != 0;
543         this.computeFrames = (flags & COMPUTE_FRAMES) != 0;
544     }
545 
546     /**
547      * Constructs a new {@link ClassWriter} object and enables optimizations for
548      * "mostly add" bytecode transformations. These optimizations are the
549      * following:
550      *
551      * <ul> <li>The constant pool from the original class is copied as is in
552      * the new class, which saves time. New constant pool entries will be added
553      * at the end if necessary, but unused constant pool entries <i>won't be
554      * removed</i>.</li> <li>Methods that are not transformed are copied as
555      * is in the new class, directly from the original class bytecode (i.e.
556      * without emitting visit events for all the method instructions), which
557      * saves a <i>lot</i> of time. Untransformed methods are detected by the
558      * fact that the {@link ClassReader} receives {@link MethodVisitor} objects
559      * that come from a {@link ClassWriter} (and not from a custom
560      * {@link ClassAdapter} or any other {@link ClassVisitor} instance).</li>
561      * </ul>
562      *
563      * @param classReader the {@link ClassReader} used to read the original
564      *        class. It will be used to copy the entire constant pool from the
565      *        original class and also to copy other fragments of original
566      *        bytecode where applicable.
567      * @param flags option flags that can be used to modify the default behavior
568      *        of this class. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}.
569      */
ClassWriter(final ClassReader classReader, final int flags)570     public ClassWriter(final ClassReader classReader, final int flags) {
571         this(flags);
572         classReader.copyPool(this);
573         this.cr = classReader;
574     }
575 
576     // ------------------------------------------------------------------------
577     // Implementation of the ClassVisitor interface
578     // ------------------------------------------------------------------------
579 
visit( final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces)580     public void visit(
581         final int version,
582         final int access,
583         final String name,
584         final String signature,
585         final String superName,
586         final String[] interfaces)
587     {
588         this.version = version;
589         this.access = access;
590         this.name = newClass(name);
591         thisName = name;
592         if (ClassReader.SIGNATURES && signature != null) {
593             this.signature = newUTF8(signature);
594         }
595         this.superName = superName == null ? 0 : newClass(superName);
596         if (interfaces != null && interfaces.length > 0) {
597             interfaceCount = interfaces.length;
598             this.interfaces = new int[interfaceCount];
599             for (int i = 0; i < interfaceCount; ++i) {
600                 this.interfaces[i] = newClass(interfaces[i]);
601             }
602         }
603     }
604 
visitSource(final String file, final String debug)605     public void visitSource(final String file, final String debug) {
606         if (file != null) {
607             sourceFile = newUTF8(file);
608         }
609         if (debug != null) {
610             sourceDebug = new ByteVector().putUTF8(debug);
611         }
612     }
613 
visitOuterClass( final String owner, final String name, final String desc)614     public void visitOuterClass(
615         final String owner,
616         final String name,
617         final String desc)
618     {
619         enclosingMethodOwner = newClass(owner);
620         if (name != null && desc != null) {
621             enclosingMethod = newNameType(name, desc);
622         }
623     }
624 
visitAnnotation( final String desc, final boolean visible)625     public AnnotationVisitor visitAnnotation(
626         final String desc,
627         final boolean visible)
628     {
629         if (!ClassReader.ANNOTATIONS) {
630             return null;
631         }
632         ByteVector bv = new ByteVector();
633         // write type, and reserve space for values count
634         bv.putShort(newUTF8(desc)).putShort(0);
635         AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2);
636         if (visible) {
637             aw.next = anns;
638             anns = aw;
639         } else {
640             aw.next = ianns;
641             ianns = aw;
642         }
643         return aw;
644     }
645 
visitAttribute(final Attribute attr)646     public void visitAttribute(final Attribute attr) {
647         attr.next = attrs;
648         attrs = attr;
649     }
650 
visitInnerClass( final String name, final String outerName, final String innerName, final int access)651     public void visitInnerClass(
652         final String name,
653         final String outerName,
654         final String innerName,
655         final int access)
656     {
657         if (innerClasses == null) {
658             innerClasses = new ByteVector();
659         }
660         ++innerClassesCount;
661         innerClasses.putShort(name == null ? 0 : newClass(name));
662         innerClasses.putShort(outerName == null ? 0 : newClass(outerName));
663         innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName));
664         innerClasses.putShort(access);
665     }
666 
visitField( final int access, final String name, final String desc, final String signature, final Object value)667     public FieldVisitor visitField(
668         final int access,
669         final String name,
670         final String desc,
671         final String signature,
672         final Object value)
673     {
674         return new FieldWriter(this, access, name, desc, signature, value);
675     }
676 
visitMethod( final int access, final String name, final String desc, final String signature, final String[] exceptions)677     public MethodVisitor visitMethod(
678         final int access,
679         final String name,
680         final String desc,
681         final String signature,
682         final String[] exceptions)
683     {
684         return new MethodWriter(this,
685                 access,
686                 name,
687                 desc,
688                 signature,
689                 exceptions,
690                 computeMaxs,
691                 computeFrames);
692     }
693 
visitEnd()694     public void visitEnd() {
695     }
696 
697     // ------------------------------------------------------------------------
698     // Other public methods
699     // ------------------------------------------------------------------------
700 
701     /**
702      * Returns the bytecode of the class that was build with this class writer.
703      *
704      * @return the bytecode of the class that was build with this class writer.
705      */
toByteArray()706     public byte[] toByteArray() {
707         // computes the real size of the bytecode of this class
708         int size = 24 + 2 * interfaceCount;
709         int nbFields = 0;
710         FieldWriter fb = firstField;
711         while (fb != null) {
712             ++nbFields;
713             size += fb.getSize();
714             fb = fb.next;
715         }
716         int nbMethods = 0;
717         MethodWriter mb = firstMethod;
718         while (mb != null) {
719             ++nbMethods;
720             size += mb.getSize();
721             mb = mb.next;
722         }
723         int attributeCount = 0;
724         if (ClassReader.SIGNATURES && signature != 0) {
725             ++attributeCount;
726             size += 8;
727             newUTF8("Signature");
728         }
729         if (sourceFile != 0) {
730             ++attributeCount;
731             size += 8;
732             newUTF8("SourceFile");
733         }
734         if (sourceDebug != null) {
735             ++attributeCount;
736             size += sourceDebug.length + 4;
737             newUTF8("SourceDebugExtension");
738         }
739         if (enclosingMethodOwner != 0) {
740             ++attributeCount;
741             size += 10;
742             newUTF8("EnclosingMethod");
743         }
744         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
745             ++attributeCount;
746             size += 6;
747             newUTF8("Deprecated");
748         }
749         if ((access & Opcodes.ACC_SYNTHETIC) != 0
750                 && (version & 0xffff) < Opcodes.V1_5)
751         {
752             ++attributeCount;
753             size += 6;
754             newUTF8("Synthetic");
755         }
756         if (innerClasses != null) {
757             ++attributeCount;
758             size += 8 + innerClasses.length;
759             newUTF8("InnerClasses");
760         }
761         if (ClassReader.ANNOTATIONS && anns != null) {
762             ++attributeCount;
763             size += 8 + anns.getSize();
764             newUTF8("RuntimeVisibleAnnotations");
765         }
766         if (ClassReader.ANNOTATIONS && ianns != null) {
767             ++attributeCount;
768             size += 8 + ianns.getSize();
769             newUTF8("RuntimeInvisibleAnnotations");
770         }
771         if (attrs != null) {
772             attributeCount += attrs.getCount();
773             size += attrs.getSize(this, null, 0, -1, -1);
774         }
775         size += pool.length;
776         // allocates a byte vector of this size, in order to avoid unnecessary
777         // arraycopy operations in the ByteVector.enlarge() method
778         ByteVector out = new ByteVector(size);
779         out.putInt(0xCAFEBABE).putInt(version);
780         out.putShort(index).putByteArray(pool.data, 0, pool.length);
781         out.putShort(access).putShort(name).putShort(superName);
782         out.putShort(interfaceCount);
783         for (int i = 0; i < interfaceCount; ++i) {
784             out.putShort(interfaces[i]);
785         }
786         out.putShort(nbFields);
787         fb = firstField;
788         while (fb != null) {
789             fb.put(out);
790             fb = fb.next;
791         }
792         out.putShort(nbMethods);
793         mb = firstMethod;
794         while (mb != null) {
795             mb.put(out);
796             mb = mb.next;
797         }
798         out.putShort(attributeCount);
799         if (ClassReader.SIGNATURES && signature != 0) {
800             out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
801         }
802         if (sourceFile != 0) {
803             out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile);
804         }
805         if (sourceDebug != null) {
806             int len = sourceDebug.length - 2;
807             out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
808             out.putByteArray(sourceDebug.data, 2, len);
809         }
810         if (enclosingMethodOwner != 0) {
811             out.putShort(newUTF8("EnclosingMethod")).putInt(4);
812             out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
813         }
814         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
815             out.putShort(newUTF8("Deprecated")).putInt(0);
816         }
817         if ((access & Opcodes.ACC_SYNTHETIC) != 0
818                 && (version & 0xffff) < Opcodes.V1_5)
819         {
820             out.putShort(newUTF8("Synthetic")).putInt(0);
821         }
822         if (innerClasses != null) {
823             out.putShort(newUTF8("InnerClasses"));
824             out.putInt(innerClasses.length + 2).putShort(innerClassesCount);
825             out.putByteArray(innerClasses.data, 0, innerClasses.length);
826         }
827         if (ClassReader.ANNOTATIONS && anns != null) {
828             out.putShort(newUTF8("RuntimeVisibleAnnotations"));
829             anns.put(out);
830         }
831         if (ClassReader.ANNOTATIONS && ianns != null) {
832             out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
833             ianns.put(out);
834         }
835         if (attrs != null) {
836             attrs.put(this, null, 0, -1, -1, out);
837         }
838         if (invalidFrames) {
839             ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
840             new ClassReader(out.data).accept(cw, ClassReader.SKIP_FRAMES);
841             return cw.toByteArray();
842         }
843         return out.data;
844     }
845 
846     // ------------------------------------------------------------------------
847     // Utility methods: constant pool management
848     // ------------------------------------------------------------------------
849 
850     /**
851      * Adds a number or string constant to the constant pool of the class being
852      * build. Does nothing if the constant pool already contains a similar item.
853      *
854      * @param cst the value of the constant to be added to the constant pool.
855      *        This parameter must be an {@link Integer}, a {@link Float}, a
856      *        {@link Long}, a {@link Double}, a {@link String} or a
857      *        {@link Type}.
858      * @return a new or already existing constant item with the given value.
859      */
newConstItem(final Object cst)860     Item newConstItem(final Object cst) {
861         if (cst instanceof Integer) {
862             int val = ((Integer) cst).intValue();
863             return newInteger(val);
864         } else if (cst instanceof Byte) {
865             int val = ((Byte) cst).intValue();
866             return newInteger(val);
867         } else if (cst instanceof Character) {
868             int val = ((Character) cst).charValue();
869             return newInteger(val);
870         } else if (cst instanceof Short) {
871             int val = ((Short) cst).intValue();
872             return newInteger(val);
873         } else if (cst instanceof Boolean) {
874             int val = ((Boolean) cst).booleanValue() ? 1 : 0;
875             return newInteger(val);
876         } else if (cst instanceof Float) {
877             float val = ((Float) cst).floatValue();
878             return newFloat(val);
879         } else if (cst instanceof Long) {
880             long val = ((Long) cst).longValue();
881             return newLong(val);
882         } else if (cst instanceof Double) {
883             double val = ((Double) cst).doubleValue();
884             return newDouble(val);
885         } else if (cst instanceof String) {
886             return newString((String) cst);
887         } else if (cst instanceof Type) {
888             Type t = (Type) cst;
889             return newClassItem(t.getSort() == Type.OBJECT
890                     ? t.getInternalName()
891                     : t.getDescriptor());
892         } else {
893             throw new IllegalArgumentException("value " + cst);
894         }
895     }
896 
897     /**
898      * Adds a number or string constant to the constant pool of the class being
899      * build. Does nothing if the constant pool already contains a similar item.
900      * <i>This method is intended for {@link Attribute} sub classes, and is
901      * normally not needed by class generators or adapters.</i>
902      *
903      * @param cst the value of the constant to be added to the constant pool.
904      *        This parameter must be an {@link Integer}, a {@link Float}, a
905      *        {@link Long}, a {@link Double} or a {@link String}.
906      * @return the index of a new or already existing constant item with the
907      *         given value.
908      */
newConst(final Object cst)909     public int newConst(final Object cst) {
910         return newConstItem(cst).index;
911     }
912 
913     /**
914      * Adds an UTF8 string to the constant pool of the class being build. Does
915      * nothing if the constant pool already contains a similar item. <i>This
916      * method is intended for {@link Attribute} sub classes, and is normally not
917      * needed by class generators or adapters.</i>
918      *
919      * @param value the String value.
920      * @return the index of a new or already existing UTF8 item.
921      */
newUTF8(final String value)922     public int newUTF8(final String value) {
923         key.set(UTF8, value, null, null);
924         Item result = get(key);
925         if (result == null) {
926             pool.putByte(UTF8).putUTF8(value);
927             result = new Item(index++, key);
928             put(result);
929         }
930         return result.index;
931     }
932 
933     /**
934      * Adds a class reference to the constant pool of the class being build.
935      * Does nothing if the constant pool already contains a similar item.
936      * <i>This method is intended for {@link Attribute} sub classes, and is
937      * normally not needed by class generators or adapters.</i>
938      *
939      * @param value the internal name of the class.
940      * @return a new or already existing class reference item.
941      */
newClassItem(final String value)942     Item newClassItem(final String value) {
943         key2.set(CLASS, value, null, null);
944         Item result = get(key2);
945         if (result == null) {
946             pool.put12(CLASS, newUTF8(value));
947             result = new Item(index++, key2);
948             put(result);
949         }
950         return result;
951     }
952 
953     /**
954      * Adds a class reference to the constant pool of the class being build.
955      * Does nothing if the constant pool already contains a similar item.
956      * <i>This method is intended for {@link Attribute} sub classes, and is
957      * normally not needed by class generators or adapters.</i>
958      *
959      * @param value the internal name of the class.
960      * @return the index of a new or already existing class reference item.
961      */
newClass(final String value)962     public int newClass(final String value) {
963         return newClassItem(value).index;
964     }
965 
966     /**
967      * Adds a field reference to the constant pool of the class being build.
968      * Does nothing if the constant pool already contains a similar item.
969      *
970      * @param owner the internal name of the field's owner class.
971      * @param name the field's name.
972      * @param desc the field's descriptor.
973      * @return a new or already existing field reference item.
974      */
newFieldItem(final String owner, final String name, final String desc)975     Item newFieldItem(final String owner, final String name, final String desc)
976     {
977         key3.set(FIELD, owner, name, desc);
978         Item result = get(key3);
979         if (result == null) {
980             put122(FIELD, newClass(owner), newNameType(name, desc));
981             result = new Item(index++, key3);
982             put(result);
983         }
984         return result;
985     }
986 
987     /**
988      * Adds a field reference to the constant pool of the class being build.
989      * Does nothing if the constant pool already contains a similar item.
990      * <i>This method is intended for {@link Attribute} sub classes, and is
991      * normally not needed by class generators or adapters.</i>
992      *
993      * @param owner the internal name of the field's owner class.
994      * @param name the field's name.
995      * @param desc the field's descriptor.
996      * @return the index of a new or already existing field reference item.
997      */
newField(final String owner, final String name, final String desc)998     public int newField(final String owner, final String name, final String desc)
999     {
1000         return newFieldItem(owner, name, desc).index;
1001     }
1002 
1003     /**
1004      * Adds a method reference to the constant pool of the class being build.
1005      * Does nothing if the constant pool already contains a similar item.
1006      *
1007      * @param owner the internal name of the method's owner class.
1008      * @param name the method's name.
1009      * @param desc the method's descriptor.
1010      * @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
1011      * @return a new or already existing method reference item.
1012      */
newMethodItem( final String owner, final String name, final String desc, final boolean itf)1013     Item newMethodItem(
1014         final String owner,
1015         final String name,
1016         final String desc,
1017         final boolean itf)
1018     {
1019         int type = itf ? IMETH : METH;
1020         key3.set(type, owner, name, desc);
1021         Item result = get(key3);
1022         if (result == null) {
1023             put122(type, newClass(owner), newNameType(name, desc));
1024             result = new Item(index++, key3);
1025             put(result);
1026         }
1027         return result;
1028     }
1029 
1030     /**
1031      * Adds a method reference to the constant pool of the class being build.
1032      * Does nothing if the constant pool already contains a similar item.
1033      * <i>This method is intended for {@link Attribute} sub classes, and is
1034      * normally not needed by class generators or adapters.</i>
1035      *
1036      * @param owner the internal name of the method's owner class.
1037      * @param name the method's name.
1038      * @param desc the method's descriptor.
1039      * @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
1040      * @return the index of a new or already existing method reference item.
1041      */
newMethod( final String owner, final String name, final String desc, final boolean itf)1042     public int newMethod(
1043         final String owner,
1044         final String name,
1045         final String desc,
1046         final boolean itf)
1047     {
1048         return newMethodItem(owner, name, desc, itf).index;
1049     }
1050 
1051     /**
1052      * Adds an integer to the constant pool of the class being build. Does
1053      * nothing if the constant pool already contains a similar item.
1054      *
1055      * @param value the int value.
1056      * @return a new or already existing int item.
1057      */
newInteger(final int value)1058     Item newInteger(final int value) {
1059         key.set(value);
1060         Item result = get(key);
1061         if (result == null) {
1062             pool.putByte(INT).putInt(value);
1063             result = new Item(index++, key);
1064             put(result);
1065         }
1066         return result;
1067     }
1068 
1069     /**
1070      * Adds a float to the constant pool of the class being build. Does nothing
1071      * if the constant pool already contains a similar item.
1072      *
1073      * @param value the float value.
1074      * @return a new or already existing float item.
1075      */
newFloat(final float value)1076     Item newFloat(final float value) {
1077         key.set(value);
1078         Item result = get(key);
1079         if (result == null) {
1080             pool.putByte(FLOAT).putInt(key.intVal);
1081             result = new Item(index++, key);
1082             put(result);
1083         }
1084         return result;
1085     }
1086 
1087     /**
1088      * Adds a long to the constant pool of the class being build. Does nothing
1089      * if the constant pool already contains a similar item.
1090      *
1091      * @param value the long value.
1092      * @return a new or already existing long item.
1093      */
newLong(final long value)1094     Item newLong(final long value) {
1095         key.set(value);
1096         Item result = get(key);
1097         if (result == null) {
1098             pool.putByte(LONG).putLong(value);
1099             result = new Item(index, key);
1100             put(result);
1101             index += 2;
1102         }
1103         return result;
1104     }
1105 
1106     /**
1107      * Adds a double to the constant pool of the class being build. Does nothing
1108      * if the constant pool already contains a similar item.
1109      *
1110      * @param value the double value.
1111      * @return a new or already existing double item.
1112      */
newDouble(final double value)1113     Item newDouble(final double value) {
1114         key.set(value);
1115         Item result = get(key);
1116         if (result == null) {
1117             pool.putByte(DOUBLE).putLong(key.longVal);
1118             result = new Item(index, key);
1119             put(result);
1120             index += 2;
1121         }
1122         return result;
1123     }
1124 
1125     /**
1126      * Adds a string to the constant pool of the class being build. Does nothing
1127      * if the constant pool already contains a similar item.
1128      *
1129      * @param value the String value.
1130      * @return a new or already existing string item.
1131      */
newString(final String value)1132     private Item newString(final String value) {
1133         key2.set(STR, value, null, null);
1134         Item result = get(key2);
1135         if (result == null) {
1136             pool.put12(STR, newUTF8(value));
1137             result = new Item(index++, key2);
1138             put(result);
1139         }
1140         return result;
1141     }
1142 
1143     /**
1144      * Adds a name and type to the constant pool of the class being build. Does
1145      * nothing if the constant pool already contains a similar item. <i>This
1146      * method is intended for {@link Attribute} sub classes, and is normally not
1147      * needed by class generators or adapters.</i>
1148      *
1149      * @param name a name.
1150      * @param desc a type descriptor.
1151      * @return the index of a new or already existing name and type item.
1152      */
newNameType(final String name, final String desc)1153     public int newNameType(final String name, final String desc) {
1154         key2.set(NAME_TYPE, name, desc, null);
1155         Item result = get(key2);
1156         if (result == null) {
1157             put122(NAME_TYPE, newUTF8(name), newUTF8(desc));
1158             result = new Item(index++, key2);
1159             put(result);
1160         }
1161         return result.index;
1162     }
1163 
1164     /**
1165      * Adds the given internal name to {@link #typeTable} and returns its index.
1166      * Does nothing if the type table already contains this internal name.
1167      *
1168      * @param type the internal name to be added to the type table.
1169      * @return the index of this internal name in the type table.
1170      */
addType(final String type)1171     int addType(final String type) {
1172         key.set(TYPE_NORMAL, type, null, null);
1173         Item result = get(key);
1174         if (result == null) {
1175             result = addType(key);
1176         }
1177         return result.index;
1178     }
1179 
1180     /**
1181      * Adds the given "uninitialized" type to {@link #typeTable} and returns its
1182      * index. This method is used for UNINITIALIZED types, made of an internal
1183      * name and a bytecode offset.
1184      *
1185      * @param type the internal name to be added to the type table.
1186      * @param offset the bytecode offset of the NEW instruction that created
1187      *        this UNINITIALIZED type value.
1188      * @return the index of this internal name in the type table.
1189      */
addUninitializedType(final String type, final int offset)1190     int addUninitializedType(final String type, final int offset) {
1191         key.type = TYPE_UNINIT;
1192         key.intVal = offset;
1193         key.strVal1 = type;
1194         key.hashCode = 0x7FFFFFFF & (TYPE_UNINIT + type.hashCode() + offset);
1195         Item result = get(key);
1196         if (result == null) {
1197             result = addType(key);
1198         }
1199         return result.index;
1200     }
1201 
1202     /**
1203      * Adds the given Item to {@link #typeTable}.
1204      *
1205      * @param item the value to be added to the type table.
1206      * @return the added Item, which a new Item instance with the same value as
1207      *         the given Item.
1208      */
addType(final Item item)1209     private Item addType(final Item item) {
1210         ++typeCount;
1211         Item result = new Item(typeCount, key);
1212         put(result);
1213         if (typeTable == null) {
1214             typeTable = new Item[16];
1215         }
1216         if (typeCount == typeTable.length) {
1217             Item[] newTable = new Item[2 * typeTable.length];
1218             System.arraycopy(typeTable, 0, newTable, 0, typeTable.length);
1219             typeTable = newTable;
1220         }
1221         typeTable[typeCount] = result;
1222         return result;
1223     }
1224 
1225     /**
1226      * Returns the index of the common super type of the two given types. This
1227      * method calls {@link #getCommonSuperClass} and caches the result in the
1228      * {@link #items} hash table to speedup future calls with the same
1229      * parameters.
1230      *
1231      * @param type1 index of an internal name in {@link #typeTable}.
1232      * @param type2 index of an internal name in {@link #typeTable}.
1233      * @return the index of the common super type of the two given types.
1234      */
getMergedType(final int type1, final int type2)1235     int getMergedType(final int type1, final int type2) {
1236         key2.type = TYPE_MERGED;
1237         key2.longVal = type1 | (((long) type2) << 32);
1238         key2.hashCode = 0x7FFFFFFF & (TYPE_MERGED + type1 + type2);
1239         Item result = get(key2);
1240         if (result == null) {
1241             String t = typeTable[type1].strVal1;
1242             String u = typeTable[type2].strVal1;
1243             key2.intVal = addType(getCommonSuperClass(t, u));
1244             result = new Item((short) 0, key2);
1245             put(result);
1246         }
1247         return result.intVal;
1248     }
1249 
1250     /**
1251      * Returns the common super type of the two given types. The default
1252      * implementation of this method <i>loads<i> the two given classes and uses
1253      * the java.lang.Class methods to find the common super class. It can be
1254      * overridden to compute this common super type in other ways, in particular
1255      * without actually loading any class, or to take into account the class
1256      * that is currently being generated by this ClassWriter, which can of
1257      * course not be loaded since it is under construction.
1258      *
1259      * @param type1 the internal name of a class.
1260      * @param type2 the internal name of another class.
1261      * @return the internal name of the common super class of the two given
1262      *         classes.
1263      */
getCommonSuperClass(final String type1, final String type2)1264     protected String getCommonSuperClass(final String type1, final String type2)
1265     {
1266         Class c, d;
1267         try {
1268             c = Class.forName(type1.replace('/', '.'));
1269             d = Class.forName(type2.replace('/', '.'));
1270         } catch (Exception e) {
1271             throw new RuntimeException(e.toString());
1272         }
1273         if (c.isAssignableFrom(d)) {
1274             return type1;
1275         }
1276         if (d.isAssignableFrom(c)) {
1277             return type2;
1278         }
1279         if (c.isInterface() || d.isInterface()) {
1280             return "java/lang/Object";
1281         } else {
1282             do {
1283                 c = c.getSuperclass();
1284             } while (!c.isAssignableFrom(d));
1285             return c.getName().replace('.', '/');
1286         }
1287     }
1288 
1289     /**
1290      * Returns the constant pool's hash table item which is equal to the given
1291      * item.
1292      *
1293      * @param key a constant pool item.
1294      * @return the constant pool's hash table item which is equal to the given
1295      *         item, or <tt>null</tt> if there is no such item.
1296      */
get(final Item key)1297     private Item get(final Item key) {
1298         Item i = items[key.hashCode % items.length];
1299         while (i != null && !key.isEqualTo(i)) {
1300             i = i.next;
1301         }
1302         return i;
1303     }
1304 
1305     /**
1306      * Puts the given item in the constant pool's hash table. The hash table
1307      * <i>must</i> not already contains this item.
1308      *
1309      * @param i the item to be added to the constant pool's hash table.
1310      */
put(final Item i)1311     private void put(final Item i) {
1312         if (index > threshold) {
1313             int ll = items.length;
1314             int nl = ll * 2 + 1;
1315             Item[] newItems = new Item[nl];
1316             for (int l = ll - 1; l >= 0; --l) {
1317                 Item j = items[l];
1318                 while (j != null) {
1319                     int index = j.hashCode % newItems.length;
1320                     Item k = j.next;
1321                     j.next = newItems[index];
1322                     newItems[index] = j;
1323                     j = k;
1324                 }
1325             }
1326             items = newItems;
1327             threshold = (int) (nl * 0.75);
1328         }
1329         int index = i.hashCode % items.length;
1330         i.next = items[index];
1331         items[index] = i;
1332     }
1333 
1334     /**
1335      * Puts one byte and two shorts into the constant pool.
1336      *
1337      * @param b a byte.
1338      * @param s1 a short.
1339      * @param s2 another short.
1340      */
put122(final int b, final int s1, final int s2)1341     private void put122(final int b, final int s1, final int s2) {
1342         pool.put12(b, s1).putShort(s2);
1343     }
1344 }
1345