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