429 assert(l > 0); 430 return l; 431 } 432 public static int opWideLength(int bc) { 433 int l = BC_LENGTH[1][bc]; 434 assert(l > 0); 435 return l; 436 } 437 438 public static boolean isLocalSlotOp(int bc) { 439 return (bc < BC_SLOT[0].length && BC_SLOT[0][bc] > 0); 440 } 441 442 public static boolean isBranchOp(int bc) { 443 return (bc < BC_BRANCH[0].length && BC_BRANCH[0][bc] > 0); 444 } 445 446 public static boolean isCPRefOp(int bc) { 447 if (bc < BC_INDEX[0].length && BC_INDEX[0][bc] > 0) return true; 448 if (bc >= _xldc_op && bc < _xldc_limit) return true; 449 return false; 450 } 451 452 public static byte getCPRefOpTag(int bc) { 453 if (bc < BC_INDEX[0].length && BC_INDEX[0][bc] > 0) return BC_TAG[0][bc]; 454 if (bc >= _xldc_op && bc < _xldc_limit) return CONSTANT_LoadableValue; 455 return CONSTANT_None; 456 } 457 458 public static boolean isFieldOp(int bc) { 459 return (bc >= _getstatic && bc <= _putfield); 460 } 461 462 public static boolean isInvokeInitOp(int bc) { 463 return (bc >= _invokeinit_op && bc < _invokeinit_limit); 464 } 465 466 public static boolean isSelfLinkerOp(int bc) { 467 return (bc >= _self_linker_op && bc < _self_linker_limit); 468 } 469 470 /// Format definitions. 471 472 static private final byte[][] BC_LENGTH = new byte[2][0x100]; 473 static private final byte[][] BC_INDEX = new byte[2][0x100]; 474 static private final byte[][] BC_TAG = new byte[2][0x100]; 630 assert(from_bc == _ldc); 631 tag = CONSTANT_LoadableValue; // _ldc opcode only 632 } 633 for (int bc = from_bc; bc <= to_bc; bc++) { 634 BC_FORMAT[w][bc] = fmt; 635 assert(BC_LENGTH[w][bc] == -1); 636 BC_LENGTH[w][bc] = (byte) length; 637 BC_INDEX[w][bc] = (byte) index; 638 BC_TAG[w][bc] = (byte) tag; 639 assert(!(index == 0 && tag != CONSTANT_None)); 640 BC_BRANCH[w][bc] = (byte) branch; 641 BC_SLOT[w][bc] = (byte) slot; 642 assert(branch == 0 || slot == 0); // not both branch & local 643 assert(branch == 0 || index == 0); // not both branch & cp 644 assert(slot == 0 || index == 0); // not both local & cp 645 BC_CON[w][bc] = (byte) con; 646 } 647 } 648 } 649 650 public static void opcodeChecker(byte[] code, ConstantPool.Entry[] cpMap) throws FormatException { 651 Instruction i = at(code, 0); 652 while (i != null) { 653 int opcode = i.getBC(); 654 if (opcode < _nop || opcode > _jsr_w) { 655 String message = "illegal opcode: " + opcode + " " + i; 656 throw new FormatException(message); 657 } 658 ConstantPool.Entry e = i.getCPRef(cpMap); 659 if (e != null) { 660 byte tag = i.getCPTag(); 661 if (!e.tagMatches(tag)) { 662 String message = "illegal reference, expected type=" + 663 ConstantPool.tagName(tag) + ": " + 664 i.toString(cpMap); 665 throw new FormatException(message); 666 } 667 } 668 i = i.next(); 669 } 670 } 671 static class FormatException extends IOException { 672 private static final long serialVersionUID = 3175572275651367015L; 673 674 FormatException(String message) { 675 super(message); 676 } 677 } 678 } | 429 assert(l > 0); 430 return l; 431 } 432 public static int opWideLength(int bc) { 433 int l = BC_LENGTH[1][bc]; 434 assert(l > 0); 435 return l; 436 } 437 438 public static boolean isLocalSlotOp(int bc) { 439 return (bc < BC_SLOT[0].length && BC_SLOT[0][bc] > 0); 440 } 441 442 public static boolean isBranchOp(int bc) { 443 return (bc < BC_BRANCH[0].length && BC_BRANCH[0][bc] > 0); 444 } 445 446 public static boolean isCPRefOp(int bc) { 447 if (bc < BC_INDEX[0].length && BC_INDEX[0][bc] > 0) return true; 448 if (bc >= _xldc_op && bc < _xldc_limit) return true; 449 if (bc == _invokespecial_int || bc == _invokestatic_int) return true; 450 return false; 451 } 452 453 public static byte getCPRefOpTag(int bc) { 454 if (bc < BC_INDEX[0].length && BC_INDEX[0][bc] > 0) return BC_TAG[0][bc]; 455 if (bc >= _xldc_op && bc < _xldc_limit) return CONSTANT_LoadableValue; 456 if (bc == _invokestatic_int || bc == _invokespecial_int) return CONSTANT_InterfaceMethodref; 457 return CONSTANT_None; 458 } 459 460 public static boolean isFieldOp(int bc) { 461 return (bc >= _getstatic && bc <= _putfield); 462 } 463 464 public static boolean isInvokeInitOp(int bc) { 465 return (bc >= _invokeinit_op && bc < _invokeinit_limit); 466 } 467 468 public static boolean isSelfLinkerOp(int bc) { 469 return (bc >= _self_linker_op && bc < _self_linker_limit); 470 } 471 472 /// Format definitions. 473 474 static private final byte[][] BC_LENGTH = new byte[2][0x100]; 475 static private final byte[][] BC_INDEX = new byte[2][0x100]; 476 static private final byte[][] BC_TAG = new byte[2][0x100]; 632 assert(from_bc == _ldc); 633 tag = CONSTANT_LoadableValue; // _ldc opcode only 634 } 635 for (int bc = from_bc; bc <= to_bc; bc++) { 636 BC_FORMAT[w][bc] = fmt; 637 assert(BC_LENGTH[w][bc] == -1); 638 BC_LENGTH[w][bc] = (byte) length; 639 BC_INDEX[w][bc] = (byte) index; 640 BC_TAG[w][bc] = (byte) tag; 641 assert(!(index == 0 && tag != CONSTANT_None)); 642 BC_BRANCH[w][bc] = (byte) branch; 643 BC_SLOT[w][bc] = (byte) slot; 644 assert(branch == 0 || slot == 0); // not both branch & local 645 assert(branch == 0 || index == 0); // not both branch & cp 646 assert(slot == 0 || index == 0); // not both local & cp 647 BC_CON[w][bc] = (byte) con; 648 } 649 } 650 } 651 652 public static void opcodeChecker(byte[] code, ConstantPool.Entry[] cpMap, 653 Package.Version clsVersion) throws FormatException { 654 Instruction i = at(code, 0); 655 while (i != null) { 656 int opcode = i.getBC(); 657 if (opcode < _nop || opcode > _jsr_w) { 658 String message = "illegal opcode: " + opcode + " " + i; 659 throw new FormatException(message); 660 } 661 ConstantPool.Entry e = i.getCPRef(cpMap); 662 if (e != null) { 663 byte tag = i.getCPTag(); 664 boolean match = e.tagMatches(tag); 665 if (!match && 666 (i.bc == _invokespecial || i.bc == _invokestatic) && 667 e.tagMatches(CONSTANT_InterfaceMethodref) && 668 clsVersion.greaterThan(Constants.JAVA7_MAX_CLASS_VERSION)) { 669 match = true; 670 } 671 if (!match) { 672 String message = "illegal reference, expected type=" 673 + ConstantPool.tagName(tag) + ": " 674 + i.toString(cpMap); 675 throw new FormatException(message); 676 } 677 } 678 i = i.next(); 679 } 680 } 681 static class FormatException extends IOException { 682 private static final long serialVersionUID = 3175572275651367015L; 683 684 FormatException(String message) { 685 super(message); 686 } 687 } 688 } |