1 52 53 package com.go.trove.classfile; 54 55 import java.util.*; 56 57 63 public class CodeDisassembler { 64 private final MethodInfo mMethod; 65 private final String mEnclosingClassName; 66 private final String mSuperClassName; 67 private final CodeAttr mCode; 68 private final ConstantPool mCp; 69 private final byte[] mByteCodes; 70 private final ExceptionHandler[] mExceptionHandlers; 71 72 private CodeAssembler mAssembler; 74 75 private Vector mLocals; 77 78 private boolean mHasThis; 80 81 private Map mLabels; 84 85 private Map mCatchLocations; 87 88 private int mAddress; 90 91 public CodeDisassembler(MethodInfo method) { 92 mMethod = method; 93 mEnclosingClassName = method.getClassFile().getClassName(); 94 mSuperClassName = method.getClassFile().getSuperClassName(); 95 mCode = method.getCodeAttr(); 96 mCp = mCode.getConstantPool(); 97 CodeBuffer buffer = mCode.getCodeBuffer(); 98 mByteCodes = buffer.getByteCodes(); 99 mExceptionHandlers = buffer.getExceptionHandlers(); 100 } 101 102 107 public synchronized void disassemble(CodeAssembler assembler) { 108 mAssembler = assembler; 109 mLocals = new Vector(); 110 mHasThis = !mMethod.getAccessFlags().isStatic(); 111 112 gatherLabels(); 113 114 LocalVariable[] paramVars = assembler.getParameters(); 116 for (int i=0; i<paramVars.length; i++) { 117 LocalVariable paramVar = paramVars[i]; 118 int number = paramVar.getNumber(); 119 if (number >= mLocals.size()) { 120 mLocals.setSize(number + 1); 121 } 122 mLocals.setElementAt(paramVar, number); 123 } 124 125 Location currentLoc = new Location() { 126 public int getLocation() { 127 return mAddress; 128 } 129 130 public int compareTo(Object obj) { 131 if (this == obj) { 132 return 0; 133 } 134 Location other = (Location)obj; 135 136 int loca = getLocation(); 137 int locb = other.getLocation(); 138 139 if (loca < locb) { 140 return -1; 141 } 142 else if (loca > locb) { 143 return 1; 144 } 145 else { 146 return 0; 147 } 148 } 149 }; 150 151 int currentLine = -1; 152 153 for (mAddress = 0; mAddress < mByteCodes.length; mAddress++) { 154 int nextLine = mCode.getLineNumber(currentLoc); 155 if (nextLine != currentLine) { 156 if ((currentLine = nextLine) >= 0) { 157 mAssembler.mapLineNumber(currentLine); 158 } 159 } 160 161 locateLabel(); 163 164 byte opcode = mByteCodes[mAddress]; 165 166 int index; 167 Location loc; 168 Class clazz; 169 ConstantInfo ci; 170 171 switch (opcode) { 172 173 default: 174 break; 176 177 179 case Opcode.NOP: 180 assembler.nop(); 181 break; 182 case Opcode.BREAKPOINT: 183 assembler.breakpoint(); 184 break; 185 186 case Opcode.ACONST_NULL: 187 assembler.loadConstant(null); 188 break; 189 case Opcode.ICONST_M1: 190 assembler.loadConstant(-1); 191 break; 192 case Opcode.ICONST_0: 193 assembler.loadConstant(0); 194 break; 195 case Opcode.ICONST_1: 196 assembler.loadConstant(1); 197 break; 198 case Opcode.ICONST_2: 199 assembler.loadConstant(2); 200 break; 201 case Opcode.ICONST_3: 202 assembler.loadConstant(3); 203 break; 204 case Opcode.ICONST_4: 205 assembler.loadConstant(4); 206 break; 207 case Opcode.ICONST_5: 208 assembler.loadConstant(5); 209 break; 210 case Opcode.LCONST_0: 211 assembler.loadConstant(0L); 212 break; 213 case Opcode.LCONST_1: 214 assembler.loadConstant(1L); 215 break; 216 case Opcode.FCONST_0: 217 assembler.loadConstant(0f); 218 break; 219 case Opcode.FCONST_1: 220 assembler.loadConstant(1f); 221 break; 222 case Opcode.FCONST_2: 223 assembler.loadConstant(2f); 224 break; 225 case Opcode.DCONST_0: 226 assembler.loadConstant(0d); 227 break; 228 case Opcode.DCONST_1: 229 assembler.loadConstant(1d); 230 break; 231 232 case Opcode.POP: 233 assembler.pop(); 234 break; 235 case Opcode.POP2: 236 assembler.pop2(); 237 break; 238 case Opcode.DUP: 239 assembler.dup(); 240 break; 241 case Opcode.DUP_X1: 242 assembler.dupX1(); 243 break; 244 case Opcode.DUP_X2: 245 assembler.dupX2(); 246 break; 247 case Opcode.DUP2: 248 assembler.dup2(); 249 break; 250 case Opcode.DUP2_X1: 251 assembler.dup2X2(); 252 break; 253 case Opcode.DUP2_X2: 254 assembler.dup2X2(); 255 break; 256 case Opcode.SWAP: 257 assembler.swap(); 258 break; 259 260 case Opcode.IADD: case Opcode.LADD: 261 case Opcode.FADD: case Opcode.DADD: 262 case Opcode.ISUB: case Opcode.LSUB: 263 case Opcode.FSUB: case Opcode.DSUB: 264 case Opcode.IMUL: case Opcode.LMUL: 265 case Opcode.FMUL: case Opcode.DMUL: 266 case Opcode.IDIV: case Opcode.LDIV: 267 case Opcode.FDIV: case Opcode.DDIV: 268 case Opcode.IREM: case Opcode.LREM: 269 case Opcode.FREM: case Opcode.DREM: 270 case Opcode.INEG: case Opcode.LNEG: 271 case Opcode.FNEG: case Opcode.DNEG: 272 case Opcode.ISHL: case Opcode.LSHL: 273 case Opcode.ISHR: case Opcode.LSHR: 274 case Opcode.IUSHR: case Opcode.LUSHR: 275 case Opcode.IAND: case Opcode.LAND: 276 case Opcode.IOR: case Opcode.LOR: 277 case Opcode.IXOR: case Opcode.LXOR: 278 case Opcode.FCMPL: case Opcode.DCMPL: 279 case Opcode.FCMPG: case Opcode.DCMPG: 280 case Opcode.LCMP: 281 assembler.math(opcode); 282 break; 283 284 case Opcode.I2L: 285 assembler.convert(int.class, long.class); 286 break; 287 case Opcode.I2F: 288 assembler.convert(int.class, float.class); 289 break; 290 case Opcode.I2D: 291 assembler.convert(int.class, double.class); 292 break; 293 case Opcode.L2I: 294 assembler.convert(long.class, int.class); 295 break; 296 case Opcode.L2F: 297 assembler.convert(long.class, float.class); 298 break; 299 case Opcode.L2D: 300 assembler.convert(long.class, double.class); 301 break; 302 case Opcode.F2I: 303 assembler.convert(float.class, int.class); 304 break; 305 case Opcode.F2L: 306 assembler.convert(float.class, long.class); 307 break; 308 case Opcode.F2D: 309 assembler.convert(float.class, double.class); 310 break; 311 case Opcode.D2I: 312 assembler.convert(double.class, int.class); 313 break; 314 case Opcode.D2L: 315 assembler.convert(double.class, long.class); 316 break; 317 case Opcode.D2F: 318 assembler.convert(double.class, float.class); 319 break; 320 case Opcode.I2B: 321 assembler.convert(int.class, byte.class); 322 break; 323 case Opcode.I2C: 324 assembler.convert(int.class, char.class); 325 break; 326 case Opcode.I2S: 327 assembler.convert(int.class, short.class); 328 break; 329 330 case Opcode.IRETURN: 331 assembler.returnValue(int.class); 332 break; 333 case Opcode.LRETURN: 334 assembler.returnValue(long.class); 335 break; 336 case Opcode.FRETURN: 337 assembler.returnValue(float.class); 338 break; 339 case Opcode.DRETURN: 340 assembler.returnValue(double.class); 341 break; 342 case Opcode.ARETURN: 343 assembler.returnValue(Object .class); 344 break; 345 case Opcode.RETURN: 346 assembler.returnVoid(); 347 break; 348 349 case Opcode.IALOAD: 350 assembler.loadFromArray(int.class); 351 break; 352 case Opcode.LALOAD: 353 assembler.loadFromArray(long.class); 354 break; 355 case Opcode.FALOAD: 356 assembler.loadFromArray(float.class); 357 break; 358 case Opcode.DALOAD: 359 assembler.loadFromArray(double.class); 360 break; 361 case Opcode.AALOAD: 362 assembler.loadFromArray(Object .class); 363 break; 364 case Opcode.BALOAD: 365 assembler.loadFromArray(byte.class); 366 break; 367 case Opcode.CALOAD: 368 assembler.loadFromArray(char.class); 369 break; 370 case Opcode.SALOAD: 371 assembler.loadFromArray(short.class); 372 break; 373 374 case Opcode.IASTORE: 375 assembler.storeToArray(int.class); 376 break; 377 case Opcode.LASTORE: 378 assembler.storeToArray(long.class); 379 break; 380 case Opcode.FASTORE: 381 assembler.storeToArray(float.class); 382 break; 383 case Opcode.DASTORE: 384 assembler.storeToArray(double.class); 385 break; 386 case Opcode.AASTORE: 387 assembler.storeToArray(Object .class); 388 break; 389 case Opcode.BASTORE: 390 assembler.storeToArray(byte.class); 391 break; 392 case Opcode.CASTORE: 393 assembler.storeToArray(char.class); 394 break; 395 case Opcode.SASTORE: 396 assembler.storeToArray(short.class); 397 break; 398 399 case Opcode.ARRAYLENGTH: 400 assembler.arrayLength(); 401 break; 402 case Opcode.ATHROW: 403 assembler.throwObject(); 404 break; 405 case Opcode.MONITORENTER: 406 assembler.monitorEnter(); 407 break; 408 case Opcode.MONITOREXIT: 409 assembler.monitorExit(); 410 break; 411 412 414 416 case Opcode.LDC: 417 case Opcode.LDC_W: 418 case Opcode.LDC2_W: 419 switch (opcode) { 420 case Opcode.LDC: 421 index = readUnsignedByte(); 422 break; 423 case Opcode.LDC_W: 424 case Opcode.LDC2_W: 425 index = readUnsignedShort(); 426 break; 427 default: 428 index = 0; 429 break; 430 } 431 432 ci = mCp.getConstant(index); 433 434 if (ci instanceof ConstantStringInfo) { 435 assembler.loadConstant 436 (((ConstantStringInfo)ci).getValue()); 437 } 438 else if (ci instanceof ConstantIntegerInfo) { 439 assembler.loadConstant 440 (((ConstantIntegerInfo)ci).getValue().intValue()); 441 } 442 else if (ci instanceof ConstantLongInfo) { 443 assembler.loadConstant 444 (((ConstantLongInfo)ci).getValue().longValue()); 445 } 446 else if (ci instanceof ConstantFloatInfo) { 447 assembler.loadConstant 448 (((ConstantFloatInfo)ci).getValue().floatValue()); 449 } 450 else if (ci instanceof ConstantDoubleInfo) { 451 assembler.loadConstant 452 (((ConstantDoubleInfo)ci).getValue().doubleValue()); 453 } 454 else { 455 } 457 break; 458 459 case Opcode.NEW: 460 ci = mCp.getConstant(readUnsignedShort()); 461 462 if (ci instanceof ConstantClassInfo) { 463 assembler.newObject 464 (((ConstantClassInfo)ci).getTypeDescriptor()); 465 } 466 else { 467 } 469 break; 470 case Opcode.ANEWARRAY: 471 ci = mCp.getConstant(readUnsignedShort()); 472 473 if (ci instanceof ConstantClassInfo) { 474 TypeDescriptor type = 475 ((ConstantClassInfo)ci).getTypeDescriptor(); 476 type = new TypeDescriptor(type, 1); 477 assembler.newObject(type); 478 } 479 else { 480 } 482 break; 483 case Opcode.MULTIANEWARRAY: 484 ci = mCp.getConstant(readUnsignedShort()); 485 int dims = readUnsignedByte(); 486 487 if (ci instanceof ConstantClassInfo) { 488 assembler.newObject 489 (((ConstantClassInfo)ci).getTypeDescriptor()); 490 } 491 else { 492 } 494 break; 495 496 case Opcode.CHECKCAST: 497 ci = mCp.getConstant(readUnsignedShort()); 498 499 if (ci instanceof ConstantClassInfo) { 500 assembler.checkCast 501 (((ConstantClassInfo)ci).getTypeDescriptor()); 502 } 503 else { 504 } 506 break; 507 case Opcode.INSTANCEOF: 508 ci = mCp.getConstant(readUnsignedShort()); 509 510 if (ci instanceof ConstantClassInfo) { 511 assembler.instanceOf 512 (((ConstantClassInfo)ci).getTypeDescriptor()); 513 } 514 else { 515 } 517 break; 518 519 case Opcode.GETSTATIC: 520 case Opcode.PUTSTATIC: 521 case Opcode.GETFIELD: 522 case Opcode.PUTFIELD: 523 ci = mCp.getConstant(readUnsignedShort()); 524 if (!(ci instanceof ConstantFieldInfo)) { 525 break; 527 } 528 ConstantFieldInfo field = (ConstantFieldInfo)ci; 529 String className = field.getParentClass().getClassName(); 530 if (mEnclosingClassName.equals(className)) { 531 className = null; 532 } 533 String fieldName = field.getNameAndType().getName(); 534 Descriptor type = field.getNameAndType().getType(); 535 if (!(type instanceof TypeDescriptor)) { 536 break; 538 } 539 540 545 switch (opcode) { 546 case Opcode.GETSTATIC: 547 if (className == null) { 548 assembler.loadStaticField 549 (fieldName, (TypeDescriptor)type); 550 } 551 else { 552 assembler.loadStaticField 553 (className, fieldName, (TypeDescriptor)type); 554 } 555 break; 556 case Opcode.PUTSTATIC: 557 if (className == null) { 558 assembler.storeStaticField 559 (fieldName, (TypeDescriptor)type); 560 } 561 else { 562 assembler.storeStaticField 563 (className, fieldName, (TypeDescriptor)type); 564 } 565 break; 566 case Opcode.GETFIELD: 567 if (className == null) { 568 assembler.loadField 569 (fieldName, (TypeDescriptor)type); 570 } 571 else { 572 assembler.loadField 573 (className, fieldName, (TypeDescriptor)type); 574 } 575 break; 576 case Opcode.PUTFIELD: 577 if (className == null) { 578 assembler.storeField 579 (fieldName, (TypeDescriptor)type); 580 } 581 else { 582 assembler.storeField 583 (className, fieldName, (TypeDescriptor)type); 584 } 585 break; 586 } 587 break; 588 589 case Opcode.INVOKEVIRTUAL: 590 case Opcode.INVOKESPECIAL: 591 case Opcode.INVOKESTATIC: 592 case Opcode.INVOKEINTERFACE: 593 ci = mCp.getConstant(readUnsignedShort()); 594 595 ConstantNameAndTypeInfo nameAndType; 596 597 if (opcode == Opcode.INVOKEINTERFACE) { 598 readShort(); 600 if (!(ci instanceof ConstantInterfaceMethodInfo)) { 601 break; 603 } 604 ConstantInterfaceMethodInfo method = 605 (ConstantInterfaceMethodInfo)ci; 606 className = method.getParentClass().getClassName(); 607 nameAndType = method.getNameAndType(); 608 } 609 else { 610 if (!(ci instanceof ConstantMethodInfo)) { 611 break; 613 } 614 ConstantMethodInfo method = 615 (ConstantMethodInfo)ci; 616 className = method.getParentClass().getClassName(); 617 if (mEnclosingClassName.equals(className)) { 618 className = null; 619 } 620 nameAndType = method.getNameAndType(); 621 } 622 623 String methodName = nameAndType.getName(); 624 type = nameAndType.getType(); 625 if (!(type instanceof MethodDescriptor)) { 626 break; 628 } 629 TypeDescriptor ret = ((MethodDescriptor)type).getReturnType(); 630 if (ret.getClassArg() == void.class) { 631 ret = null; 632 } 633 TypeDescriptor[] params = 634 ((MethodDescriptor)type).getParameterTypes(); 635 if (params.length == 0) { 636 params = null; 637 } 638 639 switch (opcode) { 640 case Opcode.INVOKEVIRTUAL: 641 if (className == null) { 642 assembler.invokeVirtual(methodName, ret, params); 643 } 644 else { 645 assembler.invokeVirtual 646 (className, methodName, ret, params); 647 } 648 break; 649 case Opcode.INVOKESPECIAL: 650 if ("<init>".equals(methodName)) { 651 if (className == null) { 652 assembler.invokeConstructor(params); 653 } 654 else { 655 if (className.equals(mSuperClassName)) { 656 assembler.invokeSuperConstructor(params); 657 } 658 else { 659 assembler.invokeConstructor(className, params); 660 } 661 } 662 } 663 else { 664 if (className == null) { 665 assembler.invokePrivate(methodName, ret, params); 666 } 667 else { 668 assembler.invokeSuper 669 (className, methodName, ret, params); 670 } 671 } 672 break; 673 case Opcode.INVOKESTATIC: 674 if (className == null) { 675 assembler.invokeStatic(methodName, ret, params); 676 } 677 else { 678 assembler.invokeStatic 679 (className, methodName, ret, params); 680 } 681 break; 682 case Opcode.INVOKEINTERFACE: 683 assembler.invokeInterface 684 (className, methodName, ret, params); 685 break; 686 } 687 break; 688 689 691 693 case Opcode.ILOAD: case Opcode.ISTORE: 694 case Opcode.LLOAD: case Opcode.LSTORE: 695 case Opcode.FLOAD: case Opcode.FSTORE: 696 case Opcode.DLOAD: case Opcode.DSTORE: 697 case Opcode.ALOAD: case Opcode.ASTORE: 698 case Opcode.ILOAD_0: case Opcode.ISTORE_0: 699 case Opcode.ILOAD_1: case Opcode.ISTORE_1: 700 case Opcode.ILOAD_2: case Opcode.ISTORE_2: 701 case Opcode.ILOAD_3: case Opcode.ISTORE_3: 702 case Opcode.LLOAD_0: case Opcode.LSTORE_0: 703 case Opcode.LLOAD_1: case Opcode.LSTORE_1: 704 case Opcode.LLOAD_2: case Opcode.LSTORE_2: 705 case Opcode.LLOAD_3: case Opcode.LSTORE_3: 706 case Opcode.FLOAD_0: case Opcode.FSTORE_0: 707 case Opcode.FLOAD_1: case Opcode.FSTORE_1: 708 case Opcode.FLOAD_2: case Opcode.FSTORE_2: 709 case Opcode.FLOAD_3: case Opcode.FSTORE_3: 710 case Opcode.DLOAD_0: case Opcode.DSTORE_0: 711 case Opcode.DLOAD_1: case Opcode.DSTORE_1: 712 case Opcode.DLOAD_2: case Opcode.DSTORE_2: 713 case Opcode.DLOAD_3: case Opcode.DSTORE_3: 714 case Opcode.ALOAD_0: case Opcode.ASTORE_0: 715 case Opcode.ALOAD_1: case Opcode.ASTORE_1: 716 case Opcode.ALOAD_2: case Opcode.ASTORE_2: 717 case Opcode.ALOAD_3: case Opcode.ASTORE_3: 718 switch (opcode) { 719 case Opcode.ILOAD: case Opcode.ISTORE: 720 index = readUnsignedByte(); 721 clazz = int.class; 722 break; 723 case Opcode.LLOAD: case Opcode.LSTORE: 724 index = readUnsignedByte(); 725 clazz = long.class; 726 break; 727 case Opcode.FLOAD: case Opcode.FSTORE: 728 index = readUnsignedByte(); 729 clazz = float.class; 730 break; 731 case Opcode.DLOAD: case Opcode.DSTORE: 732 index = readUnsignedByte(); 733 clazz = double.class; 734 break; 735 case Opcode.ALOAD: case Opcode.ASTORE: 736 index = readUnsignedByte(); 737 clazz = Object .class; 738 break; 739 case Opcode.ILOAD_0: case Opcode.ISTORE_0: 740 index = 0; 741 clazz = int.class; 742 break; 743 case Opcode.ILOAD_1: case Opcode.ISTORE_1: 744 index = 1; 745 clazz = int.class; 746 break; 747 case Opcode.ILOAD_2: case Opcode.ISTORE_2: 748 index = 2; 749 clazz = int.class; 750 break; 751 case Opcode.ILOAD_3: case Opcode.ISTORE_3: 752 index = 3; 753 clazz = int.class; 754 break; 755 case Opcode.LLOAD_0: case Opcode.LSTORE_0: 756 index = 0; 757 clazz = long.class; 758 break; 759 case Opcode.LLOAD_1: case Opcode.LSTORE_1: 760 index = 1; 761 clazz = long.class; 762 break; 763 case Opcode.LLOAD_2: case Opcode.LSTORE_2: 764 index = 2; 765 clazz = long.class; 766 break; 767 case Opcode.LLOAD_3: case Opcode.LSTORE_3: 768 index = 3; 769 clazz = long.class; 770 break; 771 case Opcode.FLOAD_0: case Opcode.FSTORE_0: 772 index = 0; 773 clazz = float.class; 774 break; 775 case Opcode.FLOAD_1: case Opcode.FSTORE_1: 776 index = 1; 777 clazz = float.class; 778 break; 779 case Opcode.FLOAD_2: case Opcode.FSTORE_2: 780 index = 2; 781 clazz = float.class; 782 break; 783 case Opcode.FLOAD_3: case Opcode.FSTORE_3: 784 index = 3; 785 clazz = float.class; 786 break; 787 case Opcode.DLOAD_0: case Opcode.DSTORE_0: 788 index = 0; 789 clazz = double.class; 790 break; 791 case Opcode.DLOAD_1: case Opcode.DSTORE_1: 792 index = 1; 793 clazz = double.class; 794 break; 795 case Opcode.DLOAD_2: case Opcode.DSTORE_2: 796 index = 2; 797 clazz = double.class; 798 break; 799 case Opcode.DLOAD_3: case Opcode.DSTORE_3: 800 index = 3; 801 clazz = double.class; 802 break; 803 case Opcode.ALOAD_0: case Opcode.ASTORE_0: 804 index = 0; 805 clazz = Object .class; 806 break; 807 case Opcode.ALOAD_1: case Opcode.ASTORE_1: 808 index = 1; 809 clazz = Object .class; 810 break; 811 case Opcode.ALOAD_2: case Opcode.ASTORE_2: 812 index = 2; 813 clazz = Object .class; 814 break; 815 case Opcode.ALOAD_3: case Opcode.ASTORE_3: 816 index = 3; 817 clazz = Object .class; 818 break; 819 default: 820 index = 0; 821 clazz = null; 822 break; 823 } 824 825 switch (opcode) { 826 case Opcode.ILOAD: 827 case Opcode.LLOAD: 828 case Opcode.FLOAD: 829 case Opcode.DLOAD: 830 case Opcode.ALOAD: 831 case Opcode.ILOAD_0: 832 case Opcode.ILOAD_1: 833 case Opcode.ILOAD_2: 834 case Opcode.ILOAD_3: 835 case Opcode.LLOAD_0: 836 case Opcode.LLOAD_1: 837 case Opcode.LLOAD_2: 838 case Opcode.LLOAD_3: 839 case Opcode.FLOAD_0: 840 case Opcode.FLOAD_1: 841 case Opcode.FLOAD_2: 842 case Opcode.FLOAD_3: 843 case Opcode.DLOAD_0: 844 case Opcode.DLOAD_1: 845 case Opcode.DLOAD_2: 846 case Opcode.DLOAD_3: 847 case Opcode.ALOAD_0: 848 case Opcode.ALOAD_1: 849 case Opcode.ALOAD_2: 850 case Opcode.ALOAD_3: 851 if (index == 0 && mHasThis) { 852 assembler.loadThis(); 853 } 854 else { 855 assembler.loadLocal(getLocalVariable(index, clazz)); 856 } 857 break; 858 case Opcode.ISTORE: 859 case Opcode.LSTORE: 860 case Opcode.FSTORE: 861 case Opcode.DSTORE: 862 case Opcode.ASTORE: 863 case Opcode.ISTORE_0: 864 case Opcode.ISTORE_1: 865 case Opcode.ISTORE_2: 866 case Opcode.ISTORE_3: 867 case Opcode.LSTORE_0: 868 case Opcode.LSTORE_1: 869 case Opcode.LSTORE_2: 870 case Opcode.LSTORE_3: 871 case Opcode.FSTORE_0: 872 case Opcode.FSTORE_1: 873 case Opcode.FSTORE_2: 874 case Opcode.FSTORE_3: 875 case Opcode.DSTORE_0: 876 case Opcode.DSTORE_1: 877 case Opcode.DSTORE_2: 878 case Opcode.DSTORE_3: 879 case Opcode.ASTORE_0: 880 case Opcode.ASTORE_1: 881 case Opcode.ASTORE_2: 882 case Opcode.ASTORE_3: 883 if (index == 0 && mHasThis) { 884 mHasThis = false; 886 } 887 assembler.storeLocal(getLocalVariable(index, clazz)); 888 break; 889 } 890 break; 891 892 case Opcode.RET: 893 LocalVariable local = getLocalVariable 894 (readUnsignedByte(), Object .class); 895 assembler.ret(local); 896 break; 897 898 case Opcode.IINC: 899 local = getLocalVariable(readUnsignedByte(), int.class); 900 assembler.integerIncrement(local, readByte()); 901 break; 902 903 905 907 case Opcode.GOTO: 908 loc = getLabel(mAddress + readShort()); 909 assembler.branch(loc); 910 break; 911 case Opcode.JSR: 912 loc = getLabel(mAddress + readShort()); 913 assembler.jsr(loc); 914 break; 915 case Opcode.GOTO_W: 916 loc = getLabel(mAddress + readInt()); 917 assembler.branch(loc); 918 break; 919 case Opcode.JSR_W: 920 loc = getLabel(mAddress + readInt()); 921 assembler.jsr(loc); 922 break; 923 924 case Opcode.IFNULL: 925 loc = getLabel(mAddress + readShort()); 926 assembler.ifNullBranch(loc, true); 927 break; 928 case Opcode.IFNONNULL: 929 loc = getLabel(mAddress + readShort()); 930 assembler.ifNullBranch(loc, false); 931 break; 932 933 case Opcode.IF_ACMPEQ: 934 loc = getLabel(mAddress + readShort()); 935 assembler.ifEqualBranch(loc, true); 936 break; 937 case Opcode.IF_ACMPNE: 938 loc = getLabel(mAddress + readShort()); 939 assembler.ifEqualBranch(loc, false); 940 break; 941 942 case Opcode.IFEQ: 943 case Opcode.IFNE: 944 case Opcode.IFLT: 945 case Opcode.IFGE: 946 case Opcode.IFGT: 947 case Opcode.IFLE: 948 loc = getLabel(mAddress + readShort()); 949 String choice; 950 switch (opcode) { 951 case Opcode.IFEQ: 952 choice = "=="; 953 break; 954 case Opcode.IFNE: 955 choice = "!="; 956 break; 957 case Opcode.IFLT: 958 choice = "<"; 959 break; 960 case Opcode.IFGE: 961 choice = ">="; 962 break; 963 case Opcode.IFGT: 964 choice = ">"; 965 break; 966 case Opcode.IFLE: 967 choice = "<="; 968 break; 969 default: 970 choice = null; 971 break; 972 } 973 assembler.ifZeroComparisonBranch(loc, choice); 974 break; 975 976 case Opcode.IF_ICMPEQ: 977 case Opcode.IF_ICMPNE: 978 case Opcode.IF_ICMPLT: 979 case Opcode.IF_ICMPGE: 980 case Opcode.IF_ICMPGT: 981 case Opcode.IF_ICMPLE: 982 loc = getLabel(mAddress + readShort()); 983 switch (opcode) { 984 case Opcode.IF_ICMPEQ: 985 choice = "=="; 986 break; 987 case Opcode.IF_ICMPNE: 988 choice = "!="; 989 break; 990 case Opcode.IF_ICMPLT: 991 choice = "<"; 992 break; 993 case Opcode.IF_ICMPGE: 994 choice = ">="; 995 break; 996 case Opcode.IF_ICMPGT: 997 choice = ">"; 998 break; 999 case Opcode.IF_ICMPLE: 1000 choice = "<="; 1001 break; 1002 default: 1003 choice = null; 1004 break; 1005 } 1006 assembler.ifComparisonBranch(loc, choice); 1007 break; 1008 1009 1011 1013 case Opcode.BIPUSH: 1014 assembler.loadConstant(readByte()); 1015 break; 1016 case Opcode.SIPUSH: 1017 assembler.loadConstant(readShort()); 1018 break; 1019 1020 case Opcode.NEWARRAY: 1021 int atype = readByte(); 1022 clazz = null; 1023 switch (atype) { 1024 case 4: clazz = boolean.class; 1026 break; 1027 case 5: clazz = char.class; 1029 break; 1030 case 6: clazz = float.class; 1032 break; 1033 case 7: clazz = double.class; 1035 break; 1036 case 8: clazz = byte.class; 1038 break; 1039 case 9: clazz = short.class; 1041 break; 1042 case 10: clazz = int.class; 1044 break; 1045 case 11: clazz = long.class; 1047 break; 1048 } 1049 1050 if (clazz == null) { 1051 break; 1053 } 1054 1055 assembler.newObject 1056 (new TypeDescriptor(new TypeDescriptor(clazz), 1)); 1057 break; 1058 1059 case Opcode.TABLESWITCH: 1060 case Opcode.LOOKUPSWITCH: 1061 int opcodeAddress = mAddress; 1062 while (((mAddress + 1) & 3) != 0) { 1064 ++mAddress; 1065 } 1066 Location defaultLocation = getLabel(opcodeAddress + readInt()); 1067 int[] cases; 1068 Location[] locations; 1069 1070 if (opcode == Opcode.TABLESWITCH) { 1071 int lowValue = readInt(); 1072 int highValue = readInt(); 1073 int caseCount = highValue - lowValue + 1; 1074 try { 1075 cases = new int[caseCount]; 1076 } 1077 catch (NegativeArraySizeException e) { 1078 break; 1080 } 1081 locations = new Location[caseCount]; 1082 for (int i=0; i<caseCount; i++) { 1083 cases[i] = lowValue + i; 1084 locations[i] = getLabel(opcodeAddress + readInt()); 1085 } 1086 } 1087 else { 1088 int caseCount = readInt(); 1089 try { 1090 cases = new int[caseCount]; 1091 } 1092 catch (NegativeArraySizeException e) { 1093 break; 1095 } 1096 locations = new Location[caseCount]; 1097 for (int i=0; i<caseCount; i++) { 1098 cases[i] = readInt(); 1099 locations[i] = getLabel(opcodeAddress + readInt()); 1100 } 1101 } 1102 1103 assembler.switchBranch(cases, locations, defaultLocation); 1104 break; 1105 1106 case Opcode.WIDE: 1107 opcode = mByteCodes[++mAddress]; 1108 switch (opcode) { 1109 1110 default: 1111 break; 1113 1114 case Opcode.ILOAD: case Opcode.ISTORE: 1115 case Opcode.LLOAD: case Opcode.LSTORE: 1116 case Opcode.FLOAD: case Opcode.FSTORE: 1117 case Opcode.DLOAD: case Opcode.DSTORE: 1118 case Opcode.ALOAD: case Opcode.ASTORE: 1119 1120 switch (opcode) { 1121 case Opcode.ILOAD: case Opcode.ISTORE: 1122 clazz = int.class; 1123 break; 1124 case Opcode.LLOAD: case Opcode.LSTORE: 1125 clazz = long.class; 1126 break; 1127 case Opcode.FLOAD: case Opcode.FSTORE: 1128 clazz = float.class; 1129 break; 1130 case Opcode.DLOAD: case Opcode.DSTORE: 1131 clazz = double.class; 1132 break; 1133 case Opcode.ALOAD: case Opcode.ASTORE: 1134 clazz = Object .class; 1135 break; 1136 default: 1137 clazz = null; 1138 break; 1139 } 1140 1141 index = readUnsignedShort(); 1142 1143 switch (opcode) { 1144 case Opcode.ILOAD: 1145 case Opcode.LLOAD: 1146 case Opcode.FLOAD: 1147 case Opcode.DLOAD: 1148 case Opcode.ALOAD: 1149 if (index == 0 && mHasThis) { 1150 assembler.loadThis(); 1151 } 1152 else { 1153 assembler.loadLocal 1154 (getLocalVariable(index, clazz)); 1155 } 1156 break; 1157 case Opcode.ISTORE: 1158 case Opcode.LSTORE: 1159 case Opcode.FSTORE: 1160 case Opcode.DSTORE: 1161 case Opcode.ASTORE: 1162 if (index == 0 && mHasThis) { 1163 mHasThis = false; 1165 } 1166 assembler.storeLocal(getLocalVariable(index, clazz)); 1167 break; 1168 } 1169 break; 1170 1171 case Opcode.RET: 1172 local = getLocalVariable 1173 (readUnsignedShort(), Object .class); 1174 assembler.ret(local); 1175 break; 1176 1177 case Opcode.IINC: 1178 local = getLocalVariable(readUnsignedShort(), int.class); 1179 assembler.integerIncrement(local, readShort()); 1180 break; 1181 } 1182 1183 break; 1184 } } } 1187 1188 private void gatherLabels() { 1189 mLabels = new HashMap(); 1190 mCatchLocations = new HashMap(mExceptionHandlers.length * 2 + 1); 1191 Integer labelKey; 1192 1193 for (int i = mExceptionHandlers.length - 1; i >= 0; i--) { 1195 ExceptionHandler handler = mExceptionHandlers[i]; 1196 labelKey = new Integer (handler.getStartLocation().getLocation()); 1197 mLabels.put(labelKey, labelKey); 1198 labelKey = new Integer (handler.getEndLocation().getLocation()); 1199 mLabels.put(labelKey, labelKey); 1200 labelKey = new Integer (handler.getCatchLocation().getLocation()); 1201 List list = (List)mCatchLocations.get(labelKey); 1202 if (list == null) { 1203 list = new ArrayList(2); 1204 mCatchLocations.put(labelKey, list); 1205 } 1206 list.add(handler); 1207 } 1208 1209 for (mAddress = 0; mAddress < mByteCodes.length; mAddress++) { 1211 byte opcode = mByteCodes[mAddress]; 1212 1213 switch (opcode) { 1214 1215 default: 1216 break; 1218 1219 1221 case Opcode.GOTO: 1222 case Opcode.JSR: 1223 case Opcode.IFNULL: 1224 case Opcode.IFNONNULL: 1225 case Opcode.IF_ACMPEQ: 1226 case Opcode.IF_ACMPNE: 1227 case Opcode.IFEQ: 1228 case Opcode.IFNE: 1229 case Opcode.IFLT: 1230 case Opcode.IFGE: 1231 case Opcode.IFGT: 1232 case Opcode.IFLE: 1233 case Opcode.IF_ICMPEQ: 1234 case Opcode.IF_ICMPNE: 1235 case Opcode.IF_ICMPLT: 1236 case Opcode.IF_ICMPGE: 1237 case Opcode.IF_ICMPGT: 1238 case Opcode.IF_ICMPLE: 1239 labelKey = new Integer (mAddress + readShort()); 1240 mLabels.put(labelKey, labelKey); 1241 break; 1242 1243 case Opcode.GOTO_W: 1244 case Opcode.JSR_W: 1245 labelKey = new Integer (mAddress + readInt()); 1246 mLabels.put(labelKey, labelKey); 1247 break; 1248 1249 case Opcode.TABLESWITCH: 1250 case Opcode.LOOKUPSWITCH: 1251 int opcodeAddress = mAddress; 1252 while (((mAddress + 1) & 3) != 0) { 1254 ++mAddress; 1255 } 1256 1257 labelKey = new Integer (opcodeAddress + readInt()); 1259 mLabels.put(labelKey, labelKey); 1260 1261 if (opcode == Opcode.TABLESWITCH) { 1262 int lowValue = readInt(); 1263 int highValue = readInt(); 1264 int caseCount = highValue - lowValue + 1; 1265 1266 for (int i=0; i<caseCount; i++) { 1267 labelKey = new Integer (opcodeAddress + readInt()); 1269 mLabels.put(labelKey, labelKey); 1270 } 1271 } 1272 else { 1273 int caseCount = readInt(); 1274 1275 for (int i=0; i<caseCount; i++) { 1276 mAddress += 4; 1278 labelKey = new Integer (opcodeAddress + readInt()); 1280 mLabels.put(labelKey, labelKey); 1281 } 1282 } 1283 break; 1284 1285 1288 1290 case Opcode.NOP: 1291 case Opcode.BREAKPOINT: 1292 case Opcode.ACONST_NULL: 1293 case Opcode.ICONST_M1: 1294 case Opcode.ICONST_0: 1295 case Opcode.ICONST_1: 1296 case Opcode.ICONST_2: 1297 case Opcode.ICONST_3: 1298 case Opcode.ICONST_4: 1299 case Opcode.ICONST_5: 1300 case Opcode.LCONST_0: 1301 case Opcode.LCONST_1: 1302 case Opcode.FCONST_0: 1303 case Opcode.FCONST_1: 1304 case Opcode.FCONST_2: 1305 case Opcode.DCONST_0: 1306 case Opcode.DCONST_1: 1307 case Opcode.POP: 1308 case Opcode.POP2: 1309 case Opcode.DUP: 1310 case Opcode.DUP_X1: 1311 case Opcode.DUP_X2: 1312 case Opcode.DUP2: 1313 case Opcode.DUP2_X1: 1314 case Opcode.DUP2_X2: 1315 case Opcode.SWAP: 1316 case Opcode.IADD: case Opcode.LADD: 1317 case Opcode.FADD: case Opcode.DADD: 1318 case Opcode.ISUB: case Opcode.LSUB: 1319 case Opcode.FSUB: case Opcode.DSUB: 1320 case Opcode.IMUL: case Opcode.LMUL: 1321 case Opcode.FMUL: case Opcode.DMUL: 1322 case Opcode.IDIV: case Opcode.LDIV: 1323 case Opcode.FDIV: case Opcode.DDIV: 1324 case Opcode.IREM: case Opcode.LREM: 1325 case Opcode.FREM: case Opcode.DREM: 1326 case Opcode.INEG: case Opcode.LNEG: 1327 case Opcode.FNEG: case Opcode.DNEG: 1328 case Opcode.ISHL: case Opcode.LSHL: 1329 case Opcode.ISHR: case Opcode.LSHR: 1330 case Opcode.IUSHR: case Opcode.LUSHR: 1331 case Opcode.IAND: case Opcode.LAND: 1332 case Opcode.IOR: case Opcode.LOR: 1333 case Opcode.IXOR: case Opcode.LXOR: 1334 case Opcode.FCMPL: case Opcode.DCMPL: 1335 case Opcode.FCMPG: case Opcode.DCMPG: 1336 case Opcode.LCMP: 1337 case Opcode.I2L: 1338 case Opcode.I2F: 1339 case Opcode.I2D: 1340 case Opcode.L2I: 1341 case Opcode.L2F: 1342 case Opcode.L2D: 1343 case Opcode.F2I: 1344 case Opcode.F2L: 1345 case Opcode.F2D: 1346 case Opcode.D2I: 1347 case Opcode.D2L: 1348 case Opcode.D2F: 1349 case Opcode.I2B: 1350 case Opcode.I2C: 1351 case Opcode.I2S: 1352 case Opcode.IRETURN: 1353 case Opcode.LRETURN: 1354 case Opcode.FRETURN: 1355 case Opcode.DRETURN: 1356 case Opcode.ARETURN: 1357 case Opcode.RETURN: 1358 case Opcode.IALOAD: 1359 case Opcode.LALOAD: 1360 case Opcode.FALOAD: 1361 case Opcode.DALOAD: 1362 case Opcode.AALOAD: 1363 case Opcode.BALOAD: 1364 case Opcode.CALOAD: 1365 case Opcode.SALOAD: 1366 case Opcode.IASTORE: 1367 case Opcode.LASTORE: 1368 case Opcode.FASTORE: 1369 case Opcode.DASTORE: 1370 case Opcode.AASTORE: 1371 case Opcode.BASTORE: 1372 case Opcode.CASTORE: 1373 case Opcode.SASTORE: 1374 case Opcode.ARRAYLENGTH: 1375 case Opcode.ATHROW: 1376 case Opcode.MONITORENTER: 1377 case Opcode.MONITOREXIT: 1378 case Opcode.ILOAD_0: case Opcode.ISTORE_0: 1379 case Opcode.ILOAD_1: case Opcode.ISTORE_1: 1380 case Opcode.ILOAD_2: case Opcode.ISTORE_2: 1381 case Opcode.ILOAD_3: case Opcode.ISTORE_3: 1382 case Opcode.LLOAD_0: case Opcode.LSTORE_0: 1383 case Opcode.LLOAD_1: case Opcode.LSTORE_1: 1384 case Opcode.LLOAD_2: case Opcode.LSTORE_2: 1385 case Opcode.LLOAD_3: case Opcode.LSTORE_3: 1386 case Opcode.FLOAD_0: case Opcode.FSTORE_0: 1387 case Opcode.FLOAD_1: case Opcode.FSTORE_1: 1388 case Opcode.FLOAD_2: case Opcode.FSTORE_2: 1389 case Opcode.FLOAD_3: case Opcode.FSTORE_3: 1390 case Opcode.DLOAD_0: case Opcode.DSTORE_0: 1391 case Opcode.DLOAD_1: case Opcode.DSTORE_1: 1392 case Opcode.DLOAD_2: case Opcode.DSTORE_2: 1393 case Opcode.DLOAD_3: case Opcode.DSTORE_3: 1394 case Opcode.ALOAD_0: case Opcode.ASTORE_0: 1395 case Opcode.ALOAD_1: case Opcode.ASTORE_1: 1396 case Opcode.ALOAD_2: case Opcode.ASTORE_2: 1397 case Opcode.ALOAD_3: case Opcode.ASTORE_3: 1398 break; 1399 1400 1402 case Opcode.LDC: 1403 case Opcode.ILOAD: case Opcode.ISTORE: 1404 case Opcode.LLOAD: case Opcode.LSTORE: 1405 case Opcode.FLOAD: case Opcode.FSTORE: 1406 case Opcode.DLOAD: case Opcode.DSTORE: 1407 case Opcode.ALOAD: case Opcode.ASTORE: 1408 case Opcode.RET: 1409 case Opcode.IINC: 1410 case Opcode.BIPUSH: 1411 case Opcode.NEWARRAY: 1412 mAddress += 1; 1413 break; 1414 1415 1417 case Opcode.LDC_W: 1418 case Opcode.LDC2_W: 1419 case Opcode.NEW: 1420 case Opcode.ANEWARRAY: 1421 case Opcode.CHECKCAST: 1422 case Opcode.INSTANCEOF: 1423 case Opcode.GETSTATIC: 1424 case Opcode.PUTSTATIC: 1425 case Opcode.GETFIELD: 1426 case Opcode.PUTFIELD: 1427 case Opcode.INVOKEVIRTUAL: 1428 case Opcode.INVOKESPECIAL: 1429 case Opcode.INVOKESTATIC: 1430 case Opcode.SIPUSH: 1431 mAddress += 2; 1432 break; 1433 1434 1436 case Opcode.MULTIANEWARRAY: 1437 mAddress += 3; 1438 break; 1439 1440 1442 case Opcode.INVOKEINTERFACE: 1443 mAddress += 4; 1444 break; 1445 1446 1448 case Opcode.WIDE: 1449 opcode = mByteCodes[++mAddress]; 1450 mAddress += 2; 1451 if (opcode == Opcode.IINC) { 1452 mAddress += 2; 1453 } 1454 break; 1455 } } } 1458 1459 private int readByte() { 1460 return mByteCodes[++mAddress]; 1461 } 1462 1463 private int readUnsignedByte() { 1464 return mByteCodes[++mAddress] & 0xff; 1465 } 1466 1467 private int readShort() { 1468 return (mByteCodes[++mAddress] << 8) | (mByteCodes[++mAddress] & 0xff); 1469 } 1470 1471 private int readUnsignedShort() { 1472 return 1473 ((mByteCodes[++mAddress] & 0xff) << 8) | 1474 ((mByteCodes[++mAddress] & 0xff) << 0); 1475 } 1476 1477 private int readInt() { 1478 return 1479 (mByteCodes[++mAddress] << 24) | 1480 ((mByteCodes[++mAddress] & 0xff) << 16) | 1481 ((mByteCodes[++mAddress] & 0xff) << 8) | 1482 ((mByteCodes[++mAddress] & 0xff) << 0); 1483 } 1484 1485 private LocalVariable getLocalVariable(int index, Class typeHint) { 1486 TypeDescriptor type = new TypeDescriptor(typeHint); 1487 LocalVariable local; 1488 1489 if (index >= mLocals.size()) { 1490 mLocals.setSize(index + 1); 1491 local = null; 1492 } 1493 else { 1494 local = (LocalVariable)mLocals.elementAt(index); 1495 if (local != null) { 1496 TypeDescriptor localType = local.getType(); 1497 Class typeClass = type.getClassArg(); 1498 Class localTypeClass = localType.getClassArg(); 1499 1500 if (typeClass != null && !typeClass.isPrimitive()) { 1501 typeClass = null; 1502 } 1503 1504 if (localTypeClass != null && !localTypeClass.isPrimitive()) { 1505 localTypeClass = null; 1506 } 1507 1508 if (typeClass == null) { 1509 if (localTypeClass == null) { 1510 } 1512 else { 1513 local = null; 1515 } 1516 } 1517 else { 1518 if (localTypeClass == null) { 1519 local = null; 1521 } 1522 else { 1523 if (typeClass != localTypeClass) { 1525 local = null; 1526 } 1527 } 1528 } 1529 } 1530 } 1531 1532 if (local == null) { 1533 local = mAssembler.createLocalVariable(null, type); 1534 mLocals.setElementAt(local, index); 1535 } 1536 1537 return local; 1538 } 1539 1540 private void locateLabel() { 1541 Integer labelKey = new Integer (mAddress); 1542 Object labelValue = mLabels.get(labelKey); 1543 if (labelValue != null) { 1544 if (labelValue instanceof Label) { 1545 ((Label)labelValue).setLocation(); 1546 } 1547 else { 1548 labelValue = mAssembler.createLabel().setLocation(); 1549 mLabels.put(labelKey, labelValue); 1550 } 1551 } 1552 1553 List handlers = (List)mCatchLocations.get(labelKey); 1554 1555 if (handlers != null) { 1556 for (int i=0; i<handlers.size(); i++) { 1557 ExceptionHandler handler = (ExceptionHandler)handlers.get(i); 1558 Label start = 1559 getLabel(handler.getStartLocation().getLocation()); 1560 Label end = 1561 getLabel(handler.getEndLocation().getLocation()); 1562 String catchClassName; 1563 if (handler.getCatchType() == null) { 1564 catchClassName = null; 1565 } 1566 else { 1567 catchClassName = handler.getCatchType().getClassName(); 1568 } 1569 mAssembler.exceptionHandler(start, end, catchClassName); 1570 } 1571 } 1572 } 1573 1574 private Label getLabel(int address) { 1575 Integer labelKey = new Integer (address); 1576 Object labelValue = mLabels.get(labelKey); 1577 if (!(labelValue instanceof Label)) { 1579 labelValue = mAssembler.createLabel(); 1580 mLabels.put(labelKey, labelValue); 1581 } 1582 return (Label)labelValue; 1583 } 1584} 1585 | Popular Tags |