| 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 &
|