1 30 package com.sleepycat.asm; 31 32 import java.io.InputStream ; 33 import java.io.IOException ; 34 35 44 public class ClassReader { 45 46 51 public final byte[] b; 52 53 58 private int[] items; 59 60 68 private String [] strings; 69 70 74 private int maxStringLength; 75 76 80 public final int header; 81 82 86 91 public ClassReader(final byte[] b) { 92 this(b, 0, b.length); 93 } 94 95 102 public ClassReader(final byte[] b, final int off, final int len) { 103 this.b = b; 104 items = new int[readUnsignedShort(off + 8)]; 106 int ll = items.length; 107 strings = new String [ll]; 108 int max = 0; 109 int index = off + 10; 110 for (int i = 1; i < ll; ++i) { 111 items[i] = index + 1; 112 int tag = b[index]; 113 int size; 114 switch (tag) { 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: 121 size = 5; 122 break; 123 case ClassWriter.LONG: 124 case ClassWriter.DOUBLE: 125 size = 9; 126 ++i; 127 break; 128 case ClassWriter.UTF8: 129 size = 3 + readUnsignedShort(index + 1); 130 if (size > max) { 131 max = size; 132 } 133 break; 134 default: 137 size = 3; 138 break; 139 } 140 index += size; 141 } 142 maxStringLength = max; 143 header = index; 145 } 146 147 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); 161 int nameType; 162 switch (tag) { 163 case ClassWriter.FIELD: 164 case ClassWriter.METH: 165 case ClassWriter.IMETH: 166 nameType = items[readUnsignedShort(index + 2)]; 167 item.set(tag, 168 readClass(index, buf), 169 readUTF8(nameType, buf), 170 readUTF8(nameType + 2, buf)); 171 break; 172 173 case ClassWriter.INT: 174 item.set(readInt(index)); 175 break; 176 177 case ClassWriter.FLOAT: 178 item.set(Float.intBitsToFloat(readInt(index))); 179 break; 180 181 case ClassWriter.NAME_TYPE: 182 item.set(tag, 183 readUTF8(index, buf), 184 readUTF8(index + 2, buf), 185 null); 186 break; 187 188 case ClassWriter.LONG: 189 item.set(readLong(index)); 190 ++i; 191 break; 192 193 case ClassWriter.DOUBLE: 194 item.set(Double.longBitsToDouble(readLong(index))); 195 ++i; 196 break; 197 198 case ClassWriter.UTF8: { 199 String s = strings[i]; 200 if (s == null) { 201 index = items[i]; 202 s = strings[i] = readUTF(index + 2, 203 readUnsignedShort(index), 204 buf); 205 } 206 item.set(tag, s, null, null); 207 } 208 break; 209 210 default: 213 item.set(tag, readUTF8(index, buf), null, null); 214 break; 215 } 216 217 int index2 = item.hashCode % items2.length; 218 item.next = items2[index2]; 219 items2[index2] = item; 220 } 221 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; 227 } 228 229 235 public ClassReader(final InputStream is) throws IOException { 236 this(readClass(is)); 237 } 238 239 245 public ClassReader(final String name) throws IOException { 246 this(ClassLoader.getSystemResourceAsStream(name.replace('.', '/') 247 + ".class")); 248 } 249 250 257 private static byte[] readClass(final InputStream is) throws IOException { 258 if (is == null) { 259 throw new IOException ("Class not found"); 260 } 261 byte[] b = new byte[is.available()]; 262 int len = 0; 263 while (true) { 264 int n = is.read(b, len, b.length - len); 265 if (n == -1) { 266 if (len < b.length) { 267 byte[] c = new byte[len]; 268 System.arraycopy(b, 0, c, 0, len); 269 b = c; 270 } 271 return b; 272 } 273 len += n; 274 if (len == b.length) { 275 byte[] c = new byte[b.length + 1000]; 276 System.arraycopy(b, 0, c, 0, len); 277 b = c; 278 } 279 } 280 } 281 282 286 298 public void accept(final ClassVisitor classVisitor, final boolean skipDebug) 299 { 300 accept(classVisitor, new Attribute[0], skipDebug); 301 } 302 303 318 public void accept( 319 final ClassVisitor classVisitor, 320 final Attribute[] attrs, 321 final boolean skipDebug) 322 { 323 byte[] b = this.b; char[] c = new char[maxStringLength]; int i, j, k; int u, v, w; Attribute attr; 328 329 int access; 330 String name; 331 String desc; 332 String attrName; 333 String signature; 334 int anns = 0; 335 int ianns = 0; 336 Attribute cattrs = null; 337 338 u = header; 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)]; 345 w = 0; 346 u += 8; 347 for (i = 0; i < implementedItfs.length; ++i) { 348 implementedItfs[i] = readClass(u, c); 349 u += 2; 350 } 351 352 v = u; 354 i = readUnsignedShort(v); 355 v += 2; 356 for (; i > 0; --i) { 357 j = readUnsignedShort(v + 6); 358 v += 8; 359 for (; j > 0; --j) { 360 v += 6 + readInt(v + 2); 361 } 362 } 363 i = readUnsignedShort(v); 364 v += 2; 365 for (; i > 0; --i) { 366 j = readUnsignedShort(v + 6); 367 v += 8; 368 for (; j > 0; --j) { 369 v += 6 + readInt(v + 2); 370 } 371 } 372 signature = null; 374 String sourceFile = null; 375 String sourceDebug = null; 376 String enclosingOwner = null; 377 String enclosingName = null; 378 String enclosingDesc = null; 379 380 i = readUnsignedShort(v); 381 v += 2; 382 for (; i > 0; --i) { 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")) { 395 w = v + 6; 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); 404 if (item != 0) { 405 enclosingName = readUTF8(items[item], c); 406 enclosingDesc = readUTF8(items[item] + 2, c); 407 } 408 } else if (attrName.equals("RuntimeVisibleAnnotations")) { 409 anns = v + 6; 410 } else if (attrName.equals("RuntimeInvisibleAnnotations")) { 411 ianns = v + 6; 412 } else { 413 attr = readAttribute(attrs, 414 attrName, 415 v + 6, 416 readInt(v + 2), 417 c, 418 -1, 419 null); 420 if (attr != null) { 421 attr.next = cattrs; 422 cattrs = attr; 423 } 424 } 425 v += 6 + readInt(v + 2); 426 } 427 classVisitor.visit(readInt(4), 429 access, 430 name, 431 signature, 432 superClassName, 433 implementedItfs); 434 435 if (sourceFile != null || sourceDebug != null) { 437 classVisitor.visitSource(sourceFile, sourceDebug); 438 } 439 440 if (enclosingOwner != null) { 442 classVisitor.visitOuterClass(enclosingOwner, 443 enclosingName, 444 enclosingDesc); 445 } 446 447 for (i = 1; i >= 0; --i) { 449 v = i == 0 ? ianns : anns; 450 if (v != 0) { 451 j = readUnsignedShort(v); 452 v += 2; 453 for (; j > 0; --j) { 454 desc = readUTF8(v, c); 455 v += 2; 456 v = readAnnotationValues(v, 457 c, 458 classVisitor.visitAnnotation(desc, i != 0)); 459 } 460 } 461 } 462 463 while (cattrs != null) { 465 attr = cattrs.next; 466 cattrs.next = null; 467 classVisitor.visitAttribute(cattrs); 468 cattrs = attr; 469 } 470 471 if (w != 0) { 473 i = readUnsignedShort(w); 474 w += 2; 475 for (; i > 0; --i) { 476 classVisitor.visitInnerClass(readUnsignedShort(w) == 0 477 ? null 478 : readClass(w, c), readUnsignedShort(w + 2) == 0 479 ? null 480 : readClass(w + 2, c), readUnsignedShort(w + 4) == 0 481 ? null 482 : readUTF8(w + 4, c), readUnsignedShort(w + 6)); 483 w += 8; 484 } 485 } 486 487 i = readUnsignedShort(u); 489 u += 2; 490 for (; i > 0; --i) { 491 access = readUnsignedShort(u); 492 name = readUTF8(u + 2, c); 493 desc = readUTF8(u + 4, c); 494 int fieldValueItem = 0; 497 signature = null; 498 anns = 0; 499 ianns = 0; 500 cattrs = null; 501 502 j = readUnsignedShort(u + 6); 503 u += 8; 504 for (; j > 0; --j) { 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")) { 517 anns = u + 6; 518 } else if (attrName.equals("RuntimeInvisibleAnnotations")) { 519 ianns = u + 6; 520 } else { 521 attr = readAttribute(attrs, 522 attrName, 523 u + 6, 524 readInt(u + 2), 525 c, 526 -1, 527 null); 528 if (attr != null) { 529 attr.next = cattrs; 530 cattrs = attr; 531 } 532 } 533 u += 6 + readInt(u + 2); 534 } 535 Object value = (fieldValueItem == 0 537 ? null 538 : readConst(fieldValueItem, c)); 539 FieldVisitor fv = classVisitor.visitField(access, 541 name, 542 desc, 543 signature, 544 value); 545 if (fv != null) { 547 for (j = 1; j >= 0; --j) { 548 v = j == 0 ? ianns : anns; 549 if (v != 0) { 550 k = readUnsignedShort(v); 551 v += 2; 552 for (; k > 0; --k) { 553 desc = readUTF8(v, c); 554 v += 2; 555 v = readAnnotationValues(v, 556 c, 557 fv.visitAnnotation(desc, j != 0)); 558 } 559 } 560 } 561 while (cattrs != null) { 562 attr = cattrs.next; 563 cattrs.next = null; 564 fv.visitAttribute(cattrs); 565 cattrs = attr; 566 } 567 fv.visitEnd(); 568 } 569 } 570 571 i = readUnsignedShort(u); 573 u += 2; 574 for (; i > 0; --i) { 575 int u0 = u + 6; 576 access = readUnsignedShort(u); 577 name = readUTF8(u + 2, c); 578 desc = readUTF8(u + 4, c); 579 signature = null; 580 anns = 0; 581 ianns = 0; 582 int dann = 0; 583 int mpanns = 0; 584 int impanns = 0; 585 cattrs = null; 586 v = 0; 587 w = 0; 588 589 j = readUnsignedShort(u + 6); 591 u += 8; 592 for (; j > 0; --j) { 593 attrName = readUTF8(u, c); 594 u += 2; 595 int attrSize = readInt(u); 596 u += 4; 597 if (attrName.equals("Code")) { 598 v = u; 599 } else if (attrName.equals("Exceptions")) { 600 w = u; 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")) { 612 dann = u; 613 } else if (attrName.equals("RuntimeVisibleAnnotations")) { 614 anns = u; 615 } else if (attrName.equals("RuntimeInvisibleAnnotations")) { 616 ianns = u; 617 } else if (attrName.equals("RuntimeVisibleParameterAnnotations")) 618 { 619 mpanns = u; 620 } else if (attrName.equals("RuntimeInvisibleParameterAnnotations")) 621 { 622 impanns = u; 623 } else { 624 attr = readAttribute(attrs, 625 attrName, 626 u, 627 attrSize, 628 c, 629 -1, 630 null); 631 if (attr != null) { 632 attr.next = cattrs; 633 cattrs = attr; 634 } 635 } 636 u += attrSize; 637 } 638 String [] exceptions; 640 if (w == 0) { 641 exceptions = null; 642 } else { 643 exceptions = new String [readUnsignedShort(w)]; 644 w += 2; 645 for (j = 0; j < exceptions.length; ++j) { 646 exceptions[j] = readClass(w, c); 647 w += 2; 648 } 649 } 650 651 MethodVisitor mv = classVisitor.visitMethod(access, 653 name, 654 desc, 655 signature, 656 exceptions); 657 658 if (mv != null) { 659 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; 677 } else { 678 if (exceptions.length == mw.exceptionCount) { 679 sameExceptions = true; 680 for (j = exceptions.length - 1; j >= 0; --j) 681 { 682 w -= 2; 683 if (mw.exceptions[j] != readUnsignedShort(w)) 684 { 685 sameExceptions = false; 686 break; 687 } 688 } 689 } 690 } 691 if (sameExceptions) { 692 698 mw.classReaderOffset = u0; 699 mw.classReaderLength = u - u0; 700 continue; 701 } 702 } 703 } 704 } 705 if (dann != 0) { 706 AnnotationVisitor dv = mv.visitAnnotationDefault(); 707 readAnnotationValue(dann, c, null, dv); 708 dv.visitEnd(); 709 } 710 for (j = 1; j >= 0; --j) { 711 w = j == 0 ? ianns : anns; 712 if (w != 0) { 713 k = readUnsignedShort(w); 714 w += 2; 715 for (; k > 0; --k) { 716 desc = readUTF8(w, c); 717 w += 2; 718 w = readAnnotationValues(w, 719 c, 720 mv.visitAnnotation(desc, j != 0)); 721 } 722 } 723 } 724 if (mpanns != 0) { 725 readParameterAnnotations(mpanns, c, true, mv); 726 } 727 if (impanns != 0) { 728 readParameterAnnotations(impanns, c, false, mv); 729 } 730 while (cattrs != null) { 731 attr = cattrs.next; 732 cattrs.next = null; 733 mv.visitAttribute(cattrs); 734 cattrs = attr; 735 } 736 } 737 738 if (mv != null && v != 0) { 739 int maxStack = readUnsignedShort(v); 740 int maxLocals = readUnsignedShort(v + 2); 741 int codeLength = readInt(v + 4); 742 v += 8; 743 744 int codeStart = v; 745 int codeEnd = v + codeLength; 746 747 mv.visitCode(); 748 749 int label; 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: 757 v += 1; 758 break; 759 case ClassWriter.LABEL_INSN: 760 label = v - codeStart + readShort(v + 1); 761 if (labels[label] == null) { 762 labels[label] = new Label(); 763 } 764 v += 3; 765 break; 766 case ClassWriter.LABELW_INSN: 767 label = v - codeStart + readInt(v + 1); 768 if (labels[label] == null) { 769 labels[label] = new Label(); 770 } 771 v += 5; 772 break; 773 case ClassWriter.WIDE_INSN: 774 opcode = b[v + 1] & 0xFF; 775 if (opcode == Opcodes.IINC) { 776 v += 6; 777 } else { 778 v += 4; 779 } 780 break; 781 case ClassWriter.TABL_INSN: 782 w = v - codeStart; 784 v = v + 4 - (w & 3); 785 label = w + readInt(v); 787 v += 4; 788 if (labels[label] == null) { 789 labels[label] = new Label(); 790 } 791 j = readInt(v); 792 v += 4; 793 j = readInt(v) - j + 1; 794 v += 4; 795 for (; j > 0; --j) { 796 label = w + readInt(v); 797 v += 4; 798 if (labels[label] == null) { 799 labels[label] = new Label(); 800 } 801 } 802 break; 803 case ClassWriter.LOOK_INSN: 804 w = v - codeStart; 806 v = v + 4 - (w & 3); 807 label = w + readInt(v); 809 v += 4; 810 if (labels[label] == null) { 811 labels[label] = new Label(); 812 } 813 j = readInt(v); 814 v += 4; 815 for (; j > 0; --j) { 816 v += 4; label = w + readInt(v); 818 v += 4; 819 if (labels[label] == null) { 820 labels[label] = new Label(); 821 } 822 } 823 break; 824 case ClassWriter.VAR_INSN: 825 case ClassWriter.SBYTE_INSN: 826 case ClassWriter.LDC_INSN: 827 v += 2; 828 break; 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: 834 v += 3; 835 break; 836 case ClassWriter.ITFMETH_INSN: 837 v += 5; 838 break; 839 default: 841 v += 4; 842 break; 843 } 844 } 845 j = readUnsignedShort(v); 847 v += 2; 848 for (; j > 0; --j) { 849 label = readUnsignedShort(v); 850 Label start = labels[label]; 851 if (start == null) { 852 labels[label] = start = new Label(); 853 } 854 label = readUnsignedShort(v + 2); 855 Label end = labels[label]; 856 if (end == null) { 857 labels[label] = end = new Label(); 858 } 859 label = readUnsignedShort(v + 4); 860 Label handler = labels[label]; 861 if (handler == null) { 862 labels[label] = handler = new Label(); 863 } 864 865 int type = readUnsignedShort(v + 6); 866 if (type == 0) { 867 mv.visitTryCatchBlock(start, end, handler, null); 868 } else { 869 mv.visitTryCatchBlock(start, 870 end, 871 handler, 872 readUTF8(items[type], c)); 873 } 874 v += 8; 875 } 876 int varTable = 0; 879 int varTypeTable = 0; 880 cattrs = null; 881 j = readUnsignedShort(v); 882 v += 2; 883 for (; j > 0; --j) { 884 attrName = readUTF8(v, c); 885 if (attrName.equals("LocalVariableTable")) { 886 if (!skipDebug) { 887 varTable = v + 6; 888 k = readUnsignedShort(v + 6); 889 w = v + 8; 890 for (; k > 0; --k) { 891 label = readUnsignedShort(w); 892 if (labels[label] == null) { 893 labels[label] = new Label(); 894 } 895 label += readUnsignedShort(w + 2); 896 if (labels[label] == null) { 897 labels[label] = new Label(); 898 } 899 w += 10; 900 } 901 } 902 } else if (attrName.equals("LocalVariableTypeTable")) { 903 varTypeTable = v + 6; 904 } else if (attrName.equals("LineNumberTable")) { 905 if (!skipDebug) { 906 k = readUnsignedShort(v + 6); 907 w = v + 8; 908 for (; k > 0; --k) { 909 label = readUnsignedShort(w); 910 if (labels[label] == null) { 911 labels[label] = new Label(); 912 } 913 labels[label].line = readUnsignedShort(w + 2); 914 w += 4; 915 } 916 } 917 } else { 918 for (k = 0; k < attrs.length; ++k) { 919 if (attrs[k].type.equals(attrName)) { 920 attr = attrs[k].read(this, 921 v + 6, 922 readInt(v + 2), 923 c, 924 codeStart - 8, 925 labels); 926 if (attr != null) { 927 attr.next = cattrs; 928 cattrs = attr; 929 } 930 } 931 } 932 } 933 v += 6 + readInt(v + 2); 934 } 935 936 v = codeStart; 938 Label l; 939 while (v < codeEnd) { 940 w = v - codeStart; 941 l = labels[w]; 942 if (l != null) { 943 mv.visitLabel(l); 944 if (!skipDebug && l.line > 0) { 945 mv.visitLineNumber(l.line, l); 946 } 947 } 948 int opcode = b[v] & 0xFF; 949 switch (ClassWriter.TYPE[opcode]) { 950 case ClassWriter.NOARG_INSN: 951 mv.visitInsn(opcode); 952 v += 1; 953 break; 954 case ClassWriter.IMPLVAR_INSN: 955 if (opcode > Opcodes.ISTORE) { 956 opcode -= 59; mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2), 958 opcode & 0x3); 959 } else { 960 opcode -= 26; mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), 962 opcode & 0x3); 963 } 964 v += 1; 965 break; 966 case ClassWriter.LABEL_INSN: 967 mv.visitJumpInsn(opcode, labels[w 968 + readShort(v + 1)]); 969 v += 3; 970 break; 971 case ClassWriter.LABELW_INSN: 972 mv.visitJumpInsn(opcode - 33, labels[w 973 + readInt(v + 1)]); 974 v += 5; 975 break; 976 case ClassWriter.WIDE_INSN: 977 opcode = b[v + 1] & 0xFF; 978 if (opcode == Opcodes.IINC) { 979 mv.visitIincInsn(readUnsignedShort(v + 2), 980 readShort(v + 4)); 981 v += 6; 982 } else { 983 mv.visitVarInsn(opcode, 984 readUnsignedShort(v + 2)); 985 v += 4; 986 } 987 break; 988 case ClassWriter.TABL_INSN: 989 v = v + 4 - (w & 3); 991 label = w + readInt(v); 993 v += 4; 994 int min = readInt(v); 995 v += 4; 996 int max = readInt(v); 997 v += 4; 998 Label[] table = new Label[max - min + 1]; 999 for (j = 0; j < table.length; ++j) { 1000 table[j] = labels[w + readInt(v)]; 1001 v += 4; 1002 } 1003 mv.visitTableSwitchInsn(min, 1004 max, 1005 labels[label], 1006 table); 1007 break; 1008 case ClassWriter.LOOK_INSN: 1009 v = v + 4 - (w & 3); 1011 label = w + readInt(v); 1013 v += 4; 1014 j = readInt(v); 1015 v += 4; 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); 1020 v += 4; 1021 values[j] = labels[w + readInt(v)]; 1022 v += 4; 1023 } 1024 mv.visitLookupSwitchInsn(labels[label], 1025 keys, 1026 values); 1027 break; 1028 case ClassWriter.VAR_INSN: 1029 mv.visitVarInsn(opcode, b[v + 1] & 0xFF); 1030 v += 2; 1031 break; 1032 case ClassWriter.SBYTE_INSN: 1033 mv.visitIntInsn(opcode, b[v + 1]); 1034 v += 2; 1035 break; 1036 case ClassWriter.SHORT_INSN: 1037 mv.visitIntInsn(opcode, readShort(v + 1)); 1038 v += 3; 1039 break; 1040 case ClassWriter.LDC_INSN: 1041 mv.visitLdcInsn(readConst(b[v + 1] & 0xFF, c)); 1042 v += 2; 1043 break; 1044 case ClassWriter.LDCW_INSN: 1045 mv.visitLdcInsn(readConst(readUnsignedShort(v + 1), 1046 c)); 1047 v += 3; 1048 break; 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); 1058 } else { 1059 mv.visitMethodInsn(opcode, iowner, iname, idesc); 1060 } 1061 if (opcode == Opcodes.INVOKEINTERFACE) { 1062 v += 5; 1063 } else { 1064 v += 3; 1065 } 1066 break; 1067 case ClassWriter.TYPE_INSN: 1068 mv.visitTypeInsn(opcode, readClass(v + 1, c)); 1069 v += 3; 1070 break; 1071 case ClassWriter.IINC_INSN: 1072 mv.visitIincInsn(b[v + 1] & 0xFF, b[v + 2]); 1073 v += 3; 1074 break; 1075 default: 1077 mv.visitMultiANewArrayInsn(readClass(v + 1, c), 1078 b[v + 3] & 0xFF); 1079 v += 4; 1080 break; 1081 } 1082 } 1083 l = labels[codeEnd - codeStart]; 1084 if (l != null) { 1085 mv.visitLabel(l); 1086 } 1087 1088 if (!skipDebug && varTable != 0) { 1090 int[] typeTable = null; 1091 if (varTypeTable != 0) { 1092 w = varTypeTable; 1093 k = readUnsignedShort(w) * 3; 1094 w += 2; 1095 typeTable = new int[k]; 1096 while (k > 0) { 1097 typeTable[--k] = w + 6; typeTable[--k] = readUnsignedShort(w + 8); typeTable[--k] = readUnsignedShort(w); w += 10; 1101 } 1102 } 1103 w = varTable; 1104 k = readUnsignedShort(w); 1105 w += 2; 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) 1115 { 1116 vsignature = readUTF8(typeTable[a + 2], c); 1117 break; 1118 } 1119 } 1120 } 1121 mv.visitLocalVariable(readUTF8(w + 4, c), 1122 readUTF8(w + 6, c), 1123 vsignature, 1124 labels[start], 1125 labels[start + length], 1126 index); 1127 w += 10; 1128 } 1129 } 1130 while (cattrs != null) { 1132 attr = cattrs.next; 1133 cattrs.next = null; 1134 mv.visitAttribute(cattrs); 1135 cattrs = attr; 1136 } 1137 mv.visitMaxs(maxStack, maxLocals); 1139 } 1140 1141 if (mv != null) { 1142 mv.visitEnd(); 1143 } 1144 } 1145 1146 classVisitor.visitEnd(); 1148 } 1149 1150 1161 private void readParameterAnnotations( 1162 int v, 1163 final char[] buf, 1164 final boolean visible, 1165 final MethodVisitor mv) 1166 { 1167 int n = b[v++] & 0xFF; 1168 for (int i = 0; i < n; ++i) { 1169 int j = readUnsignedShort(v); 1170 v += 2; 1171 for (; j > 0; --j) { 1172 String desc = readUTF8(v, buf); 1173 v += 2; 1174 AnnotationVisitor av = mv.visitParameterAnnotation(i, 1175 desc, 1176 visible); 1177 v = readAnnotationValues(v, buf, av); 1178 } 1179 } 1180 } 1181 1182 1193 private int readAnnotationValues( 1194 int v, 1195 final char[] buf, 1196 final AnnotationVisitor av) 1197 { 1198 int i = readUnsignedShort(v); 1199 v += 2; 1200 for (; i > 0; --i) { 1201 String name = readUTF8(v, buf); 1202 v += 2; 1203 v = readAnnotationValue(v, buf, name, av); 1204 } 1205 av.visitEnd(); 1206 return v; 1207 } 1208 1209 1221 private int readAnnotationValue( 1222 int v, 1223 final char[] buf, 1224 final String name, 1225 final AnnotationVisitor av) 1226 { 1227 int i; 1228 switch (readByte(v++)) { 1229 case 'I': case 'J': case 'F': case 'D': av.visit(name, readConst(readUnsignedShort(v), buf)); 1234 v += 2; 1235 break; 1236 case 'B': av.visit(name, 1238 new Byte ((byte) readInt(items[readUnsignedShort(v)]))); 1239 v += 2; 1240 break; 1241 case 'Z': boolean b = readInt(items[readUnsignedShort(v)]) == 0; 1243 av.visit(name, b ? Boolean.FALSE : Boolean.TRUE); 1244 v += 2; 1245 break; 1246 case 'S': av.visit(name, 1248 new Short ((short) readInt(items[readUnsignedShort(v)]))); 1249 v += 2; 1250 break; 1251 case 'C': av.visit(name, 1253 new Character ((char) readInt(items[readUnsignedShort(v)]))); 1254 v += 2; 1255 break; 1256 case 's': av.visit(name, readUTF8(v, buf)); 1258 v += 2; 1259 break; 1260 case 'e': av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf)); 1262 v += 4; 1263 break; 1264 case 'c': av.visit(name, Type.getType(readUTF8(v, buf))); 1266 v += 2; 1267 break; 1268 case '@': String desc = readUTF8(v, buf); 1270 v += 2; 1271 v = readAnnotationValues(v, buf, av.visitAnnotation(name, desc)); 1272 break; 1273 case '[': int size = readUnsignedShort(v); 1275 v += 2; 1276 if (size == 0) { 1277 av.visitArray(name).visitEnd(); 1278 return v; 1279 } 1280 switch (readByte(v++)) { 1281 case 'B': 1282 byte[] bv = new byte[size]; 1283 for (i = 0; i < size; i++) { 1284 bv[i] = (byte) readInt(items[readUnsignedShort(v)]); 1285 v += 3; 1286 } 1287 av.visit(name, bv); 1288 --v; 1289 break; 1290 case 'Z': 1291 boolean[] zv = new boolean[size]; 1292 for (i = 0; i < size; i++) { 1293 zv[i] = readInt(items[readUnsignedShort(v)]) != 0; 1294 v += 3; 1295 } 1296 av.visit(name, zv); 1297 --v; 1298 break; 1299 case 'S': 1300 short[] sv = new short[size]; 1301 for (i = 0; i < size; i++) { 1302 sv[i] = (short) readInt(items[readUnsignedShort(v)]); 1303 v += 3; 1304 } 1305 av.visit(name, sv); 1306 --v; 1307 break; 1308 case 'C': 1309 char[] cv = new char[size]; 1310 for (i = 0; i < size; i++) { 1311 cv[i] = (char) readInt(items[readUnsignedShort(v)]); 1312 v += 3; 1313 } 1314 av.visit(name, cv); 1315 --v; 1316 break; 1317 case 'I': 1318 int[] iv = new int[size]; 1319 for (i = 0; i < size; i++) { 1320 iv[i] = readInt(items[readUnsignedShort(v)]); 1321 v += 3; 1322 } 1323 av.visit(name, iv); 1324 --v; 1325 break; 1326 case 'J': 1327 long[] lv = new long[size]; 1328 for (i = 0; i < size; i++) { 1329 lv[i] = readLong(items[readUnsignedShort(v)]); 1330 v += 3; 1331 } 1332 av.visit(name, lv); 1333 --v; 1334 break; 1335 case 'F': 1336 float[] fv = new float[size]; 1337 for (i = 0; i < size; i++) { 1338 fv[i] = Float.intBitsToFloat(readInt(items[readUnsignedShort(v)])); 1339 v += 3; 1340 } 1341 av.visit(name, fv); 1342 --v; 1343 break; 1344 case 'D': 1345 double[] dv = new double[size]; 1346 for (i = 0; i < size; i++) { 1347 dv[i] = Double.longBitsToDouble(readLong(items[readUnsignedShort(v)])); 1348 v += 3; 1349 } 1350 av.visit(name, dv); 1351 --v; 1352 break; 1353 default: 1354 v--; 1355 AnnotationVisitor aav = av.visitArray(name); 1356 for (i = size; i > 0; --i) { 1357 v = readAnnotationValue(v, buf, null, aav); 1358 } 1359 aav.visitEnd(); 1360 } 1361 } 1362 return v; 1363 } 1364 1365 1390 private Attribute readAttribute( 1391 final Attribute[] attrs, 1392 final String type, 1393 final int off, 1394 final int len, 1395 final char[] buf, 1396 final int codeOff, 1397 final Label[] labels) 1398 { 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); 1402 } 1403 } 1404 return new Attribute(type).read(this, off, len, null, -1, null); 1405 } 1406 1407 1411 1420 public int getItem(final int item) { 1421 return items[item]; 1422 } 1423 1424 1432 public int readByte(final int index) { 1433 return b[index] & 0xFF; 1434 } 1435 1436 1444 public int readUnsignedShort(final int index) { 1445 byte[] b = this.b; 1446 return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF); 1447 } 1448 1449 1457 public short readShort(final int index) { 1458 byte[] b = this.b; 1459 return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF)); 1460 } 1461 1462 1470 public int readInt(final int index) { 1471 byte[] b = this.b; 1472 return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16) 1473 | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF); 1474 } 1475 1476 1484 public long readLong(final int index) { 1485 long l1 = readInt(index); 1486 long l0 = readInt(index + 4) & 0xFFFFFFFFL; 1487 return (l1 << 32) | l0; 1488 } 1489 1490 1501 public String readUTF8(int index, final char[] buf) { 1502 int item = readUnsignedShort(index); 1503 String s = strings[item]; 1504 if (s != null) { 1505 return s; 1506 } 1507 index = items[item]; 1508 return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf); 1509 } 1510 1511 1520 private String readUTF(int index, int utfLen, char[] buf) { 1521 int endIndex = index + utfLen; 1522 byte[] b = this.b; 1523 int strLen = 0; 1524 int c, d, e; 1525 while (index < endIndex) { 1526 c = b[index++] & 0xFF; 1527 switch (c >> 4) { 1528 case 0: 1529 case 1: 1530 case 2: 1531 case 3: 1532 case 4: 1533 case 5: 1534 case 6: 1535 case 7: 1536 buf[strLen++] = (char) c; 1538 break; 1539 case 12: 1540 case 13: 1541 d = b[index++]; 1543 buf[strLen++] = (char) (((c & 0x1F) << 6) | (d & 0x3F)); 1544 break; 1545 default: 1546 d = b[index++]; 1548 e = b[index++]; 1549 buf[strLen++] = (char) (((c & 0x0F) << 12) 1550 | ((d & 0x3F) << 6) | (e & 0x3F)); 1551 break; 1552 } 1553 } 1554 return new String (buf, 0, strLen); 1555 } 1556 1557 1568 public String readClass(final int index, final char[] buf) { 1569 return readUTF8(items[readUnsignedShort(index)], buf); 1573 } 1574 1575 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 default: 1603 return readUTF8(index, buf); 1604 } 1605 } 1606} 1607 | Popular Tags |