2 * ASM: a very small and fast Java bytecode manipulation framework
3 * Copyright (c) 2000-2005 INRIA, France Telecom
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
30 package org.objectweb.asm;
32 import java.io.InputStream;
33 import java.io.IOException;
36 * A Java class parser to make a {@link ClassVisitor} visit an existing class.
37 * This class parses a byte array conforming to the Java class file format and
38 * calls the appropriate visit methods of a given class visitor for each field,
39 * method and bytecode instruction encountered.
41 * @author Eric Bruneton
42 * @author Eugene Kuleshov
44 public class ClassReader {
47 * The class to be parsed. <i>The content of this array must not be
48 * modified. This field is intended for {@link Attribute} sub classes, and
49 * is normally not needed by class generators or adapters.</i>
51 public final byte[] b;
54 * The start index of each constant pool item in {@link #b b}, plus one.
55 * The one byte offset skips the constant pool item tag that indicates its
61 * The String objects corresponding to the CONSTANT_Utf8 items. This cache
62 * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item,
63 * which GREATLY improves performances (by a factor 2 to 3). This caching
64 * strategy could be extended to all constant pool items, but its benefit
65 * would not be so great for these items (because they are much less
66 * expensive to parse than CONSTANT_Utf8 items).
68 private String[] strings;
71 * Maximum length of the strings contained in the constant pool of the
74 private int maxStringLength;
77 * Start index of the class header information (access, name...) in
80 public final int header;
82 // ------------------------------------------------------------------------
84 // ------------------------------------------------------------------------
87 * Constructs a new {@link ClassReader} object.
89 * @param b the bytecode of the class to be read.
91 public ClassReader(final byte[] b) {
96 * Constructs a new {@link ClassReader} object.
98 * @param b the bytecode of the class to be read.
99 * @param off the start offset of the class data.
100 * @param len the length of the class data.
102 public ClassReader(final byte[] b, final int off, final int len) {
104 // parses the constant pool
105 items = new int[readUnsignedShort(off + 8)];
106 int ll = items.length;
107 strings = new String[ll];
109 int index = off + 10;
110 for (int i = 1; i < ll; ++i) {
111 items[i] = index + 1;
115 case ClassWriter.FIELD:
116 case ClassWriter.METH:
117 case ClassWriter.IMETH:
118 case ClassWriter.INT:
119 case ClassWriter.FLOAT:
120 case ClassWriter.NAME_TYPE:
123 case ClassWriter.LONG:
124 case ClassWriter.DOUBLE:
128 case ClassWriter.UTF8:
129 size = 3 + readUnsignedShort(index + 1);
134 // case ClassWriter.CLASS:
135 // case ClassWriter.STR:
142 maxStringLength = max;
143 // the class header information starts just after the constant pool
148 * Copies the constant pool data into the given {@link ClassWriter}. Should
149 * be called before the {@link #accept(ClassVisitor,boolean)} method.
151 * @param classWriter the {@link ClassWriter} to copy constant pool into.
153 void copyPool(final ClassWriter classWriter) {
154 char[] buf = new char[maxStringLength];
155 int ll = items.length;
156 Item[] items2 = new Item[ll];
157 for (int i = 1; i < ll; i++) {
158 int index = items[i];
159 int tag = b[index - 1];
160 Item item = new Item(i);
163 case ClassWriter.FIELD:
164 case ClassWriter.METH:
165 case ClassWriter.IMETH:
166 nameType = items[readUnsignedShort(index + 2)];
168 readClass(index, buf),
169 readUTF8(nameType, buf),
170 readUTF8(nameType + 2, buf));
173 case ClassWriter.INT:
174 item.set(readInt(index));
177 case ClassWriter.FLOAT:
178 item.set(Float.intBitsToFloat(readInt(index)));
181 case ClassWriter.NAME_TYPE:
183 readUTF8(index, buf),
184 readUTF8(index + 2, buf),
188 case ClassWriter.LONG:
189 item.set(readLong(index));
193 case ClassWriter.DOUBLE:
194 item.set(Double.longBitsToDouble(readLong(index)));
198 case ClassWriter.UTF8: {
199 String s = strings[i];
202 s = strings[i] = readUTF(index + 2,
203 readUnsignedShort(index),
206 item.set(tag, s, null, null);
210 // case ClassWriter.STR:
211 // case ClassWriter.CLASS:
213 item.set(tag, readUTF8(index, buf), null, null);
217 int index2 = item.hashCode % items2.length;
218 item.next = items2[index2];
219 items2[index2] = item;
222 int off = items[1] - 1;
223 classWriter.pool.putByteArray(b, off, header - off);
224 classWriter.items = items2;
225 classWriter.threshold = (int) (0.75d * ll);
226 classWriter.index = ll;
230 * Constructs a new {@link ClassReader} object.
232 * @param is an input stream from which to read the class.
233 * @throws IOException if a problem occurs during reading.
235 public ClassReader(final InputStream is) throws IOException {
240 * Constructs a new {@link ClassReader} object.
242 * @param name the fully qualified name of the class to be read.
243 * @throws IOException if an exception occurs during reading.
245 public ClassReader(final String name) throws IOException {
246 this(ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
251 * Reads the bytecode of a class.
253 * @param is an input stream from which to read the class.
254 * @return the bytecode read from the given input stream.
255 * @throws IOException if a problem occurs during reading.
257 private static byte[] readClass(final InputStream is) throws IOException {
259 throw new IOException("Class not found");
261 byte[] b = new byte[is.available()];
264 int n = is.read(b, len, b.length - len);
266 if (len < b.length) {
267 byte[] c = new byte[len];
268 System.arraycopy(b, 0, c, 0, len);
274 if (len == b.length) {
275 byte[] c = new byte[b.length + 1000];
276 System.arraycopy(b, 0, c, 0, len);
282 // ------------------------------------------------------------------------
284 // ------------------------------------------------------------------------
287 * Makes the given visitor visit the Java class of this {@link ClassReader}.
288 * This class is the one specified in the constructor (see
289 * {@link #ClassReader(byte[]) ClassReader}).
291 * @param classVisitor the visitor that must visit this class.
292 * @param skipDebug <tt>true</tt> if the debug information of the class
293 * must not be visited. In this case the
294 * {@link MethodVisitor#visitLocalVariable visitLocalVariable} and
295 * {@link MethodVisitor#visitLineNumber visitLineNumber} methods will
298 public void accept(final ClassVisitor classVisitor, final boolean skipDebug)
300 accept(classVisitor, new Attribute[0], skipDebug);
304 * Makes the given visitor visit the Java class of this {@link ClassReader}.
305 * This class is the one specified in the constructor (see
306 * {@link #ClassReader(byte[]) ClassReader}).
308 * @param classVisitor the visitor that must visit this class.
309 * @param attrs prototypes of the attributes that must be parsed during the
310 * visit of the class. Any attribute whose type is not equal to the
311 * type of one the prototypes will be ignored.
312 * @param skipDebug <tt>true</tt> if the debug information of the class
313 * must not be visited. In this case the
314 * {@link MethodVisitor#visitLocalVariable visitLocalVariable} and
315 * {@link MethodVisitor#visitLineNumber visitLineNumber} methods will
319 final ClassVisitor classVisitor,
320 final Attribute[] attrs,
321 final boolean skipDebug)
323 byte[] b = this.b; // the bytecode array
324 char[] c = new char[maxStringLength]; // buffer used to read strings
325 int i, j, k; // loop variables
326 int u, v, w; // indexes in b
336 Attribute cattrs = null;
340 access = readUnsignedShort(u);
341 name = readClass(u + 2, c);
342 v = items[readUnsignedShort(u + 4)];
343 String superClassName = v == 0 ? null : readUTF8(v, c);
344 String[] implementedItfs = new String[readUnsignedShort(u + 6)];
347 for (i = 0; i < implementedItfs.length; ++i) {
348 implementedItfs[i] = readClass(u, c);
352 // skips fields and methods
354 i = readUnsignedShort(v);
357 j = readUnsignedShort(v + 6);
360 v += 6 + readInt(v + 2);
363 i = readUnsignedShort(v);
366 j = readUnsignedShort(v + 6);
369 v += 6 + readInt(v + 2);
372 // reads the class's attributes
374 String sourceFile = null;
375 String sourceDebug = null;
376 String enclosingOwner = null;
377 String enclosingName = null;
378 String enclosingDesc = null;
380 i = readUnsignedShort(v);
383 attrName = readUTF8(v, c);
384 if (attrName.equals("SourceFile")) {
385 sourceFile = readUTF8(v + 6, c);
386 } else if (attrName.equals("Deprecated")) {
387 access |= Opcodes.ACC_DEPRECATED;
388 } else if (attrName.equals("Synthetic")) {
389 access |= Opcodes.ACC_SYNTHETIC;
390 } else if (attrName.equals("Annotation")) {
391 access |= Opcodes.ACC_ANNOTATION;
392 } else if (attrName.equals("Enum")) {
393 access |= Opcodes.ACC_ENUM;
394 } else if (attrName.equals("InnerClasses")) {
396 } else if (attrName.equals("Signature")) {
397 signature = readUTF8(v + 6, c);
398 } else if (attrName.equals("SourceDebugExtension")) {
399 int len = readInt(v + 2);
400 sourceDebug = readUTF(v + 6, len, new char[len]);
401 } else if (attrName.equals("EnclosingMethod")) {
402 enclosingOwner = readClass(v + 6, c);
403 int item = readUnsignedShort(v + 8);
405 enclosingName = readUTF8(items[item], c);
406 enclosingDesc = readUTF8(items[item] + 2, c);
408 } else if (attrName.equals("RuntimeVisibleAnnotations")) {
410 } else if (attrName.equals("RuntimeInvisibleAnnotations")) {
413 attr = readAttribute(attrs,
425 v += 6 + readInt(v + 2);
427 // calls the visit method
428 classVisitor.visit(readInt(4),
435 // calls the visitSource method
436 if (sourceFile != null || sourceDebug != null) {
437 classVisitor.visitSource(sourceFile, sourceDebug);
440 // calls the visitOuterClass method
441 if (enclosingOwner != null) {
442 classVisitor.visitOuterClass(enclosingOwner,
447 // visits the class annotations
448 for (i = 1; i >= 0; --i) {
449 v = i == 0 ? ianns : anns;
451 j = readUnsignedShort(v);
454 desc = readUTF8(v, c);
456 v = readAnnotationValues(v,
458 classVisitor.visitAnnotation(desc, i != 0));
463 // visits the class attributes
464 while (cattrs != null) {
467 classVisitor.visitAttribute(cattrs);
471 // class the visitInnerClass method
473 i = readUnsignedShort(w);
476 classVisitor.visitInnerClass(readUnsignedShort(w) == 0
478 : readClass(w, c), readUnsignedShort(w + 2) == 0
480 : readClass(w + 2, c), readUnsignedShort(w + 4) == 0
482 : readUTF8(w + 4, c), readUnsignedShort(w + 6));
488 i = readUnsignedShort(u);
491 access = readUnsignedShort(u);
492 name = readUTF8(u + 2, c);
493 desc = readUTF8(u + 4, c);
494 // visits the field's attributes and looks for a ConstantValue
496 int fieldValueItem = 0;
502 j = readUnsignedShort(u + 6);
505 attrName = readUTF8(u, c);
506 if (attrName.equals("ConstantValue")) {
507 fieldValueItem = readUnsignedShort(u + 6);
508 } else if (attrName.equals("Synthetic")) {
509 access |= Opcodes.ACC_SYNTHETIC;
510 } else if (attrName.equals("Deprecated")) {
511 access |= Opcodes.ACC_DEPRECATED;
512 } else if (attrName.equals("Enum")) {
513 access |= Opcodes.ACC_ENUM;
514 } else if (attrName.equals("Signature")) {
515 signature = readUTF8(u + 6, c);
516 } else if (attrName.equals("RuntimeVisibleAnnotations")) {
518 } else if (attrName.equals("RuntimeInvisibleAnnotations")) {
521 attr = readAttribute(attrs,
533 u += 6 + readInt(u + 2);
535 // reads the field's value, if any
536 Object value = (fieldValueItem == 0
538 : readConst(fieldValueItem, c));
540 FieldVisitor fv = classVisitor.visitField(access,
545 // visits the field annotations and attributes
547 for (j = 1; j >= 0; --j) {
548 v = j == 0 ? ianns : anns;
550 k = readUnsignedShort(v);
553 desc = readUTF8(v, c);
555 v = readAnnotationValues(v,
557 fv.visitAnnotation(desc, j != 0));
561 while (cattrs != null) {
564 fv.visitAttribute(cattrs);
571 // visits the methods
572 i = readUnsignedShort(u);
576 access = readUnsignedShort(u);
577 name = readUTF8(u + 2, c);
578 desc = readUTF8(u + 4, c);
589 // looks for Code and Exceptions attributes
590 j = readUnsignedShort(u + 6);
593 attrName = readUTF8(u, c);
595 int attrSize = readInt(u);
597 if (attrName.equals("Code")) {
599 } else if (attrName.equals("Exceptions")) {
601 } else if (attrName.equals("Synthetic")) {
602 access |= Opcodes.ACC_SYNTHETIC;
603 } else if (attrName.equals("Varargs")) {
604 access |= Opcodes.ACC_VARARGS;
605 } else if (attrName.equals("Bridge")) {
606 access |= Opcodes.ACC_BRIDGE;
607 } else if (attrName.equals("Deprecated")) {
608 access |= Opcodes.ACC_DEPRECATED;
609 } else if (attrName.equals("Signature")) {
610 signature = readUTF8(u, c);
611 } else if (attrName.equals("AnnotationDefault")) {
613 } else if (attrName.equals("RuntimeVisibleAnnotations")) {
615 } else if (attrName.equals("RuntimeInvisibleAnnotations")) {
617 } else if (attrName.equals("RuntimeVisibleParameterAnnotations"))
620 } else if (attrName.equals("RuntimeInvisibleParameterAnnotations"))
624 attr = readAttribute(attrs,
638 // reads declared exceptions
643 exceptions = new String[readUnsignedShort(w)];
645 for (j = 0; j < exceptions.length; ++j) {
646 exceptions[j] = readClass(w, c);
651 // visits the method's code, if any
652 MethodVisitor mv = classVisitor.visitMethod(access,
660 * if the returned MethodVisitor is in fact a MethodWriter, it
661 * means there is no method adapter between the reader and the
662 * writer. If, in addition, the writer's constant pool was
663 * copied from this reader (mw.cw.cr == this), and the signature
664 * and exceptions of the method have not been changed, then it
665 * is possible to skip all visit events and just copy the
666 * original code of the method to the writer (the access, name
667 * and descriptor can have been changed, this is not important
668 * since they are not copied as is from the reader).
670 if (mv instanceof MethodWriter) {
671 MethodWriter mw = (MethodWriter) mv;
672 if (mw.cw.cr == this) {
673 if (signature == mw.signature) {
674 boolean sameExceptions = false;
675 if (exceptions == null) {
676 sameExceptions = mw.exceptionCount == 0;
678 if (exceptions.length == mw.exceptionCount) {
679 sameExceptions = true;
680 for (j = exceptions.length - 1; j >= 0; --j)
683 if (mw.exceptions[j] != readUnsignedShort(w))
685 sameExceptions = false;
691 if (sameExceptions) {
693 * we do not copy directly the code into
694 * MethodWriter to save a byte array copy
695 * operation. The real copy will be done in
696 * ClassWriter.toByteArray().
698 mw.classReaderOffset = u0;
699 mw.classReaderLength = u - u0;
706 AnnotationVisitor dv = mv.visitAnnotationDefault();
707 readAnnotationValue(dann, c, null, dv);
710 for (j = 1; j >= 0; --j) {
711 w = j == 0 ? ianns : anns;
713 k = readUnsignedShort(w);
716 desc = readUTF8(w, c);
718 w = readAnnotationValues(w,
720 mv.visitAnnotation(desc, j != 0));
725 readParameterAnnotations(mpanns, c, true, mv);
728 readParameterAnnotations(impanns, c, false, mv);
730 while (cattrs != null) {
733 mv.visitAttribute(cattrs);
738 if (mv != null && v != 0) {
739 int maxStack = readUnsignedShort(v);
740 int maxLocals = readUnsignedShort(v + 2);
741 int codeLength = readInt(v + 4);
745 int codeEnd = v + codeLength;
749 // 1st phase: finds the labels
751 Label[] labels = new Label[codeLength + 1];
752 while (v < codeEnd) {
753 int opcode = b[v] & 0xFF;
754 switch (ClassWriter.TYPE[opcode]) {
755 case ClassWriter.NOARG_INSN:
756 case ClassWriter.IMPLVAR_INSN:
759 case ClassWriter.LABEL_INSN:
760 label = v - codeStart + readShort(v + 1);
761 if (labels[label] == null) {
762 labels[label] = new Label();
766 case ClassWriter.LABELW_INSN:
767 label = v - codeStart + readInt(v + 1);
768 if (labels[label] == null) {
769 labels[label] = new Label();
773 case ClassWriter.WIDE_INSN:
774 opcode = b[v + 1] & 0xFF;
775 if (opcode == Opcodes.IINC) {
781 case ClassWriter.TABL_INSN:
782 // skips 0 to 3 padding bytes
786 label = w + readInt(v);
788 if (labels[label] == null) {
789 labels[label] = new Label();
793 j = readInt(v) - j + 1;
796 label = w + readInt(v);
798 if (labels[label] == null) {
799 labels[label] = new Label();
803 case ClassWriter.LOOK_INSN:
804 // skips 0 to 3 padding bytes
808 label = w + readInt(v);
810 if (labels[label] == null) {
811 labels[label] = new Label();
817 label = w + readInt(v);
819 if (labels[label] == null) {
820 labels[label] = new Label();
824 case ClassWriter.VAR_INSN:
825 case ClassWriter.SBYTE_INSN:
826 case ClassWriter.LDC_INSN:
829 case ClassWriter.SHORT_INSN:
830 case ClassWriter.LDCW_INSN:
831 case ClassWriter.FIELDORMETH_INSN:
832 case ClassWriter.TYPE_INSN:
833 case ClassWriter.IINC_INSN:
836 case ClassWriter.ITFMETH_INSN:
845 // parses the try catch entries
846 j = readUnsignedShort(v);
849 label = readUnsignedShort(v);
850 Label start = labels[label];
852 labels[label] = start = new Label();
854 label = readUnsignedShort(v + 2);
855 Label end = labels[label];
857 labels[label] = end = new Label();
859 label = readUnsignedShort(v + 4);
860 Label handler = labels[label];
861 if (handler == null) {
862 labels[label] = handler = new Label();
865 int type = readUnsignedShort(v + 6);
867 mv.visitTryCatchBlock(start, end, handler, null);
869 mv.visitTryCatchBlock(start,
872 readUTF8(items[type], c));
876 // parses the local variable, line number tables, and code
879 int varTypeTable = 0;
881 j = readUnsignedShort(v);
884 attrName = readUTF8(v, c);
885 if (attrName.equals("LocalVariableTable")) {
888 k = readUnsignedShort(v + 6);
891 label = readUnsignedShort(w);
892 if (labels[label] == null) {
893 labels[label] = new Label();
895 label += readUnsignedShort(w + 2);
896 if (labels[label] == null) {
897 labels[label] = new Label();
902 } else if (attrName.equals("LocalVariableTypeTable")) {
903 varTypeTable = v + 6;
904 } else if (attrName.equals("LineNumberTable")) {
906 k = readUnsignedShort(v + 6);
909 label = readUnsignedShort(w);
910 if (labels[label] == null) {
911 labels[label] = new Label();
913 labels[label].line = readUnsignedShort(w + 2);
918 for (k = 0; k < attrs.length; ++k) {
919 if (attrs[k].type.equals(attrName)) {
920 attr = attrs[k].read(this,
933 v += 6 + readInt(v + 2);
936 // 2nd phase: visits each instruction
939 while (v < codeEnd) {
944 if (!skipDebug && l.line > 0) {
945 mv.visitLineNumber(l.line, l);
948 int opcode = b[v] & 0xFF;
949 switch (ClassWriter.TYPE[opcode]) {
950 case ClassWriter.NOARG_INSN:
951 mv.visitInsn(opcode);
954 case ClassWriter.IMPLVAR_INSN:
955 if (opcode > Opcodes.ISTORE) {
956 opcode -= 59; // ISTORE_0
957 mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
960 opcode -= 26; // ILOAD_0
961 mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2),
966 case ClassWriter.LABEL_INSN:
967 mv.visitJumpInsn(opcode, labels[w
968 + readShort(v + 1)]);
971 case ClassWriter.LABELW_INSN:
972 mv.visitJumpInsn(opcode - 33, labels[w
976 case ClassWriter.WIDE_INSN:
977 opcode = b[v + 1] & 0xFF;
978 if (opcode == Opcodes.IINC) {
979 mv.visitIincInsn(readUnsignedShort(v + 2),
983 mv.visitVarInsn(opcode,
984 readUnsignedShort(v + 2));
988 case ClassWriter.TABL_INSN:
989 // skips 0 to 3 padding bytes
992 label = w + readInt(v);
994 int min = readInt(v);
996 int max = readInt(v);
998 Label[] table = new Label[max - min + 1];
999 for (j = 0; j < table.length; ++j) {
1000 table[j] = labels[w + readInt(v)];
1003 mv.visitTableSwitchInsn(min,
1008 case ClassWriter.LOOK_INSN:
1009 // skips 0 to 3 padding bytes
1010 v = v + 4 - (w & 3);
1011 // reads instruction
1012 label = w + readInt(v);
1016 int[] keys = new int[j];
1017 Label[] values = new Label[j];
1018 for (j = 0; j < keys.length; ++j) {
1019 keys[j] = readInt(v);
1021 values[j] = labels[w + readInt(v)];
1024 mv.visitLookupSwitchInsn(labels[label],
1028 case ClassWriter.VAR_INSN:
1029 mv.visitVarInsn(opcode, b[v + 1] & 0xFF);
1032 case ClassWriter.SBYTE_INSN:
1033 mv.visitIntInsn(opcode, b[v + 1]);
1036 case ClassWriter.SHORT_INSN:
1037 mv.visitIntInsn(opcode, readShort(v + 1));
1040 case ClassWriter.LDC_INSN:
1041 mv.visitLdcInsn(readConst(b[v + 1] & 0xFF, c));
1044 case ClassWriter.LDCW_INSN:
1045 mv.visitLdcInsn(readConst(readUnsignedShort(v + 1),
1049 case ClassWriter.FIELDORMETH_INSN:
1050 case ClassWriter.ITFMETH_INSN:
1051 int cpIndex = items[readUnsignedShort(v + 1)];
1052 String iowner = readClass(cpIndex, c);
1053 cpIndex = items[readUnsignedShort(cpIndex + 2)];
1054 String iname = readUTF8(cpIndex, c);
1055 String idesc = readUTF8(cpIndex + 2, c);
1056 if (opcode < Opcodes.INVOKEVIRTUAL) {
1057 mv.visitFieldInsn(opcode, iowner, iname, idesc);
1059 mv.visitMethodInsn(opcode, iowner, iname, idesc);
1061 if (opcode == Opcodes.INVOKEINTERFACE) {
1067 case ClassWriter.TYPE_INSN:
1068 mv.visitTypeInsn(opcode, readClass(v + 1, c));
1071 case ClassWriter.IINC_INSN:
1072 mv.visitIincInsn(b[v + 1] & 0xFF, b[v + 2]);
1077 mv.visitMultiANewArrayInsn(readClass(v + 1, c),
1083 l = labels[codeEnd - codeStart];
1088 // visits the local variable tables
1089 if (!skipDebug && varTable != 0) {
1090 int[] typeTable = null;
1091 if (varTypeTable != 0) {
1093 k = readUnsignedShort(w) * 3;
1095 typeTable = new int[k];
1097 typeTable[--k] = w + 6; // signature
1098 typeTable[--k] = readUnsignedShort(w + 8); // index
1099 typeTable[--k] = readUnsignedShort(w); // start
1104 k = readUnsignedShort(w);
1106 for (; k > 0; --k) {
1107 int start = readUnsignedShort(w);
1108 int length = readUnsignedShort(w + 2);
1109 int index = readUnsignedShort(w + 8);
1110 String vsignature = null;
1111 if (typeTable != null) {
1112 for (int a = 0; a < typeTable.length; a += 3) {
1113 if (typeTable[a] == start
1114 && typeTable[a + 1] == index)
1116 vsignature = readUTF8(typeTable[a + 2], c);
1121 mv.visitLocalVariable(readUTF8(w + 4, c),
1125 labels[start + length],
1130 // visits the other attributes
1131 while (cattrs != null) {
1134 mv.visitAttribute(cattrs);
1137 // visits the max stack and max locals values
1138 mv.visitMaxs(maxStack, maxLocals);
1146 // visits the end of the class
1147 classVisitor.visitEnd();
1151 * Reads parameter annotations and makes the given visitor visit them.
1153 * @param v start offset in {@link #b b} of the annotations to be read.
1154 * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
1155 * {@link #readClass(int,char[]) readClass} or
1156 * {@link #readConst readConst}.
1157 * @param visible <tt>true</tt> if the annotations to be read are visible
1159 * @param mv the visitor that must visit the annotations.
1161 private void readParameterAnnotations(
1164 final boolean visible,
1165 final MethodVisitor mv)
1167 int n = b[v++] & 0xFF;
1168 for (int i = 0; i < n; ++i) {
1169 int j = readUnsignedShort(v);
1171 for (; j > 0; --j) {
1172 String desc = readUTF8(v, buf);
1174 AnnotationVisitor av = mv.visitParameterAnnotation(i,
1177 v = readAnnotationValues(v, buf, av);
1183 * Reads the values of an annotation and makes the given visitor visit them.
1185 * @param v the start offset in {@link #b b} of the values to be read
1186 * (including the unsigned short that gives the number of values).
1187 * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
1188 * {@link #readClass(int,char[]) readClass} or
1189 * {@link #readConst readConst}.
1190 * @param av the visitor that must visit the values.
1191 * @return the end offset of the annotations values.
1193 private int readAnnotationValues(
1196 final AnnotationVisitor av)
1198 int i = readUnsignedShort(v);
1200 for (; i > 0; --i) {
1201 String name = readUTF8(v, buf);
1203 v = readAnnotationValue(v, buf, name, av);
1210 * Reads a value of an annotation and makes the given visitor visit it.
1212 * @param v the start offset in {@link #b b} of the value to be read (<i>not
1213 * including the value name constant pool index</i>).
1214 * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
1215 * {@link #readClass(int,char[]) readClass} or
1216 * {@link #readConst readConst}.
1217 * @param name the name of the value to be read.
1218 * @param av the visitor that must visit the value.
1219 * @return the end offset of the annotation value.
1221 private int readAnnotationValue(
1225 final AnnotationVisitor av)
1228 switch (readByte(v++)) {
1229 case 'I': // pointer to CONSTANT_Integer
1230 case 'J': // pointer to CONSTANT_Long
1231 case 'F': // pointer to CONSTANT_Float
1232 case 'D': // pointer to CONSTANT_Double
1233 av.visit(name, readConst(readUnsignedShort(v), buf));
1236 case 'B': // pointer to CONSTANT_Byte
1238 new Byte((byte) readInt(items[readUnsignedShort(v)])));
1241 case 'Z': // pointer to CONSTANT_Boolean
1242 boolean b = readInt(items[readUnsignedShort(v)]) == 0;
1243 av.visit(name, b ? Boolean.FALSE : Boolean.TRUE);
1246 case 'S': // pointer to CONSTANT_Short
1248 new Short((short) readInt(items[readUnsignedShort(v)])));
1251 case 'C': // pointer to CONSTANT_Char
1253 new Character((char) readInt(items[readUnsignedShort(v)])));
1256 case 's': // pointer to CONSTANT_Utf8
1257 av.visit(name, readUTF8(v, buf));
1260 case 'e': // enum_const_value
1261 av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
1264 case 'c': // class_info
1265 av.visit(name, Type.getType(readUTF8(v, buf)));
1268 case '@': // annotation_value
1269 String desc = readUTF8(v, buf);
1271 v = readAnnotationValues(v, buf, av.visitAnnotation(name, desc));
1273 case '[': // array_value
1274 int size = readUnsignedShort(v);
1277 av.visitArray(name).visitEnd();
1280 switch (readByte(v++)) {
1282 byte[] bv = new byte[size];
1283 for (i = 0; i < size; i++) {
1284 bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
1291 boolean[] zv = new boolean[size];
1292 for (i = 0; i < size; i++) {
1293 zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
1300 short[] sv = new short[size];
1301 for (i = 0; i < size; i++) {
1302 sv[i] = (short) readInt(items[readUnsignedShort(v)]);
1309 char[] cv = new char[size];
1310 for (i = 0; i < size; i++) {
1311 cv[i] = (char) readInt(items[readUnsignedShort(v)]);
1318 int[] iv = new int[size];
1319 for (i = 0; i < size; i++) {
1320 iv[i] = readInt(items[readUnsignedShort(v)]);
1327 long[] lv = new long[size];
1328 for (i = 0; i < size; i++) {
1329 lv[i] = readLong(items[readUnsignedShort(v)]);
1336 float[] fv = new float[size];
1337 for (i = 0; i < size; i++) {
1338 fv[i] = Float.intBitsToFloat(readInt(items[readUnsignedShort(v)]));
1345 double[] dv = new double[size];
1346 for (i = 0; i < size; i++) {
1347 dv[i] = Double.longBitsToDouble(readLong(items[readUnsignedShort(v)]));
1355 AnnotationVisitor aav = av.visitArray(name);
1356 for (i = size; i > 0; --i) {
1357 v = readAnnotationValue(v, buf, null, aav);
1366 * Reads an attribute in {@link #b b}.
1368 * @param attrs prototypes of the attributes that must be parsed during the
1369 * visit of the class. Any attribute whose type is not equal to the
1370 * type of one the prototypes is ignored (i.e. an empty
1371 * {@link Attribute} instance is returned).
1372 * @param type the type of the attribute.
1373 * @param off index of the first byte of the attribute's content in
1374 * {@link #b b}. The 6 attribute header bytes, containing the type
1375 * and the length of the attribute, are not taken into account here
1376 * (they have already been read).
1377 * @param len the length of the attribute's content.
1378 * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
1379 * {@link #readClass(int,char[]) readClass} or
1380 * {@link #readConst readConst}.
1381 * @param codeOff index of the first byte of code's attribute content in
1382 * {@link #b b}, or -1 if the attribute to be read is not a code
1383 * attribute. The 6 attribute header bytes, containing the type and
1384 * the length of the attribute, are not taken into account here.
1385 * @param labels the labels of the method's code, or <tt>null</tt> if the
1386 * attribute to be read is not a code attribute.
1387 * @return the attribute that has been read, or <tt>null</tt> to skip this
1390 private Attribute readAttribute(
1391 final Attribute[] attrs,
1397 final Label[] labels)
1399 for (int i = 0; i < attrs.length; ++i) {
1400 if (attrs[i].type.equals(type)) {
1401 return attrs[i].read(this, off, len, buf, codeOff, labels);
1404 return new Attribute(type).read(this, off, len, null, -1, null);
1407 // ------------------------------------------------------------------------
1408 // Utility methods: low level parsing
1409 // ------------------------------------------------------------------------
1412 * Returns the start index of the constant pool item in {@link #b b}, plus
1413 * one. <i>This method is intended for {@link Attribute} sub classes, and is
1414 * normally not needed by class generators or adapters.</i>
1416 * @param item the index a constant pool item.
1417 * @return the start index of the constant pool item in {@link #b b}, plus
1420 public int getItem(final int item) {
1425 * Reads a byte value in {@link #b b}. <i>This method is intended for
1426 * {@link Attribute} sub classes, and is normally not needed by class
1427 * generators or adapters.</i>
1429 * @param index the start index of the value to be read in {@link #b b}.
1430 * @return the read value.
1432 public int readByte(final int index) {
1433 return b[index] & 0xFF;
1437 * Reads an unsigned short value in {@link #b b}. <i>This method is
1438 * intended for {@link Attribute} sub classes, and is normally not needed by
1439 * class generators or adapters.</i>
1441 * @param index the start index of the value to be read in {@link #b b}.
1442 * @return the read value.
1444 public int readUnsignedShort(final int index) {
1446 return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
1450 * Reads a signed short value in {@link #b b}. <i>This method is intended
1451 * for {@link Attribute} sub classes, and is normally not needed by class
1452 * generators or adapters.</i>
1454 * @param index the start index of the value to be read in {@link #b b}.
1455 * @return the read value.
1457 public short readShort(final int index) {
1459 return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
1463 * Reads a signed int value in {@link #b b}. <i>This method is intended for
1464 * {@link Attribute} sub classes, and is normally not needed by class
1465 * generators or adapters.</i>
1467 * @param index the start index of the value to be read in {@link #b b}.
1468 * @return the read value.
1470 public int readInt(final int index) {
1472 return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
1473 | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
1477 * Reads a signed long value in {@link #b b}. <i>This method is intended
1478 * for {@link Attribute} sub classes, and is normally not needed by class
1479 * generators or adapters.</i>
1481 * @param index the start index of the value to be read in {@link #b b}.
1482 * @return the read value.
1484 public long readLong(final int index) {
1485 long l1 = readInt(index);
1486 long l0 = readInt(index + 4) & 0xFFFFFFFFL;
1487 return (l1 << 32) | l0;
1491 * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method
1492 * is intended for {@link Attribute} sub classes, and is normally not needed
1493 * by class generators or adapters.</i>
1495 * @param index the start index of an unsigned short value in {@link #b b},
1496 * whose value is the index of an UTF8 constant pool item.
1497 * @param buf buffer to be used to read the item. This buffer must be
1498 * sufficiently large. It is not automatically resized.
1499 * @return the String corresponding to the specified UTF8 item.
1501 public String readUTF8(int index, final char[] buf) {
1502 int item = readUnsignedShort(index);
1503 String s = strings[item];
1507 index = items[item];
1508 return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf);
1512 * Reads UTF8 string in {@link #b b}.
1514 * @param index start offset of the UTF8 string to be read.
1515 * @param utfLen length of the UTF8 string to be read.
1516 * @param buf buffer to be used to read the string. This buffer must be
1517 * sufficiently large. It is not automatically resized.
1518 * @return the String corresponding to the specified UTF8 string.
1520 private String readUTF(int index, int utfLen, char[] buf) {
1521 int endIndex = index + utfLen;
1525 while (index < endIndex) {
1526 c = b[index++] & 0xFF;
1537 buf[strLen++] = (char) c;
1541 // 110x xxxx 10xx xxxx
1543 buf[strLen++] = (char) (((c & 0x1F) << 6) | (d & 0x3F));
1546 // 1110 xxxx 10xx xxxx 10xx xxxx
1549 buf[strLen++] = (char) (((c & 0x0F) << 12)
1550 | ((d & 0x3F) << 6) | (e & 0x3F));
1554 return new String(buf, 0, strLen);
1558 * Reads a class constant pool item in {@link #b b}. <i>This method is
1559 * intended for {@link Attribute} sub classes, and is normally not needed by
1560 * class generators or adapters.</i>
1562 * @param index the start index of an unsigned short value in {@link #b b},
1563 * whose value is the index of a class constant pool item.
1564 * @param buf buffer to be used to read the item. This buffer must be
1565 * sufficiently large. It is not automatically resized.
1566 * @return the String corresponding to the specified class item.
1568 public String readClass(final int index, final char[] buf) {
1569 // computes the start index of the CONSTANT_Class item in b
1570 // and reads the CONSTANT_Utf8 item designated by
1571 // the first two bytes of this CONSTANT_Class item
1572 return readUTF8(items[readUnsignedShort(index)], buf);
1576 * Reads a numeric or string constant pool item in {@link #b b}. <i>This
1577 * method is intended for {@link Attribute} sub classes, and is normally not
1578 * needed by class generators or adapters.</i>
1580 * @param item the index of a constant pool item.
1581 * @param buf buffer to be used to read the item. This buffer must be
1582 * sufficiently large. It is not automatically resized.
1583 * @return the {@link Integer}, {@link Float}, {@link Long},
1584 * {@link Double}, {@link String} or {@link Type} corresponding to
1585 * the given constant pool item.
1587 public Object readConst(final int item, final char[] buf) {
1588 int index = items[item];
1589 switch (b[index - 1]) {
1590 case ClassWriter.INT:
1591 return new Integer(readInt(index));
1592 case ClassWriter.FLOAT:
1593 return new Float(Float.intBitsToFloat(readInt(index)));
1594 case ClassWriter.LONG:
1595 return new Long(readLong(index));
1596 case ClassWriter.DOUBLE:
1597 return new Double(Double.longBitsToDouble(readLong(index)));
1598 case ClassWriter.CLASS:
1599 String s = readUTF8(index, buf);
1600 return Type.getType(s.charAt(0) == '[' ? s : "L" + s + ";");
1601 // case ClassWriter.STR:
1603 return readUTF8(index, buf);