1 30 package org.objectweb.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 strings = new String [items.length]; 107 int max = 0; 108 int index = off + 10; 109 for (int i = 1; i < items.length; ++i) { 110 items[i] = index + 1; 111 int tag = b[index]; 112 int size; 113 switch (tag) { 114 case ClassWriter.FIELD: 115 case ClassWriter.METH: 116 case ClassWriter.IMETH: 117 case ClassWriter.INT: 118 case ClassWriter.FLOAT: 119 case ClassWriter.NAME_TYPE: 120 size = 5; 121 break; 122 case ClassWriter.LONG: 123 case ClassWriter.DOUBLE: 124 size = 9; 125 ++i; 126 break; 127 case ClassWriter.UTF8: 128 size = 3 + readUnsignedShort(index + 1); 129 if (size > max) { 130 max = size; 131 } 132 break; 133 default: 136 size = 3; 137 break; 138 } 139 index += size; 140 } 141 maxStringLength = max; 142 header = index; 144 } 145 146 152 public ClassReader(final InputStream is) throws IOException { 153 this(readClass(is)); 154 } 155 156 162 public ClassReader(final String name) throws IOException { 163 this(ClassLoader.getSystemResourceAsStream(name.replace('.', '/') 164 + ".class")); 165 } 166 167 174 private static byte[] readClass(final InputStream is) throws IOException { 175 if (is == null) { 176 throw new IOException ("Class not found"); 177 } 178 byte[] b = new byte[is.available()]; 179 int len = 0; 180 while (true) { 181 int n = is.read(b, len, b.length - len); 182 if (n == -1) { 183 if (len < b.length) { 184 byte[] c = new byte[len]; 185 System.arraycopy(b, 0, c, 0, len); 186 b = c; 187 } 188 return b; 189 } 190 len += n; 191 if (len == b.length) { 192 byte[] c = new byte[b.length + 1000]; 193 System.arraycopy(b, 0, c, 0, len); 194 b = c; 195 } 196 } 197 } 198 199 203 215 public void accept(final ClassVisitor classVisitor, final boolean skipDebug) 216 { 217 accept(classVisitor, new Attribute[0], skipDebug); 218 } 219 220 235 public void accept( 236 final ClassVisitor classVisitor, 237 final Attribute[] attrs, 238 final boolean skipDebug) 239 { 240 byte[] b = this.b; char[] c = new char[maxStringLength]; int i, j, k; int u, v, w; Attribute attr; 245 246 int access; 247 String name; 248 String desc; 249 String attrName; 250 String signature; 251 int anns = 0; 252 int ianns = 0; 253 Attribute cattrs = null; 254 255 u = header; 257 access = readUnsignedShort(u); 258 name = readClass(u + 2, c); 259 v = items[readUnsignedShort(u + 4)]; 260 String superClassName = v == 0 ? null : readUTF8(v, c); 261 String [] implementedItfs = new String [readUnsignedShort(u + 6)]; 262 w = 0; 263 u += 8; 264 for (i = 0; i < implementedItfs.length; ++i) { 265 implementedItfs[i] = readClass(u, c); 266 u += 2; 267 } 268 269 v = u; 271 i = readUnsignedShort(v); 272 v += 2; 273 for (; i > 0; --i) { 274 j = readUnsignedShort(v + 6); 275 v += 8; 276 for (; j > 0; --j) { 277 v += 6 + readInt(v + 2); 278 } 279 } 280 i = readUnsignedShort(v); 281 v += 2; 282 for (; i > 0; --i) { 283 j = readUnsignedShort(v + 6); 284 v += 8; 285 for (; j > 0; --j) { 286 v += 6 + readInt(v + 2); 287 } 288 } 289 signature = null; 291 String sourceFile = null; 292 String sourceDebug = null; 293 String enclosingOwner = null; 294 String enclosingName = null; 295 String enclosingDesc = null; 296 297 i = readUnsignedShort(v); 298 v += 2; 299 for (; i > 0; --i) { 300 attrName = readUTF8(v, c); 301 if (attrName.equals("SourceFile")) { 302 sourceFile = readUTF8(v + 6, c); 303 } else if (attrName.equals("Deprecated")) { 304 access |= Opcodes.ACC_DEPRECATED; 305 } else if (attrName.equals("Synthetic")) { 306 access |= Opcodes.ACC_SYNTHETIC; 307 } else if (attrName.equals("Annotation")) { 308 access |= Opcodes.ACC_ANNOTATION; 309 } else if (attrName.equals("Enum")) { 310 access |= Opcodes.ACC_ENUM; 311 } else if (attrName.equals("InnerClasses")) { 312 w = v + 6; 313 } else if (attrName.equals("Signature")) { 314 signature = readUTF8(v + 6, c); 315 } else if (attrName.equals("SourceDebugExtension")) { 316 int len = readInt(v + 2); 317 sourceDebug = readUTF(v + 6, len, new char[len]); 318 } else if (attrName.equals("EnclosingMethod")) { 319 enclosingOwner = readClass(v + 6, c); 320 int item = readUnsignedShort(v + 8); 321 if (item != 0) { 322 enclosingName = readUTF8(items[item], c); 323 enclosingDesc = readUTF8(items[item] + 2, c); 324 } 325 } else if (attrName.equals("RuntimeVisibleAnnotations")) { 326 anns = v + 6; 327 } else if (attrName.equals("RuntimeInvisibleAnnotations")) { 328 ianns = v + 6; 329 } else { 330 attr = readAttribute(attrs, 331 attrName, 332 v + 6, 333 readInt(v + 2), 334 c, 335 -1, 336 null); 337 if (attr != null) { 338 attr.next = cattrs; 339 cattrs = attr; 340 } 341 } 342 v += 6 + readInt(v + 2); 343 } 344 classVisitor.visit(readInt(4), 346 access, 347 name, 348 signature, 349 superClassName, 350 implementedItfs); 351 352 if (sourceFile != null || sourceDebug != null) { 354 classVisitor.visitSource(sourceFile, sourceDebug); 355 } 356 357 if (enclosingOwner != null) { 359 classVisitor.visitOuterClass(enclosingOwner, 360 enclosingName, 361 enclosingDesc); 362 } 363 364 for (i = 1; i >= 0; --i) { 366 v = i == 0 ? ianns : anns; 367 if (v != 0) { 368 j = readUnsignedShort(v); 369 v += 2; 370 for (; j > 0; --j) { 371 desc = readUTF8(v, c); 372 v += 2; 373 v = readAnnotationValues(v, 374 c, 375 classVisitor.visitAnnotation(desc, i != 0)); 376 } 377 } 378 } 379 380 while (cattrs != null) { 382 attr = cattrs.next; 383 cattrs.next = null; 384 classVisitor.visitAttribute(cattrs); 385 cattrs = attr; 386 } 387 388 if (w != 0) { 390 i = readUnsignedShort(w); 391 w += 2; 392 for (; i > 0; --i) { 393 classVisitor.visitInnerClass(readUnsignedShort(w) == 0 394 ? null 395 : readClass(w, c), readUnsignedShort(w + 2) == 0 396 ? null 397 : readClass(w + 2, c), readUnsignedShort(w + 4) == 0 398 ? null 399 : readUTF8(w + 4, c), readUnsignedShort(w + 6)); 400 w += 8; 401 } 402 } 403 404 i = readUnsignedShort(u); 406 u += 2; 407 for (; i > 0; --i) { 408 access = readUnsignedShort(u); 409 name = readUTF8(u + 2, c); 410 desc = readUTF8(u + 4, c); 411 int fieldValueItem = 0; 414 signature = null; 415 anns = 0; 416 ianns = 0; 417 cattrs = null; 418 419 j = readUnsignedShort(u + 6); 420 u += 8; 421 for (; j > 0; --j) { 422 attrName = readUTF8(u, c); 423 if (attrName.equals("ConstantValue")) { 424 fieldValueItem = readUnsignedShort(u + 6); 425 } else if (attrName.equals("Synthetic")) { 426 access |= Opcodes.ACC_SYNTHETIC; 427 } else if (attrName.equals("Deprecated")) { 428 access |= Opcodes.ACC_DEPRECATED; 429 } else if (attrName.equals("Enum")) { 430 access |= Opcodes.ACC_ENUM; 431 } else if (attrName.equals("Signature")) { 432 signature = readUTF8(u + 6, c); 433 } else if (attrName.equals("RuntimeVisibleAnnotations")) { 434 anns = u + 6; 435 } else if (attrName.equals("RuntimeInvisibleAnnotations")) { 436 ianns = u + 6; 437 } else { 438 attr = readAttribute(attrs, 439 attrName, 440 u + 6, 441 readInt(u + 2), 442 c, 443 -1, 444 null); 445 if (attr != null) { 446 attr.next = cattrs; 447 cattrs = attr; 448 } 449 } 450 u += 6 + readInt(u + 2); 451 } 452 Object value = (fieldValueItem == 0 454 ? null 455 : readConst(fieldValueItem, c)); 456 FieldVisitor fv = classVisitor.visitField(access, 458 name, 459 desc, 460 signature, 461 value); 462 if (fv != null) { 464 for (j = 1; j >= 0; --j) { 465 v = j == 0 ? ianns : anns; 466 if (v != 0) { 467 k = readUnsignedShort(v); 468 v += 2; 469 for (; k > 0; --k) { 470 desc = readUTF8(v, c); 471 v += 2; 472 v = readAnnotationValues(v, 473 c, 474 fv.visitAnnotation(desc, j != 0)); 475 } 476 } 477 } 478 while (cattrs != null) { 479 attr = cattrs.next; 480 cattrs.next = null; 481 fv.visitAttribute(cattrs); 482 cattrs = attr; 483 } 484 fv.visitEnd(); 485 } 486 } 487 488 i = readUnsignedShort(u); 490 u += 2; 491 for (; i > 0; --i) { 492 access = readUnsignedShort(u); 493 name = readUTF8(u + 2, c); 494 desc = readUTF8(u + 4, c); 495 signature = null; 496 anns = 0; 497 ianns = 0; 498 int dann = 0; 499 int mpanns = 0; 500 int impanns = 0; 501 cattrs = null; 502 v = 0; 503 w = 0; 504 505 j = readUnsignedShort(u + 6); 507 u += 8; 508 for (; j > 0; --j) { 509 attrName = readUTF8(u, c); 510 u += 2; 511 int attrSize = readInt(u); 512 u += 4; 513 if (attrName.equals("Code")) { 514 v = u; 515 } else if (attrName.equals("Exceptions")) { 516 w = u; 517 } else if (attrName.equals("Synthetic")) { 518 access |= Opcodes.ACC_SYNTHETIC; 519 } else if (attrName.equals("Varargs")) { 520 access |= Opcodes.ACC_VARARGS; 521 } else if (attrName.equals("Bridge")) { 522 access |= Opcodes.ACC_BRIDGE; 523 } else if (attrName.equals("Deprecated")) { 524 access |= Opcodes.ACC_DEPRECATED; 525 } else if (attrName.equals("Signature")) { 526 signature = readUTF8(u, c); 527 } else if (attrName.equals("AnnotationDefault")) { 528 dann = u; 529 } else if (attrName.equals("RuntimeVisibleAnnotations")) { 530 anns = u; 531 } else if (attrName.equals("RuntimeInvisibleAnnotations")) { 532 ianns = u; 533 } else if (attrName.equals("RuntimeVisibleParameterAnnotations")) 534 { 535 mpanns = u; 536 } else if (attrName.equals("RuntimeInvisibleParameterAnnotations")) 537 { 538 impanns = u; 539 } else { 540 attr = readAttribute(attrs, 541 attrName, 542 u, 543 attrSize, 544 c, 545 -1, 546 null); 547 if (attr != null) { 548 attr.next = cattrs; 549 cattrs = attr; 550 } 551 } 552 u += attrSize; 553 } 554 String [] exceptions; 556 if (w == 0) { 557 exceptions = null; 558 } else { 559 exceptions = new String [readUnsignedShort(w)]; 560 w += 2; 561 for (j = 0; j < exceptions.length; ++j) { 562 exceptions[j] = readClass(w, c); 563 w += 2; 564 } 565 } 566 567 MethodVisitor mv = classVisitor.visitMethod(access, 569 name, 570 desc, 571 signature, 572 exceptions); 573 574 if (mv != null) { 575 if (dann != 0) { 576 AnnotationVisitor dv = mv.visitAnnotationDefault(); 577 readAnnotationValue(dann, c, null, dv); 578 dv.visitEnd(); 579 } 580 for (j = 1; j >= 0; --j) { 581 w = j == 0 ? ianns : anns; 582 if (w != 0) { 583 k = readUnsignedShort(w); 584 w += 2; 585 for (; k > 0; --k) { 586 desc = readUTF8(w, c); 587 w += 2; 588 w = readAnnotationValues(w, 589 c, 590 mv.visitAnnotation(desc, j != 0)); 591 } 592 } 593 } 594 if (mpanns != 0) { 595 readParameterAnnotations(mpanns, c, true, mv); 596 } 597 if (impanns != 0) { 598 readParameterAnnotations(impanns, c, false, mv); 599 } 600 while (cattrs != null) { 601 attr = cattrs.next; 602 cattrs.next = null; 603 mv.visitAttribute(cattrs); 604 cattrs = attr; 605 } 606 } 607 608 if (mv != null && v != 0) { 609 int maxStack = readUnsignedShort(v); 610 int maxLocals = readUnsignedShort(v + 2); 611 int codeLength = readInt(v + 4); 612 v += 8; 613 614 int codeStart = v; 615 int codeEnd = v + codeLength; 616 617 int label; 619 Label[] labels = new Label[codeLength + 1]; 620 while (v < codeEnd) { 621 int opcode = b[v] & 0xFF; 622 switch (ClassWriter.TYPE[opcode]) { 623 case ClassWriter.NOARG_INSN: 624 case ClassWriter.IMPLVAR_INSN: 625 v += 1; 626 break; 627 case ClassWriter.LABEL_INSN: 628 label = v - codeStart + readShort(v + 1); 629 if (labels[label] == null) { 630 labels[label] = new Label(); 631 } 632 v += 3; 633 break; 634 case ClassWriter.LABELW_INSN: 635 label = v - codeStart + readInt(v + 1); 636 if (labels[label] == null) { 637 labels[label] = new Label(); 638 } 639 v += 5; 640 break; 641 case ClassWriter.WIDE_INSN: 642 opcode = b[v + 1] & 0xFF; 643 if (opcode == Opcodes.IINC) { 644 v += 6; 645 } else { 646 v += 4; 647 } 648 break; 649 case ClassWriter.TABL_INSN: 650 w = v - codeStart; 652 v = v + 4 - (w & 3); 653 label = w + readInt(v); 655 v += 4; 656 if (labels[label] == null) { 657 labels[label] = new Label(); 658 } 659 j = readInt(v); 660 v += 4; 661 j = readInt(v) - j + 1; 662 v += 4; 663 for (; j > 0; --j) { 664 label = w + readInt(v); 665 v += 4; 666 if (labels[label] == null) { 667 labels[label] = new Label(); 668 } 669 } 670 break; 671 case ClassWriter.LOOK_INSN: 672 w = v - codeStart; 674 v = v + 4 - (w & 3); 675 label = w + readInt(v); 677 v += 4; 678 if (labels[label] == null) { 679 labels[label] = new Label(); 680 } 681 j = readInt(v); 682 v += 4; 683 for (; j > 0; --j) { 684 v += 4; label = w + readInt(v); 686 v += 4; 687 if (labels[label] == null) { 688 labels[label] = new Label(); 689 } 690 } 691 break; 692 case ClassWriter.VAR_INSN: 693 case ClassWriter.SBYTE_INSN: 694 case ClassWriter.LDC_INSN: 695 v += 2; 696 break; 697 case ClassWriter.SHORT_INSN: 698 case ClassWriter.LDCW_INSN: 699 case ClassWriter.FIELDORMETH_INSN: 700 case ClassWriter.TYPE_INSN: 701 case ClassWriter.IINC_INSN: 702 v += 3; 703 break; 704 case ClassWriter.ITFMETH_INSN: 705 v += 5; 706 break; 707 default: 709 v += 4; 710 break; 711 } 712 } 713 j = readUnsignedShort(v); 715 v += 2; 716 for (; j > 0; --j) { 717 label = readUnsignedShort(v); 718 if (labels[label] == null) { 719 labels[label] = new Label(); 720 } 721 label = readUnsignedShort(v + 2); 722 if (labels[label] == null) { 723 labels[label] = new Label(); 724 } 725 label = readUnsignedShort(v + 4); 726 if (labels[label] == null) { 727 labels[label] = new Label(); 728 } 729 v += 8; 730 } 731 int varTable = 0; 734 int varTypeTable = 0; 735 cattrs = null; 736 j = readUnsignedShort(v); 737 v += 2; 738 for (; j > 0; --j) { 739 attrName = readUTF8(v, c); 740 if (attrName.equals("LocalVariableTable")) { 741 if (!skipDebug) { 742 varTable = v + 6; 743 k = readUnsignedShort(v + 6); 744 w = v + 8; 745 for (; k > 0; --k) { 746 label = readUnsignedShort(w); 747 if (labels[label] == null) { 748 labels[label] = new Label(); 749 } 750 label += readUnsignedShort(w + 2); 751 if (labels[label] == null) { 752 labels[label] = new Label(); 753 } 754 w += 10; 755 } 756 } 757 } else if (attrName.equals("LocalVariableTypeTable")) { 758 varTypeTable = v + 6; 759 } else if (attrName.equals("LineNumberTable")) { 760 if (!skipDebug) { 761 k = readUnsignedShort(v + 6); 762 w = v + 8; 763 for (; k > 0; --k) { 764 label = readUnsignedShort(w); 765 if (labels[label] == null) { 766 labels[label] = new Label(); 767 } 768 labels[label].line = readUnsignedShort(w + 2); 769 w += 4; 770 } 771 } 772 } else { 773 for (k = 0; k < attrs.length; ++k) { 774 if (attrs[k].type.equals(attrName)) { 775 attr = attrs[k].read(this, 776 v + 6, 777 readInt(v + 2), 778 c, 779 codeStart - 8, 780 labels); 781 if (attr != null) { 782 attr.next = cattrs; 783 cattrs = attr; 784 } 785 } 786 } 787 } 788 v += 6 + readInt(v + 2); 789 } 790 791 mv.visitCode(); 793 v = codeStart; 794 Label l; 795 while (v < codeEnd) { 796 w = v - codeStart; 797 l = labels[w]; 798 if (l != null) { 799 mv.visitLabel(l); 800 if (!skipDebug && l.line > 0) { 801 mv.visitLineNumber(l.line, l); 802 } 803 } 804 int opcode = b[v] & 0xFF; 805 switch (ClassWriter.TYPE[opcode]) { 806 case ClassWriter.NOARG_INSN: 807 mv.visitInsn(opcode); 808 v += 1; 809 break; 810 case ClassWriter.IMPLVAR_INSN: 811 if (opcode > Opcodes.ISTORE) { 812 opcode -= 59; mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2), 814 opcode & 0x3); 815 } else { 816 opcode -= 26; mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), 818 opcode & 0x3); 819 } 820 v += 1; 821 break; 822 case ClassWriter.LABEL_INSN: 823 mv.visitJumpInsn(opcode, labels[w 824 + readShort(v + 1)]); 825 v += 3; 826 break; 827 case ClassWriter.LABELW_INSN: 828 mv.visitJumpInsn(opcode - 33, labels[w 829 + readInt(v + 1)]); 830 v += 5; 831 break; 832 case ClassWriter.WIDE_INSN: 833 opcode = b[v + 1] & 0xFF; 834 if (opcode == Opcodes.IINC) { 835 mv.visitIincInsn(readUnsignedShort(v + 2), 836 readShort(v + 4)); 837 v += 6; 838 } else { 839 mv.visitVarInsn(opcode, 840 readUnsignedShort(v + 2)); 841 v += 4; 842 } 843 break; 844 case ClassWriter.TABL_INSN: 845 v = v + 4 - (w & 3); 847 label = w + readInt(v); 849 v += 4; 850 int min = readInt(v); 851 v += 4; 852 int max = readInt(v); 853 v += 4; 854 Label[] table = new Label[max - min + 1]; 855 for (j = 0; j < table.length; ++j) { 856 table[j] = labels[w + readInt(v)]; 857 v += 4; 858 } 859 mv.visitTableSwitchInsn(min, 860 max, 861 labels[label], 862 table); 863 break; 864 case ClassWriter.LOOK_INSN: 865 v = v + 4 - (w & 3); 867 label = w + readInt(v); 869 v += 4; 870 j = readInt(v); 871 v += 4; 872 int[] keys = new int[j]; 873 Label[] values = new Label[j]; 874 for (j = 0; j < keys.length; ++j) { 875 keys[j] = readInt(v); 876 v += 4; 877 values[j] = labels[w + readInt(v)]; 878 v += 4; 879 } 880 mv.visitLookupSwitchInsn(labels[label], 881 keys, 882 values); 883 break; 884 case ClassWriter.VAR_INSN: 885 mv.visitVarInsn(opcode, b[v + 1] & 0xFF); 886 v += 2; 887 break; 888 case ClassWriter.SBYTE_INSN: 889 mv.visitIntInsn(opcode, b[v + 1]); 890 v += 2; 891 break; 892 case ClassWriter.SHORT_INSN: 893 mv.visitIntInsn(opcode, readShort(v + 1)); 894 v += 3; 895 break; 896 case ClassWriter.LDC_INSN: 897 mv.visitLdcInsn(readConst(b[v + 1] & 0xFF, c)); 898 v += 2; 899 break; 900 case ClassWriter.LDCW_INSN: 901 mv.visitLdcInsn(readConst(readUnsignedShort(v + 1), 902 c)); 903 v += 3; 904 break; 905 case ClassWriter.FIELDORMETH_INSN: 906 case ClassWriter.ITFMETH_INSN: 907 int cpIndex = items[readUnsignedShort(v + 1)]; 908 String iowner = readClass(cpIndex, c); 909 cpIndex = items[readUnsignedShort(cpIndex + 2)]; 910 String iname = readUTF8(cpIndex, c); 911 String idesc = readUTF8(cpIndex + 2, c); 912 if (opcode < Opcodes.INVOKEVIRTUAL) { 913 mv.visitFieldInsn(opcode, iowner, iname, idesc); 914 } else { 915 mv.visitMethodInsn(opcode, iowner, iname, idesc); 916 } 917 if (opcode == Opcodes.INVOKEINTERFACE) { 918 v += 5; 919 } else { 920 v += 3; 921 } 922 break; 923 case ClassWriter.TYPE_INSN: 924 mv.visitTypeInsn(opcode, readClass(v + 1, c)); 925 v += 3; 926 break; 927 case ClassWriter.IINC_INSN: 928 mv.visitIincInsn(b[v + 1] & 0xFF, b[v + 2]); 929 v += 3; 930 break; 931 default: 933 mv.visitMultiANewArrayInsn(readClass(v + 1, c), 934 b[v + 3] & 0xFF); 935 v += 4; 936 break; 937 } 938 } 939 l = labels[codeEnd - codeStart]; 940 if (l != null) { 941 mv.visitLabel(l); 942 } 943 j = readUnsignedShort(v); 945 v += 2; 946 for (; j > 0; --j) { 947 Label start = labels[readUnsignedShort(v)]; 948 Label end = labels[readUnsignedShort(v + 2)]; 949 Label handler = labels[readUnsignedShort(v + 4)]; 950 int type = readUnsignedShort(v + 6); 951 if (type == 0) { 952 mv.visitTryCatchBlock(start, end, handler, null); 953 } else { 954 mv.visitTryCatchBlock(start, 955 end, 956 handler, 957 readUTF8(items[type], c)); 958 } 959 v += 8; 960 } 961 if (!skipDebug && varTable != 0) { 963 int[] typeTable = null; 964 if (varTypeTable != 0) { 965 w = varTypeTable; 966 k = readUnsignedShort(w) * 3; 967 w += 2; 968 typeTable = new int[k]; 969 while (k > 0) { 970 typeTable[--k] = w + 6; typeTable[--k] = readUnsignedShort(w + 8); typeTable[--k] = readUnsignedShort(w); w += 10; 974 } 975 } 976 w = varTable; 977 k = readUnsignedShort(w); 978 w += 2; 979 for (; k > 0; --k) { 980 int start = readUnsignedShort(w); 981 int length = readUnsignedShort(w + 2); 982 int index = readUnsignedShort(w + 8); 983 String vsignature = null; 984 if (typeTable != null) { 985 for (int a = 0; a < typeTable.length; a += 3) { 986 if (typeTable[a] == start 987 && typeTable[a + 1] == index) 988 { 989 vsignature = readUTF8(typeTable[a + 2], c); 990 break; 991 } 992 } 993 } 994 mv.visitLocalVariable(readUTF8(w + 4, c), 995 readUTF8(w + 6, c), 996 vsignature, 997 labels[start], 998 labels[start + length], 999 index); 1000 w += 10; 1001 } 1002 } 1003 while (cattrs != null) { 1005 attr = cattrs.next; 1006 cattrs.next = null; 1007 mv.visitAttribute(cattrs); 1008 cattrs = attr; 1009 } 1010 mv.visitMaxs(maxStack, maxLocals); 1012 } 1013 1014 if (mv != null) { 1015 mv.visitEnd(); 1016 } 1017 } 1018 1019 classVisitor.visitEnd(); 1021 } 1022 1023 1034 private void readParameterAnnotations( 1035 int v, 1036 final char[] buf, 1037 final boolean visible, 1038 final MethodVisitor mv) 1039 { 1040 int n = b[v++] & 0xFF; 1041 for (int i = 0; i < n; ++i) { 1042 int j = readUnsignedShort(v); 1043 v += 2; 1044 for (; j > 0; --j) { 1045 String desc = readUTF8(v, buf); 1046 v += 2; 1047 AnnotationVisitor av = mv.visitParameterAnnotation(i, 1048 desc, 1049 visible); 1050 v = readAnnotationValues(v, buf, av); 1051 } 1052 } 1053 } 1054 1055 1066 private int readAnnotationValues( 1067 int v, 1068 final char[] buf, 1069 final AnnotationVisitor av) 1070 { 1071 int i = readUnsignedShort(v); 1072 v += 2; 1073 for (; i > 0; --i) { 1074 String name = readUTF8(v, buf); 1075 v += 2; 1076 v = readAnnotationValue(v, buf, name, av); 1077 } 1078 av.visitEnd(); 1079 return v; 1080 } 1081 1082 1094 private int readAnnotationValue( 1095 int v, 1096 final char[] buf, 1097 final String name, 1098 final AnnotationVisitor av) 1099 { 1100 int i; 1101 switch (readByte(v++)) { 1102 case 'I': case 'J': case 'F': case 'D': av.visit(name, readConst(readUnsignedShort(v), buf)); 1107 v += 2; 1108 break; 1109 case 'B': av.visit(name, 1111 new Byte ((byte) readInt(items[readUnsignedShort(v)]))); 1112 v += 2; 1113 break; 1114 case 'Z': boolean b = readInt(items[readUnsignedShort(v)]) == 0; 1116 av.visit(name, b ? Boolean.FALSE : Boolean.TRUE); 1117 v += 2; 1118 break; 1119 case 'S': av.visit(name, 1121 new Short ((short) readInt(items[readUnsignedShort(v)]))); 1122 v += 2; 1123 break; 1124 case 'C': av.visit(name, 1126 new Character ((char) readInt(items[readUnsignedShort(v)]))); 1127 v += 2; 1128 break; 1129 case 's': av.visit(name, readUTF8(v, buf)); 1131 v += 2; 1132 break; 1133 case 'e': av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf)); 1135 v += 4; 1136 break; 1137 case 'c': av.visit(name, Type.getType(readUTF8(v, buf))); 1139 v += 2; 1140 break; 1141 case '@': String desc = readUTF8(v, buf); 1143 v += 2; 1144 v = readAnnotationValues(v, buf, av.visitAnnotation(name, desc)); 1145 break; 1146 case '[': int size = readUnsignedShort(v); 1148 v += 2; 1149 switch (readByte(v++)) { 1150 case 'B': 1151 byte[] bv = new byte[size]; 1152 for (i = 0; i < size; i++) { 1153 bv[i] = (byte) readInt(items[readUnsignedShort(v)]); 1154 v += 3; 1155 } 1156 av.visit(name, bv); 1157 --v; 1158 break; 1159 case 'Z': 1160 boolean[] zv = new boolean[size]; 1161 for (i = 0; i < size; i++) { 1162 zv[i] = readInt(items[readUnsignedShort(v)]) != 0; 1163 v += 3; 1164 } 1165 av.visit(name, zv); 1166 --v; 1167 break; 1168 case 'S': 1169 short[] sv = new short[size]; 1170 for (i = 0; i < size; i++) { 1171 sv[i] = (short) readInt(items[readUnsignedShort(v)]); 1172 v += 3; 1173 } 1174 av.visit(name, sv); 1175 --v; 1176 break; 1177 case 'C': 1178 char[] cv = new char[size]; 1179 for (i = 0; i < size; i++) { 1180 cv[i] = (char) readInt(items[readUnsignedShort(v)]); 1181 v += 3; 1182 } 1183 av.visit(name, cv); 1184 --v; 1185 break; 1186 case 'I': 1187 int[] iv = new int[size]; 1188 for (i = 0; i < size; i++) { 1189 iv[i] = readInt(items[readUnsignedShort(v)]); 1190 v += 3; 1191 } 1192 av.visit(name, iv); 1193 --v; 1194 break; 1195 case 'J': 1196 long[] lv = new long[size]; 1197 for (i = 0; i < size; i++) { 1198 lv[i] = readLong(items[readUnsignedShort(v)]); 1199 v += 3; 1200 } 1201 av.visit(name, lv); 1202 --v; 1203 break; 1204 case 'F': 1205 float[] fv = new float[size]; 1206 for (i = 0; i < size; i++) { 1207 fv[i] = Float.intBitsToFloat(readInt(items[readUnsignedShort(v)])); 1208 v += 3; 1209 } 1210 av.visit(name, fv); 1211 --v; 1212 break; 1213 case 'D': 1214 double[] dv = new double[size]; 1215 for (i = 0; i < size; i++) { 1216 dv[i] = Double.longBitsToDouble(readLong(items[readUnsignedShort(v)])); 1217 v += 3; 1218 } 1219 av.visit(name, dv); 1220 --v; 1221 break; 1222 default: 1223 v--; 1224 AnnotationVisitor aav = av.visitArray(name); 1225 for (i = size; i > 0; --i) { 1226 v = readAnnotationValue(v, buf, null, aav); 1227 } 1228 aav.visitEnd(); 1229 } 1230 } 1231 return v; 1232 } 1233 1234 1259 private Attribute readAttribute( 1260 final Attribute[] attrs, 1261 final String type, 1262 final int off, 1263 final int len, 1264 final char[] buf, 1265 final int codeOff, 1266 final Label[] labels) 1267 { 1268 for (int i = 0; i < attrs.length; ++i) { 1269 if (attrs[i].type.equals(type)) { 1270 return attrs[i].read(this, off, len, buf, codeOff, labels); 1271 } 1272 } 1273 return new Attribute(type); 1274 } 1275 1276 1280 1289 public int getItem(final int item) { 1290 return items[item]; 1291 } 1292 1293 1301 public int readByte(final int index) { 1302 return b[index] & 0xFF; 1303 } 1304 1305 1313 public int readUnsignedShort(final int index) { 1314 byte[] b = this.b; 1315 return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF); 1316 } 1317 1318 1326 public short readShort(final int index) { 1327 byte[] b = this.b; 1328 return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF)); 1329 } 1330 1331 1339 public int readInt(final int index) { 1340 byte[] b = this.b; 1341 return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16) 1342 | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF); 1343 } 1344 1345 1353 public long readLong(final int index) { 1354 long l1 = readInt(index); 1355 long l0 = readInt(index + 4) & 0xFFFFFFFFL; 1356 return (l1 << 32) | l0; 1357 } 1358 1359 1370 public String readUTF8(int index, final char[] buf) { 1371 int item = readUnsignedShort(index); 1372 String s = strings[item]; 1373 if (s != null) { 1374 return s; 1375 } 1376 index = items[item]; 1377 return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf); 1378 } 1379 1380 1389 private String readUTF(int index, int utfLen, char[] buf) { 1390 int endIndex = index + utfLen; 1391 byte[] b = this.b; 1392 int strLen = 0; 1393 int c, d, e; 1394 while (index < endIndex) { 1395 c = b[index++] & 0xFF; 1396 switch (c >> 4) { 1397 case 0: 1398 case 1: 1399 case 2: 1400 case 3: 1401 case 4: 1402 case 5: 1403 case 6: 1404 case 7: 1405 buf[strLen++] = (char) c; 1407 break; 1408 case 12: 1409 case 13: 1410 d = b[index++]; 1412 buf[strLen++] = (char) (((c & 0x1F) << 6) | (d & 0x3F)); 1413 break; 1414 default: 1415 d = b[index++]; 1417 e = b[index++]; 1418 buf[strLen++] = (char) (((c & 0x0F) << 12) 1419 | ((d & 0x3F) << 6) | (e & 0x3F)); 1420 break; 1421 } 1422 } 1423 return new String (buf, 0, strLen); 1424 } 1425 1426 1437 public String readClass(final int index, final char[] buf) { 1438 return readUTF8(items[readUnsignedShort(index)], buf); 1442 } 1443 1444 1456 public Object readConst(final int item, final char[] buf) { 1457 int index = items[item]; 1458 switch (b[index - 1]) { 1459 case ClassWriter.INT: 1460 return new Integer (readInt(index)); 1461 case ClassWriter.FLOAT: 1462 return new Float (Float.intBitsToFloat(readInt(index))); 1463 case ClassWriter.LONG: 1464 return new Long (readLong(index)); 1465 case ClassWriter.DOUBLE: 1466 return new Double (Double.longBitsToDouble(readLong(index))); 1467 case ClassWriter.CLASS: 1468 String s = readUTF8(index, buf); 1469 return Type.getType(s.charAt(0) == '[' ? s : "L" + s + ";"); 1470 default: 1472 return readUTF8(index, buf); 1473 } 1474 } 1475} 1476 | Popular Tags |