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