446 |
461 |
447 maybe_inline |
462 maybe_inline |
448 int unpacker::putref_index(entry* e, int size) { |
463 int unpacker::putref_index(entry* e, int size) { |
449 if (e == null) |
464 if (e == null) |
450 return 0; |
465 return 0; |
451 else if (e->outputIndex > NOT_REQUESTED) |
466 else if (e->outputIndex > REQUESTED_NONE) |
452 return e->outputIndex; |
467 return e->outputIndex; |
453 else if (e->tag == CONSTANT_Signature) |
468 else if (e->tag == CONSTANT_Signature) |
454 return putref_index(e->ref(0), size); |
469 return putref_index(e->ref(0), size); |
455 else { |
470 else { |
456 e->requestOutputIndex(cp, -size); |
471 e->requestOutputIndex(cp, (size == 1 ? REQUESTED_LDC : REQUESTED)); |
457 // Later on we'll fix the bits. |
472 // Later on we'll fix the bits. |
458 class_fixup_type.addByte(size); |
473 class_fixup_type.addByte(size); |
459 class_fixup_offset.add((int)wpoffset()); |
474 class_fixup_offset.add((int)wpoffset()); |
460 class_fixup_ref.add(e); |
475 class_fixup_ref.add(e); |
461 #ifdef PRODUCT |
476 #ifdef PRODUCT |
513 } |
528 } |
514 b.len = len; |
529 b.len = len; |
515 b.copyFrom(ptr, len); |
530 b.copyFrom(ptr, len); |
516 } |
531 } |
517 |
532 |
|
533 bool testBit(int archive_options, int bitMask) { |
|
534 return (archive_options & bitMask) != 0; |
|
535 } |
|
536 |
518 // Read up through band_headers. |
537 // Read up through band_headers. |
519 // Do the archive_size dance to set the size of the input mega-buffer. |
538 // Do the archive_size dance to set the size of the input mega-buffer. |
520 void unpacker::read_file_header() { |
539 void unpacker::read_file_header() { |
521 // Read file header to determine file type and total size. |
540 // Read file header to determine file type and total size. |
522 enum { |
541 enum { |
523 MAGIC_BYTES = 4, |
542 MAGIC_BYTES = 4, |
524 AH_LENGTH_0 = 3, //minver, majver, options are outside of archive_size |
543 AH_LENGTH_0 = 3, // archive_header_0 = {minver, majver, options} |
|
544 AH_LENGTH_MIN = 15, // observed in spec {header_0[3], cp_counts[8], class_counts[4]} |
525 AH_LENGTH_0_MAX = AH_LENGTH_0 + 1, // options might have 2 bytes |
545 AH_LENGTH_0_MAX = AH_LENGTH_0 + 1, // options might have 2 bytes |
526 AH_LENGTH = 26, //maximum archive header length (w/ all fields) |
546 AH_LENGTH = 30, //maximum archive header length (w/ all fields) |
527 // Length contributions from optional header fields: |
547 // Length contributions from optional header fields: |
528 AH_FILE_HEADER_LEN = 5, // sizehi/lo/next/modtime/files |
548 AH_LENGTH_S = 2, // archive_header_S = optional {size_hi, size_lo} |
529 AH_ARCHIVE_SIZE_LEN = 2, // sizehi/lo only; part of AH_FILE_HEADER_LEN |
549 AH_ARCHIVE_SIZE_HI = 0, // offset in archive_header_S |
530 AH_CP_NUMBER_LEN = 4, // int/float/long/double |
550 AH_ARCHIVE_SIZE_LO = 1, // offset in archive_header_S |
531 AH_SPECIAL_FORMAT_LEN = 2, // layouts/band-headers |
551 AH_FILE_HEADER_LEN = 5, // file_counts = {{size_hi, size_lo), next, modtile, files} |
532 AH_LENGTH_MIN = AH_LENGTH |
552 AH_SPECIAL_FORMAT_LEN = 2, // special_count = {layouts, band_headers} |
533 -(AH_FILE_HEADER_LEN+AH_SPECIAL_FORMAT_LEN+AH_CP_NUMBER_LEN), |
553 AH_CP_NUMBER_LEN = 4, // cp_number_counts = {int, float, long, double} |
534 ARCHIVE_SIZE_MIN = AH_LENGTH_MIN - (AH_LENGTH_0 + AH_ARCHIVE_SIZE_LEN), |
554 AH_CP_EXTRA_LEN = 4, // cp_attr_counts = {MH, MT, InDy, BSM} |
|
555 ARCHIVE_SIZE_MIN = AH_LENGTH_MIN - AH_LENGTH_0 - AH_LENGTH_S, |
535 FIRST_READ = MAGIC_BYTES + AH_LENGTH_MIN |
556 FIRST_READ = MAGIC_BYTES + AH_LENGTH_MIN |
536 }; |
557 }; |
537 |
558 |
538 assert(AH_LENGTH_MIN == 15); // # of UNSIGNED5 fields required after archive_magic |
559 assert(AH_LENGTH_MIN == 15); // # of UNSIGNED5 fields required after archive_magic |
539 assert(ARCHIVE_SIZE_MIN == 10); // # of UNSIGNED5 fields required after archive_size |
|
540 // An absolute minimum null archive is magic[4], {minver,majver,options}[3], |
560 // An absolute minimum null archive is magic[4], {minver,majver,options}[3], |
541 // archive_size[0], cp_counts[8], class_counts[4], for a total of 19 bytes. |
561 // archive_size[0], cp_counts[8], class_counts[4], for a total of 19 bytes. |
542 // (Note that archive_size is optional; it may be 0..10 bytes in length.) |
562 // (Note that archive_size is optional; it may be 0..10 bytes in length.) |
543 // The first read must capture everything up through the options field. |
563 // The first read must capture everything up through the options field. |
544 // This happens to work even if {minver,majver,options} is a pathological |
564 // This happens to work even if {minver,majver,options} is a pathological |
620 } |
640 } |
621 |
641 |
622 // Read the first 3 values from the header. |
642 // Read the first 3 values from the header. |
623 value_stream hdr; |
643 value_stream hdr; |
624 int hdrVals = 0; |
644 int hdrVals = 0; |
625 int hdrValsSkipped = 0; // debug only |
645 int hdrValsSkipped = 0; // for assert |
626 hdr.init(rp, rplimit, UNSIGNED5_spec); |
646 hdr.init(rp, rplimit, UNSIGNED5_spec); |
627 minver = hdr.getInt(); |
647 minver = hdr.getInt(); |
628 majver = hdr.getInt(); |
648 majver = hdr.getInt(); |
629 hdrVals += 2; |
649 hdrVals += 2; |
630 |
650 |
631 if (magic != (int)JAVA_PACKAGE_MAGIC || |
651 int majmin[3][2] = { |
632 (majver != JAVA5_PACKAGE_MAJOR_VERSION && |
652 {JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION}, |
633 majver != JAVA6_PACKAGE_MAJOR_VERSION) || |
653 {JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION}, |
634 (minver != JAVA5_PACKAGE_MINOR_VERSION && |
654 {JAVA7_PACKAGE_MAJOR_VERSION, JAVA7_PACKAGE_MINOR_VERSION} |
635 minver != JAVA6_PACKAGE_MINOR_VERSION)) { |
655 }; |
|
656 int majminfound = false; |
|
657 for (int i = 0 ; i < 3 ; i++) { |
|
658 if (majver == majmin[i][0] && minver == majmin[i][1]) { |
|
659 majminfound = true; |
|
660 break; |
|
661 } |
|
662 } |
|
663 if (majminfound == null) { |
636 char message[200]; |
664 char message[200]; |
637 sprintf(message, "@" ERROR_FORMAT ": magic/ver = " |
665 sprintf(message, "@" ERROR_FORMAT ": magic/ver = " |
638 "%08X/%d.%d should be %08X/%d.%d OR %08X/%d.%d\n", |
666 "%08X/%d.%d should be %08X/%d.%d OR %08X/%d.%d OR %08X/%d.%d\n", |
639 magic, majver, minver, |
667 magic, majver, minver, |
640 JAVA_PACKAGE_MAGIC, JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION, |
668 JAVA_PACKAGE_MAGIC, JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION, |
641 JAVA_PACKAGE_MAGIC, JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION); |
669 JAVA_PACKAGE_MAGIC, JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION, |
|
670 JAVA_PACKAGE_MAGIC, JAVA7_PACKAGE_MAJOR_VERSION, JAVA7_PACKAGE_MINOR_VERSION); |
642 abort(message); |
671 abort(message); |
643 } |
672 } |
644 CHECK; |
673 CHECK; |
645 |
674 |
646 archive_options = hdr.getInt(); |
675 archive_options = hdr.getInt(); |
647 hdrVals += 1; |
676 hdrVals += 1; |
648 assert(hdrVals == AH_LENGTH_0); // first three fields only |
677 assert(hdrVals == AH_LENGTH_0); // first three fields only |
649 |
678 bool haveSizeHi = testBit(archive_options, AO_HAVE_FILE_SIZE_HI); |
650 #define ORBIT(bit) |(bit) |
679 bool haveModTime = testBit(archive_options, AO_HAVE_FILE_MODTIME); |
651 int OPTION_LIMIT = (0 ARCHIVE_BIT_DO(ORBIT)); |
680 bool haveFileOpt = testBit(archive_options, AO_HAVE_FILE_OPTIONS); |
652 #undef ORBIT |
681 |
653 if ((archive_options & ~OPTION_LIMIT) != 0) { |
682 bool haveSpecial = testBit(archive_options, AO_HAVE_SPECIAL_FORMATS); |
654 fprintf(errstrm, "Warning: Illegal archive options 0x%x\n", |
683 bool haveFiles = testBit(archive_options, AO_HAVE_FILE_HEADERS); |
655 archive_options); |
684 bool haveNumbers = testBit(archive_options, AO_HAVE_CP_NUMBERS); |
656 abort("illegal archive options"); |
685 bool haveCPExtra = testBit(archive_options, AO_HAVE_CP_EXTRAS); |
|
686 |
|
687 if (majver < JAVA7_PACKAGE_MAJOR_VERSION) { |
|
688 if (haveCPExtra) { |
|
689 abort("Format bits for Java 7 must be zero in previous releases"); |
|
690 return; |
|
691 } |
|
692 } |
|
693 if (testBit(archive_options, AO_UNUSED_MBZ)) { |
|
694 abort("High archive option bits are reserved and must be zero"); |
657 return; |
695 return; |
658 } |
696 } |
659 |
697 if (haveFiles) { |
660 if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) { |
|
661 uint hi = hdr.getInt(); |
698 uint hi = hdr.getInt(); |
662 uint lo = hdr.getInt(); |
699 uint lo = hdr.getInt(); |
663 julong x = band::makeLong(hi, lo); |
700 julong x = band::makeLong(hi, lo); |
664 archive_size = (size_t) x; |
701 archive_size = (size_t) x; |
665 if (archive_size != x) { |
702 if (archive_size != x) { |
736 if (aborting()) { |
773 if (aborting()) { |
737 abort("cannot allocate large input buffer for package file"); |
774 abort("cannot allocate large input buffer for package file"); |
738 return; |
775 return; |
739 } |
776 } |
740 |
777 |
741 // read the rest of the header fields |
778 // read the rest of the header fields int assertSkipped = AH_LENGTH_MIN - AH_LENGTH_0 - AH_LENGTH_S; |
742 ensure_input((AH_LENGTH-AH_LENGTH_0) * B_MAX); |
779 int remainingHeaders = AH_LENGTH_MIN - AH_LENGTH_0 - AH_LENGTH_S; |
|
780 if (haveSpecial) |
|
781 remainingHeaders += AH_SPECIAL_FORMAT_LEN; |
|
782 if (haveFiles) |
|
783 remainingHeaders += AH_FILE_HEADER_LEN; |
|
784 if (haveNumbers) |
|
785 remainingHeaders += AH_CP_NUMBER_LEN; |
|
786 if (haveCPExtra) |
|
787 remainingHeaders += AH_CP_EXTRA_LEN; |
|
788 |
|
789 ensure_input(remainingHeaders * B_MAX); |
743 CHECK; |
790 CHECK; |
744 hdr.rp = rp; |
791 hdr.rp = rp; |
745 hdr.rplimit = rplimit; |
792 hdr.rplimit = rplimit; |
746 |
793 |
747 if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) { |
794 if (haveFiles) { |
748 archive_next_count = hdr.getInt(); |
795 archive_next_count = hdr.getInt(); |
749 CHECK_COUNT(archive_next_count); |
796 CHECK_COUNT(archive_next_count); |
750 archive_modtime = hdr.getInt(); |
797 archive_modtime = hdr.getInt(); |
751 file_count = hdr.getInt(); |
798 file_count = hdr.getInt(); |
752 CHECK_COUNT(file_count); |
799 CHECK_COUNT(file_count); |
753 hdrVals += 3; |
800 hdrVals += 3; |
754 } else { |
801 } else { |
755 hdrValsSkipped += 3; |
802 hdrValsSkipped += 3; |
756 } |
803 } |
757 |
804 |
758 if ((archive_options & AO_HAVE_SPECIAL_FORMATS) != 0) { |
805 if (haveSpecial) { |
759 band_headers_size = hdr.getInt(); |
806 band_headers_size = hdr.getInt(); |
760 CHECK_COUNT(band_headers_size); |
807 CHECK_COUNT(band_headers_size); |
761 attr_definition_count = hdr.getInt(); |
808 attr_definition_count = hdr.getInt(); |
762 CHECK_COUNT(attr_definition_count); |
809 CHECK_COUNT(attr_definition_count); |
763 hdrVals += 2; |
810 hdrVals += 2; |
765 hdrValsSkipped += 2; |
812 hdrValsSkipped += 2; |
766 } |
813 } |
767 |
814 |
768 int cp_counts[N_TAGS_IN_ORDER]; |
815 int cp_counts[N_TAGS_IN_ORDER]; |
769 for (int k = 0; k < (int)N_TAGS_IN_ORDER; k++) { |
816 for (int k = 0; k < (int)N_TAGS_IN_ORDER; k++) { |
770 if (!(archive_options & AO_HAVE_CP_NUMBERS)) { |
817 if (!haveNumbers) { |
771 switch (TAGS_IN_ORDER[k]) { |
818 switch (TAGS_IN_ORDER[k]) { |
772 case CONSTANT_Integer: |
819 case CONSTANT_Integer: |
773 case CONSTANT_Float: |
820 case CONSTANT_Float: |
774 case CONSTANT_Long: |
821 case CONSTANT_Long: |
775 case CONSTANT_Double: |
822 case CONSTANT_Double: |
776 cp_counts[k] = 0; |
823 cp_counts[k] = 0; |
777 hdrValsSkipped += 1; |
824 hdrValsSkipped += 1; |
778 continue; |
825 continue; |
779 } |
826 } |
780 } |
827 } |
|
828 if (!haveCPExtra) { |
|
829 switch(TAGS_IN_ORDER[k]) { |
|
830 case CONSTANT_MethodHandle: |
|
831 case CONSTANT_MethodType: |
|
832 case CONSTANT_InvokeDynamic: |
|
833 case CONSTANT_BootstrapMethod: |
|
834 cp_counts[k] = 0; |
|
835 hdrValsSkipped += 1; |
|
836 continue; |
|
837 } |
|
838 } |
781 cp_counts[k] = hdr.getInt(); |
839 cp_counts[k] = hdr.getInt(); |
782 CHECK_COUNT(cp_counts[k]); |
840 CHECK_COUNT(cp_counts[k]); |
783 hdrVals += 1; |
841 hdrVals += 1; |
784 } |
842 } |
785 |
843 |
789 default_class_majver = hdr.getInt(); |
847 default_class_majver = hdr.getInt(); |
790 class_count = hdr.getInt(); |
848 class_count = hdr.getInt(); |
791 CHECK_COUNT(class_count); |
849 CHECK_COUNT(class_count); |
792 hdrVals += 4; |
850 hdrVals += 4; |
793 |
851 |
794 // done with archive_header |
852 // done with archive_header, time to reconcile to ensure |
|
853 // we have read everything correctly |
795 hdrVals += hdrValsSkipped; |
854 hdrVals += hdrValsSkipped; |
796 assert(hdrVals == AH_LENGTH); |
855 assert(hdrVals == AH_LENGTH); |
797 #ifndef PRODUCT |
|
798 int assertSkipped = AH_LENGTH - AH_LENGTH_MIN; |
|
799 if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) |
|
800 assertSkipped -= AH_FILE_HEADER_LEN; |
|
801 if ((archive_options & AO_HAVE_SPECIAL_FORMATS) != 0) |
|
802 assertSkipped -= AH_SPECIAL_FORMAT_LEN; |
|
803 if ((archive_options & AO_HAVE_CP_NUMBERS) != 0) |
|
804 assertSkipped -= AH_CP_NUMBER_LEN; |
|
805 assert(hdrValsSkipped == assertSkipped); |
|
806 #endif //PRODUCT |
|
807 |
|
808 rp = hdr.rp; |
856 rp = hdr.rp; |
809 if (rp > rplimit) |
857 if (rp > rplimit) |
810 abort("EOF reading archive header"); |
858 abort("EOF reading archive header"); |
811 |
859 |
812 // Now size the CP. |
860 // Now size the CP. |
813 #ifndef PRODUCT |
861 #ifndef PRODUCT |
814 bool x = (N_TAGS_IN_ORDER == cpool::NUM_COUNTS); |
862 // bool x = (N_TAGS_IN_ORDER == CONSTANT_Limit); |
815 assert(x); |
863 // assert(x); |
816 #endif //PRODUCT |
864 #endif //PRODUCT |
817 cp.init(this, cp_counts); |
865 cp.init(this, cp_counts); |
818 CHECK; |
866 CHECK; |
819 |
867 |
820 default_file_modtime = archive_modtime; |
868 default_file_modtime = archive_modtime; |
821 if (default_file_modtime == 0 && !(archive_options & AO_HAVE_FILE_MODTIME)) |
869 if (default_file_modtime == 0 && haveModTime) |
822 default_file_modtime = DEFAULT_ARCHIVE_MODTIME; // taken from driver |
870 default_file_modtime = DEFAULT_ARCHIVE_MODTIME; // taken from driver |
823 if ((archive_options & AO_DEFLATE_HINT) != 0) |
871 if (testBit(archive_options, AO_DEFLATE_HINT)) |
824 default_file_options |= FO_DEFLATE_HINT; |
872 default_file_options |= FO_DEFLATE_HINT; |
825 |
873 |
826 // meta-bytes, if any, immediately follow archive header |
874 // meta-bytes, if any, immediately follow archive header |
827 //band_headers.readData(band_headers_size); |
875 //band_headers.readData(band_headers_size); |
828 ensure_input(band_headers_size); |
876 ensure_input(band_headers_size); |
922 CHECK; |
970 CHECK; |
923 |
971 |
924 first_extra_entry = &entries[nentries]; |
972 first_extra_entry = &entries[nentries]; |
925 |
973 |
926 // Initialize the standard indexes. |
974 // Initialize the standard indexes. |
927 tag_count[CONSTANT_All] = nentries; |
|
928 tag_base[ CONSTANT_All] = 0; |
|
929 for (int tag = 0; tag < CONSTANT_Limit; tag++) { |
975 for (int tag = 0; tag < CONSTANT_Limit; tag++) { |
930 entry* cpMap = &entries[tag_base[tag]]; |
976 entry* cpMap = &entries[tag_base[tag]]; |
931 tag_index[tag].init(tag_count[tag], cpMap, tag); |
977 tag_index[tag].init(tag_count[tag], cpMap, tag); |
932 } |
978 } |
933 |
979 |
|
980 // Initialize *all* our entries once |
|
981 for (int i = 0 ; i < maxentries ; i++) |
|
982 entries[i].outputIndex = REQUESTED_NONE; |
|
983 |
|
984 initGroupIndexes(); |
934 // Initialize hashTab to a generous power-of-two size. |
985 // Initialize hashTab to a generous power-of-two size. |
935 uint pow2 = 1; |
986 uint pow2 = 1; |
936 uint target = maxentries + maxentries/2; // 60% full |
987 uint target = maxentries + maxentries/2; // 60% full |
937 while (pow2 < target) pow2 <<= 1; |
988 while (pow2 < target) pow2 <<= 1; |
938 hashTab = U_NEW(entry*, hashTabLength = pow2); |
989 hashTab = U_NEW(entry*, hashTabLength = pow2); |
1279 } |
1330 } |
1280 } |
1331 } |
1281 //cp_Signature_classes.done(); |
1332 //cp_Signature_classes.done(); |
1282 } |
1333 } |
1283 |
1334 |
|
1335 maybe_inline |
|
1336 void unpacker::checkLegacy(const char* name) { |
|
1337 if (u->majver < JAVA7_PACKAGE_MAJOR_VERSION) { |
|
1338 char message[100]; |
|
1339 snprintf(message, 99, "unexpected band %s\n", name); |
|
1340 abort(message); |
|
1341 } |
|
1342 } |
|
1343 |
|
1344 maybe_inline |
|
1345 void unpacker::read_method_handle(entry* cpMap, int len) { |
|
1346 if (len > 0) { |
|
1347 checkLegacy(cp_MethodHandle_refkind.name); |
|
1348 } |
|
1349 cp_MethodHandle_refkind.readData(len); |
|
1350 cp_MethodHandle_member.setIndexByTag(CONSTANT_AnyMember); |
|
1351 cp_MethodHandle_member.readData(len); |
|
1352 for (int i = 0 ; i < len ; i++) { |
|
1353 entry& e = cpMap[i]; |
|
1354 e.value.i = cp_MethodHandle_refkind.getInt(); |
|
1355 e.refs = U_NEW(entry*, e.nrefs = 1); |
|
1356 e.refs[0] = cp_MethodHandle_member.getRef(); |
|
1357 CHECK; |
|
1358 } |
|
1359 } |
|
1360 |
|
1361 maybe_inline |
|
1362 void unpacker::read_method_type(entry* cpMap, int len) { |
|
1363 if (len > 0) { |
|
1364 checkLegacy(cp_MethodType.name); |
|
1365 } |
|
1366 cp_MethodType.setIndexByTag(CONSTANT_Signature); |
|
1367 cp_MethodType.readData(len); |
|
1368 for (int i = 0 ; i < len ; i++) { |
|
1369 entry& e = cpMap[i]; |
|
1370 e.refs = U_NEW(entry*, e.nrefs = 1); |
|
1371 e.refs[0] = cp_MethodType.getRef(); |
|
1372 } |
|
1373 } |
|
1374 |
|
1375 maybe_inline |
|
1376 void unpacker::read_bootstrap_methods(entry* cpMap, int len) { |
|
1377 if (len > 0) { |
|
1378 checkLegacy(cp_BootstrapMethod_ref.name); |
|
1379 } |
|
1380 cp_BootstrapMethod_ref.setIndexByTag(CONSTANT_MethodHandle); |
|
1381 cp_BootstrapMethod_ref.readData(len); |
|
1382 |
|
1383 cp_BootstrapMethod_arg_count.readData(len); |
|
1384 int totalArgCount = cp_BootstrapMethod_arg_count.getIntTotal(); |
|
1385 cp_BootstrapMethod_arg.setIndexByTag(CONSTANT_LoadableValue); |
|
1386 cp_BootstrapMethod_arg.readData(totalArgCount); |
|
1387 for (int i = 0; i < len; i++) { |
|
1388 entry& e = cpMap[i]; |
|
1389 int argc = cp_BootstrapMethod_arg_count.getInt(); |
|
1390 e.value.i = argc; |
|
1391 e.refs = U_NEW(entry*, e.nrefs = argc + 1); |
|
1392 e.refs[0] = cp_BootstrapMethod_ref.getRef(); |
|
1393 for (int j = 1 ; j < e.nrefs ; j++) { |
|
1394 e.refs[j] = cp_BootstrapMethod_arg.getRef(); |
|
1395 CHECK; |
|
1396 } |
|
1397 } |
|
1398 } |
1284 // Cf. PackageReader.readConstantPool |
1399 // Cf. PackageReader.readConstantPool |
1285 void unpacker::read_cp() { |
1400 void unpacker::read_cp() { |
1286 byte* rp0 = rp; |
1401 byte* rp0 = rp; |
1287 |
1402 |
1288 int i; |
1403 int i; |
1342 case CONSTANT_InterfaceMethodref: |
1465 case CONSTANT_InterfaceMethodref: |
1343 read_double_refs(cp_Imethod_class /*& cp_Imethod_desc*/, |
1466 read_double_refs(cp_Imethod_class /*& cp_Imethod_desc*/, |
1344 CONSTANT_Class, CONSTANT_NameandType, |
1467 CONSTANT_Class, CONSTANT_NameandType, |
1345 cpMap, len); |
1468 cpMap, len); |
1346 break; |
1469 break; |
|
1470 case CONSTANT_MethodHandle: |
|
1471 // consumes cp_MethodHandle_refkind and cp_MethodHandle_member |
|
1472 read_method_handle(cpMap, len); |
|
1473 break; |
|
1474 case CONSTANT_MethodType: |
|
1475 // consumes cp_MethodType |
|
1476 read_method_type(cpMap, len); |
|
1477 break; |
|
1478 case CONSTANT_InvokeDynamic: |
|
1479 read_double_refs(cp_InvokeDynamic_spec, CONSTANT_BootstrapMethod, |
|
1480 CONSTANT_NameandType, |
|
1481 cpMap, len); |
|
1482 break; |
|
1483 case CONSTANT_BootstrapMethod: |
|
1484 // consumes cp_BootstrapMethod_ref, cp_BootstrapMethod_arg_count and cp_BootstrapMethod_arg |
|
1485 read_bootstrap_methods(cpMap, len); |
|
1486 break; |
1347 default: |
1487 default: |
1348 assert(false); |
1488 assert(false); |
1349 break; |
1489 break; |
1350 } |
1490 } |
1351 |
|
1352 // Initialize the tag's CP index right away, since it might be needed |
|
1353 // in the next pass to initialize the CP for another tag. |
|
1354 #ifndef PRODUCT |
|
1355 cpindex* ix = &cp.tag_index[tag]; |
|
1356 assert(ix->ixTag == tag); |
|
1357 assert((int)ix->len == len); |
|
1358 assert(ix->base1 == cpMap); |
|
1359 #endif |
|
1360 CHECK; |
1491 CHECK; |
1361 } |
1492 } |
1362 |
1493 |
1363 cp.expandSignatures(); |
1494 cp.expandSignatures(); |
1364 CHECK; |
1495 CHECK; |
1789 case 'I': ixTag = CONSTANT_Integer; break; |
1920 case 'I': ixTag = CONSTANT_Integer; break; |
1790 case 'J': ixTag = CONSTANT_Long; break; |
1921 case 'J': ixTag = CONSTANT_Long; break; |
1791 case 'F': ixTag = CONSTANT_Float; break; |
1922 case 'F': ixTag = CONSTANT_Float; break; |
1792 case 'D': ixTag = CONSTANT_Double; break; |
1923 case 'D': ixTag = CONSTANT_Double; break; |
1793 case 'S': ixTag = CONSTANT_String; break; |
1924 case 'S': ixTag = CONSTANT_String; break; |
1794 case 'Q': ixTag = CONSTANT_Literal; break; |
1925 case 'Q': ixTag = CONSTANT_FieldSpecific; break; |
|
1926 |
|
1927 // new in 1.7 |
|
1928 case 'M': ixTag = CONSTANT_MethodHandle; break; |
|
1929 case 'T': ixTag = CONSTANT_MethodType; break; |
|
1930 case 'L': ixTag = CONSTANT_LoadableValue; break; |
1795 } |
1931 } |
1796 } else { |
1932 } else { |
1797 switch (*lp++) { |
1933 switch (*lp++) { |
1798 case 'C': ixTag = CONSTANT_Class; break; |
1934 case 'C': ixTag = CONSTANT_Class; break; |
1799 case 'S': ixTag = CONSTANT_Signature; break; |
1935 case 'S': ixTag = CONSTANT_Signature; break; |
1801 case 'F': ixTag = CONSTANT_Fieldref; break; |
1937 case 'F': ixTag = CONSTANT_Fieldref; break; |
1802 case 'M': ixTag = CONSTANT_Methodref; break; |
1938 case 'M': ixTag = CONSTANT_Methodref; break; |
1803 case 'I': ixTag = CONSTANT_InterfaceMethodref; break; |
1939 case 'I': ixTag = CONSTANT_InterfaceMethodref; break; |
1804 case 'U': ixTag = CONSTANT_Utf8; break; //utf8_ref |
1940 case 'U': ixTag = CONSTANT_Utf8; break; //utf8_ref |
1805 case 'Q': ixTag = CONSTANT_All; break; //untyped_ref |
1941 case 'Q': ixTag = CONSTANT_All; break; //untyped_ref |
|
1942 |
|
1943 // new in 1.7 |
|
1944 case 'Y': ixTag = CONSTANT_InvokeDynamic; break; |
|
1945 case 'B': ixTag = CONSTANT_BootstrapMethod; break; |
|
1946 case 'N': ixTag = CONSTANT_AnyMember; break; |
1806 } |
1947 } |
1807 } |
1948 } |
1808 if (ixTag == CONSTANT_None) { |
1949 if (ixTag == CONSTANT_None) { |
1809 abort("bad reference layout"); |
1950 abort("bad reference layout"); |
1810 break; |
1951 break; |
1871 attr_defs[ATTR_CONTEXT_CODE].attrc = ATTR_CONTEXT_CODE; |
2012 attr_defs[ATTR_CONTEXT_CODE].attrc = ATTR_CONTEXT_CODE; |
1872 attr_defs[ATTR_CONTEXT_CODE].xxx_flags_hi_bn = e_code_flags_hi; |
2013 attr_defs[ATTR_CONTEXT_CODE].xxx_flags_hi_bn = e_code_flags_hi; |
1873 |
2014 |
1874 // Decide whether bands for the optional high flag words are present. |
2015 // Decide whether bands for the optional high flag words are present. |
1875 attr_defs[ATTR_CONTEXT_CLASS] |
2016 attr_defs[ATTR_CONTEXT_CLASS] |
1876 .setHaveLongFlags((archive_options & AO_HAVE_CLASS_FLAGS_HI) != 0); |
2017 .setHaveLongFlags(testBit(archive_options, AO_HAVE_CLASS_FLAGS_HI)); |
1877 attr_defs[ATTR_CONTEXT_FIELD] |
2018 attr_defs[ATTR_CONTEXT_FIELD] |
1878 .setHaveLongFlags((archive_options & AO_HAVE_FIELD_FLAGS_HI) != 0); |
2019 .setHaveLongFlags(testBit(archive_options, AO_HAVE_FIELD_FLAGS_HI)); |
1879 attr_defs[ATTR_CONTEXT_METHOD] |
2020 attr_defs[ATTR_CONTEXT_METHOD] |
1880 .setHaveLongFlags((archive_options & AO_HAVE_METHOD_FLAGS_HI) != 0); |
2021 .setHaveLongFlags(testBit(archive_options, AO_HAVE_METHOD_FLAGS_HI)); |
1881 attr_defs[ATTR_CONTEXT_CODE] |
2022 attr_defs[ATTR_CONTEXT_CODE] |
1882 .setHaveLongFlags((archive_options & AO_HAVE_CODE_FLAGS_HI) != 0); |
2023 .setHaveLongFlags(testBit(archive_options, AO_HAVE_CODE_FLAGS_HI)); |
1883 |
2024 |
1884 // Set up built-in attrs. |
2025 // Set up built-in attrs. |
1885 // (The simple ones are hard-coded. The metadata layouts are not.) |
2026 // (The simple ones are hard-coded. The metadata layouts are not.) |
1886 const char* md_layout = ( |
2027 const char* md_layout = ( |
1887 // parameter annotations: |
2028 // parameter annotations: |
2651 } |
2792 } |
2652 } |
2793 } |
2653 |
2794 |
2654 void unpacker::read_files() { |
2795 void unpacker::read_files() { |
2655 file_name.readData(file_count); |
2796 file_name.readData(file_count); |
2656 if ((archive_options & AO_HAVE_FILE_SIZE_HI) != 0) |
2797 if (testBit(archive_options, AO_HAVE_FILE_SIZE_HI)) |
2657 file_size_hi.readData(file_count); |
2798 file_size_hi.readData(file_count); |
2658 file_size_lo.readData(file_count); |
2799 file_size_lo.readData(file_count); |
2659 if ((archive_options & AO_HAVE_FILE_MODTIME) != 0) |
2800 if (testBit(archive_options, AO_HAVE_FILE_MODTIME)) |
2660 file_modtime.readData(file_count); |
2801 file_modtime.readData(file_count); |
2661 int allFiles = file_count + class_count; |
2802 int allFiles = file_count + class_count; |
2662 if ((archive_options & AO_HAVE_FILE_OPTIONS) != 0) { |
2803 if (testBit(archive_options, AO_HAVE_FILE_OPTIONS)) { |
2663 file_options.readData(file_count); |
2804 file_options.readData(file_count); |
2664 // FO_IS_CLASS_STUB might be set, causing overlap between classes and files |
2805 // FO_IS_CLASS_STUB might be set, causing overlap between classes and files |
2665 for (int i = 0; i < file_count; i++) { |
2806 for (int i = 0; i < file_count; i++) { |
2666 if ((file_options.getInt() & FO_IS_CLASS_STUB) != 0) { |
2807 if ((file_options.getInt() & FO_IS_CLASS_STUB) != 0) { |
2667 allFiles -= 1; // this one counts as both class and file |
2808 allFiles -= 1; // this one counts as both class and file |
3129 e2 = e2->refs[0]; |
3274 e2 = e2->refs[0]; |
3130 } |
3275 } |
3131 } |
3276 } |
3132 } |
3277 } |
3133 |
3278 |
|
3279 bool isLoadableValue(int tag) { |
|
3280 switch(tag) { |
|
3281 case CONSTANT_Integer: |
|
3282 case CONSTANT_Float: |
|
3283 case CONSTANT_Long: |
|
3284 case CONSTANT_Double: |
|
3285 case CONSTANT_String: |
|
3286 case CONSTANT_Class: |
|
3287 case CONSTANT_MethodHandle: |
|
3288 case CONSTANT_MethodType: |
|
3289 return true; |
|
3290 default: |
|
3291 return false; |
|
3292 } |
|
3293 } |
|
3294 /* |
|
3295 * this method can be used to size an array using null as the parameter, |
|
3296 * thereafter can be reused to initialize the array using a valid pointer |
|
3297 * as a parameter. |
|
3298 */ |
|
3299 int cpool::initLoadableValues(entry** loadable_entries) { |
|
3300 int loadable_count = 0; |
|
3301 for (int i = 0; i < (int)N_TAGS_IN_ORDER; i++) { |
|
3302 int tag = TAGS_IN_ORDER[i]; |
|
3303 if (!isLoadableValue(tag)) |
|
3304 continue; |
|
3305 if (loadable_entries != NULL) { |
|
3306 for (int n = 0 ; n < tag_count[tag] ; n++) { |
|
3307 loadable_entries[loadable_count + n] = &entries[tag_base[tag] + n]; |
|
3308 } |
|
3309 } |
|
3310 loadable_count += tag_count[tag]; |
|
3311 } |
|
3312 return loadable_count; |
|
3313 } |
|
3314 |
|
3315 // Initialize various views into the constant pool. |
|
3316 void cpool::initGroupIndexes() { |
|
3317 // Initialize All |
|
3318 int all_count = 0; |
|
3319 for (int tag = CONSTANT_None ; tag < CONSTANT_Limit ; tag++) { |
|
3320 all_count += tag_count[tag]; |
|
3321 } |
|
3322 entry* all_entries = &entries[tag_base[CONSTANT_None]]; |
|
3323 tag_group_count[CONSTANT_All - CONSTANT_All] = all_count; |
|
3324 tag_group_index[CONSTANT_All - CONSTANT_All].init(all_count, all_entries, CONSTANT_All); |
|
3325 |
|
3326 // Initialize LoadableValues |
|
3327 int loadable_count = initLoadableValues(NULL); |
|
3328 entry** loadable_entries = U_NEW(entry*, loadable_count); |
|
3329 initLoadableValues(loadable_entries); |
|
3330 tag_group_count[CONSTANT_LoadableValue - CONSTANT_All] = loadable_count; |
|
3331 tag_group_index[CONSTANT_LoadableValue - CONSTANT_All].init(loadable_count, |
|
3332 loadable_entries, CONSTANT_LoadableValue); |
|
3333 |
|
3334 // Initialize AnyMembers |
|
3335 int any_count = tag_count[CONSTANT_Fieldref] + |
|
3336 tag_count[CONSTANT_Methodref] + |
|
3337 tag_count[CONSTANT_InterfaceMethodref]; |
|
3338 entry *any_entries = &entries[tag_base[CONSTANT_Fieldref]]; |
|
3339 tag_group_count[CONSTANT_AnyMember - CONSTANT_All] = any_count; |
|
3340 tag_group_index[CONSTANT_AnyMember - CONSTANT_All].init(any_count, |
|
3341 any_entries, CONSTANT_AnyMember); |
|
3342 } |
|
3343 |
3134 void cpool::initMemberIndexes() { |
3344 void cpool::initMemberIndexes() { |
3135 // This function does NOT refer to any class schema. |
3345 // This function does NOT refer to any class schema. |
3136 // It is totally internal to the cpool. |
3346 // It is totally internal to the cpool. |
3137 int i, j; |
3347 int i, j; |
3138 |
3348 |
3236 // Free intermediate buffers. |
3446 // Free intermediate buffers. |
3237 u->free_temps(); |
3447 u->free_temps(); |
3238 } |
3448 } |
3239 |
3449 |
3240 void entry::requestOutputIndex(cpool& cp, int req) { |
3450 void entry::requestOutputIndex(cpool& cp, int req) { |
3241 assert(outputIndex <= NOT_REQUESTED); // must not have assigned indexes yet |
3451 assert(outputIndex <= REQUESTED_NONE); // must not have assigned indexes yet |
3242 if (tag == CONSTANT_Signature) { |
3452 if (tag == CONSTANT_Signature) { |
3243 ref(0)->requestOutputIndex(cp, req); |
3453 ref(0)->requestOutputIndex(cp, req); |
3244 return; |
3454 return; |
3245 } |
3455 } |
3246 assert(req == REQUESTED || req == REQUESTED_LDC); |
3456 assert(req == REQUESTED || req == REQUESTED_LDC); |
3247 if (outputIndex != NOT_REQUESTED) { |
3457 if (outputIndex != REQUESTED_NONE) { |
3248 if (req == REQUESTED_LDC) |
3458 if (req == REQUESTED_LDC) |
3249 outputIndex = req; // this kind has precedence |
3459 outputIndex = req; // this kind has precedence |
3250 return; |
3460 return; |
3251 } |
3461 } |
3252 outputIndex = req; |
3462 outputIndex = req; |
3253 //assert(!cp.outputEntries.contains(this)); |
3463 //assert(!cp.outputEntries.contains(this)); |
3254 assert(tag != CONSTANT_Signature); |
3464 assert(tag != CONSTANT_Signature); |
3255 cp.outputEntries.add(this); |
3465 // The BSMs are jetisoned to a side table, however all references |
|
3466 // that the BSMs refer to, need to be considered. |
|
3467 if (tag == CONSTANT_BootstrapMethod) { |
|
3468 // this is a a pseudo-op entry; an attribute will be generated later on |
|
3469 cp.requested_bsms.add(this); |
|
3470 } else { |
|
3471 // all other tag types go into real output file CP: |
|
3472 cp.outputEntries.add(this); |
|
3473 } |
3256 for (int j = 0; j < nrefs; j++) { |
3474 for (int j = 0; j < nrefs; j++) { |
3257 ref(j)->requestOutputIndex(cp); |
3475 ref(j)->requestOutputIndex(cp); |
3258 } |
3476 } |
3259 } |
3477 } |
3260 |
3478 |
3261 void cpool::resetOutputIndexes() { |
3479 void cpool::resetOutputIndexes() { |
3262 int i; |
3480 /* |
3263 int noes = outputEntries.length(); |
3481 * reset those few entries that are being used in the current class |
|
3482 * (Caution since this method is called after every class written, a loop |
|
3483 * over every global constant pool entry would be a quadratic cost.) |
|
3484 */ |
|
3485 |
|
3486 int noes = outputEntries.length(); |
3264 entry** oes = (entry**) outputEntries.base(); |
3487 entry** oes = (entry**) outputEntries.base(); |
3265 for (i = 0; i < noes; i++) { |
3488 for (int i = 0 ; i < noes ; i++) { |
3266 entry& e = *oes[i]; |
3489 entry& e = *oes[i]; |
3267 e.outputIndex = NOT_REQUESTED; |
3490 e.outputIndex = REQUESTED_NONE; |
|
3491 } |
|
3492 |
|
3493 // do the same for bsms and reset them if required |
|
3494 int nbsms = requested_bsms.length(); |
|
3495 entry** boes = (entry**) requested_bsms.base(); |
|
3496 for (int i = 0 ; i < nbsms ; i++) { |
|
3497 entry& e = *boes[i]; |
|
3498 e.outputIndex = REQUESTED_NONE; |
3268 } |
3499 } |
3269 outputIndexLimit = 0; |
3500 outputIndexLimit = 0; |
3270 outputEntries.empty(); |
3501 outputEntries.empty(); |
3271 #ifndef PRODUCT |
3502 #ifndef PRODUCT |
3272 // they must all be clear now |
3503 // ensure things are cleared out |
3273 for (i = 0; i < (int)nentries; i++) |
3504 for (int i = 0; i < (int)maxentries; i++) |
3274 assert(entries[i].outputIndex == NOT_REQUESTED); |
3505 assert(entries[i].outputIndex == REQUESTED_NONE); |
3275 #endif |
3506 #endif |
3276 } |
3507 } |
3277 |
3508 |
3278 static const byte TAG_ORDER[CONSTANT_Limit] = { |
3509 static const byte TAG_ORDER[CONSTANT_Limit] = { |
3279 0, 1, 0, 2, 3, 4, 5, 7, 6, 10, 11, 12, 9, 8 |
3510 0, 1, 0, 2, 3, 4, 5, 7, 6, 10, 11, 12, 9, 8, 0, 13, 14, 15, 16 |
3280 }; |
3511 }; |
3281 |
3512 |
3282 extern "C" |
3513 extern "C" |
3283 int outputEntry_cmp(const void* e1p, const void* e2p) { |
3514 int outputEntry_cmp(const void* e1p, const void* e2p) { |
3284 // Sort entries according to the Pack200 rules for deterministic |
3515 // Sort entries according to the Pack200 rules for deterministic |
3321 static uint checkStart = 0; |
3552 static uint checkStart = 0; |
3322 int checkStep = 1; |
3553 int checkStep = 1; |
3323 if (nentries > 100) checkStep = nentries / 100; |
3554 if (nentries > 100) checkStep = nentries / 100; |
3324 for (i = (int)(checkStart++ % checkStep); i < (int)nentries; i += checkStep) { |
3555 for (i = (int)(checkStart++ % checkStep); i < (int)nentries; i += checkStep) { |
3325 entry& e = entries[i]; |
3556 entry& e = entries[i]; |
3326 if (e.outputIndex != NOT_REQUESTED) { |
3557 if (e.tag == CONSTANT_BootstrapMethod) { |
3327 assert(outputEntries.contains(&e)); |
3558 if (e.outputIndex != REQUESTED_NONE) { |
|
3559 assert(requested_bsms.contains(&e)); |
|
3560 } else { |
|
3561 assert(!requested_bsms.contains(&e)); |
|
3562 } |
3328 } else { |
3563 } else { |
3329 assert(!outputEntries.contains(&e)); |
3564 if (e.outputIndex != REQUESTED_NONE) { |
|
3565 assert(outputEntries.contains(&e)); |
|
3566 } else { |
|
3567 assert(!outputEntries.contains(&e)); |
|
3568 } |
3330 } |
3569 } |
3331 } |
3570 } |
3332 |
3571 |
3333 // check hand-initialization of TAG_ORDER |
3572 // check hand-initialization of TAG_ORDER |
3334 for (i = 0; i < (int)N_TAGS_IN_ORDER; i++) { |
3573 for (i = 0; i < (int)N_TAGS_IN_ORDER; i++) { |
3346 // Allocate a new index for each entry that needs one. |
3585 // Allocate a new index for each entry that needs one. |
3347 // We do this in two passes, one for LDC entries and one for the rest. |
3586 // We do this in two passes, one for LDC entries and one for the rest. |
3348 int nextIndex = 1; // always skip index #0 in output cpool |
3587 int nextIndex = 1; // always skip index #0 in output cpool |
3349 for (i = 0; i < noes; i++) { |
3588 for (i = 0; i < noes; i++) { |
3350 entry& e = *oes[i]; |
3589 entry& e = *oes[i]; |
3351 assert(e.outputIndex == REQUESTED || e.outputIndex == REQUESTED_LDC); |
3590 assert(e.outputIndex >= REQUESTED_LDC); |
3352 e.outputIndex = nextIndex++; |
3591 e.outputIndex = nextIndex++; |
3353 if (e.isDoubleWord()) nextIndex++; // do not use the next index |
3592 if (e.isDoubleWord()) nextIndex++; // do not use the next index |
3354 } |
3593 } |
3355 outputIndexLimit = nextIndex; |
3594 outputIndexLimit = nextIndex; |
3356 PRINTCR((3,"renumbering CP to %d entries", outputIndexLimit)); |
3595 PRINTCR((3,"renumbering CP to %d entries", outputIndexLimit)); |
4351 void* p1 = *(void**) p1p; |
4597 void* p1 = *(void**) p1p; |
4352 void* p2 = *(void**) p2p; |
4598 void* p2 = *(void**) p2p; |
4353 return (p1 > p2)? 1: (p1 < p2)? -1: 0; |
4599 return (p1 > p2)? 1: (p1 < p2)? -1: 0; |
4354 } |
4600 } |
4355 |
4601 |
4356 void unpacker::write_classfile_tail() { |
4602 /* |
4357 cur_classfile_tail.empty(); |
4603 * writes the InnerClass attributes and returns the updated attribute |
4358 set_output(&cur_classfile_tail); |
4604 */ |
4359 |
4605 int unpacker::write_ics(int naOffset, int na) { |
4360 int i, num; |
|
4361 |
|
4362 attr_definitions& ad = attr_defs[ATTR_CONTEXT_CLASS]; |
|
4363 |
|
4364 bool haveLongFlags = ad.haveLongFlags(); |
|
4365 julong kflags = class_flags_hi.getLong(class_flags_lo, haveLongFlags); |
|
4366 julong indexMask = ad.flagIndexMask(); |
|
4367 |
|
4368 cur_class = class_this.getRef(); |
|
4369 cur_super = class_super.getRef(); |
|
4370 |
|
4371 CHECK; |
|
4372 |
|
4373 if (cur_super == cur_class) cur_super = null; |
|
4374 // special representation for java/lang/Object |
|
4375 |
|
4376 putu2((ushort)(kflags & ~indexMask)); |
|
4377 putref(cur_class); |
|
4378 putref(cur_super); |
|
4379 |
|
4380 putu2(num = class_interface_count.getInt()); |
|
4381 for (i = 0; i < num; i++) { |
|
4382 putref(class_interface.getRef()); |
|
4383 } |
|
4384 |
|
4385 write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD); |
|
4386 write_members(class_method_count.getInt(), ATTR_CONTEXT_METHOD); |
|
4387 CHECK; |
|
4388 |
|
4389 cur_class_has_local_ics = false; // may be set true by write_attrs |
|
4390 |
|
4391 |
|
4392 int naOffset = (int)wpoffset(); |
|
4393 int na = write_attrs(ATTR_CONTEXT_CLASS, (kflags & indexMask)); |
|
4394 |
|
4395 |
|
4396 // at the very last, choose which inner classes (if any) pertain to k: |
|
4397 #ifdef ASSERT |
4606 #ifdef ASSERT |
4398 for (i = 0; i < ic_count; i++) { |
4607 for (int i = 0; i < ic_count; i++) { |
4399 assert(!ics[i].requested); |
4608 assert(!ics[i].requested); |
4400 } |
4609 } |
4401 #endif |
4610 #endif |
4402 // First, consult the global table and the local constant pool, |
4611 // First, consult the global table and the local constant pool, |
4403 // and decide on the globally implied inner classes. |
4612 // and decide on the globally implied inner classes. |
4414 } |
4623 } |
4415 // And, for each inner class mentioned in the constant pool, |
4624 // And, for each inner class mentioned in the constant pool, |
4416 // include it and all its outers. |
4625 // include it and all its outers. |
4417 int noes = cp.outputEntries.length(); |
4626 int noes = cp.outputEntries.length(); |
4418 entry** oes = (entry**) cp.outputEntries.base(); |
4627 entry** oes = (entry**) cp.outputEntries.base(); |
4419 for (i = 0; i < noes; i++) { |
4628 for (int i = 0; i < noes; i++) { |
4420 entry& e = *oes[i]; |
4629 entry& e = *oes[i]; |
4421 if (e.tag != CONSTANT_Class) continue; // wrong sort |
4630 if (e.tag != CONSTANT_Class) continue; // wrong sort |
4422 for (inner_class* ic = cp.getIC(&e); |
4631 for (inner_class* ic = cp.getIC(&e); |
4423 ic != null; |
4632 ic != null; |
4424 ic = cp.getIC(ic->outer)) { |
4633 ic = cp.getIC(ic->outer)) { |
4440 } else { |
4649 } else { |
4441 extra_ics = T_NEW(inner_class, num_extra_ics); |
4650 extra_ics = T_NEW(inner_class, num_extra_ics); |
4442 // Note: extra_ics will be freed up by next call to get_next_file(). |
4651 // Note: extra_ics will be freed up by next call to get_next_file(). |
4443 } |
4652 } |
4444 } |
4653 } |
4445 for (i = 0; i < num_extra_ics; i++) { |
4654 for (int i = 0; i < num_extra_ics; i++) { |
4446 inner_class& extra_ic = extra_ics[i]; |
4655 inner_class& extra_ic = extra_ics[i]; |
4447 extra_ic.inner = class_InnerClasses_RC.getRef(); |
4656 extra_ic.inner = class_InnerClasses_RC.getRef(); |
4448 CHECK; |
4657 CHECK_0; |
4449 // Find the corresponding equivalent global IC: |
4658 // Find the corresponding equivalent global IC: |
4450 inner_class* global_ic = cp.getIC(extra_ic.inner); |
4659 inner_class* global_ic = cp.getIC(extra_ic.inner); |
4451 int flags = class_InnerClasses_F.getInt(); |
4660 int flags = class_InnerClasses_F.getInt(); |
4452 if (flags == 0) { |
4661 if (flags == 0) { |
4453 // The extra IC is simply a copy of a global IC. |
4662 // The extra IC is simply a copy of a global IC. |
4510 assert(local_ics == 0); // must balance |
4719 assert(local_ics == 0); // must balance |
4511 putu2_at(wp_at(naOffset), ++na); // increment class attr count |
4720 putu2_at(wp_at(naOffset), ++na); // increment class attr count |
4512 } |
4721 } |
4513 |
4722 |
4514 // Tidy up global 'requested' bits: |
4723 // Tidy up global 'requested' bits: |
4515 for (i = requested_ics.length(); --i >= 0; ) { |
4724 for (int i = requested_ics.length(); --i >= 0; ) { |
4516 inner_class* ic = (inner_class*) requested_ics.get(i); |
4725 inner_class* ic = (inner_class*) requested_ics.get(i); |
4517 ic->requested = false; |
4726 ic->requested = false; |
4518 } |
4727 } |
4519 requested_ics.empty(); |
4728 requested_ics.empty(); |
4520 |
4729 return na; |
|
4730 } |
|
4731 |
|
4732 /* |
|
4733 * Writes the BootstrapMethods attribute and returns the updated attribute count |
|
4734 */ |
|
4735 int unpacker::write_bsms(int naOffset, int na) { |
|
4736 cur_class_local_bsm_count = cp.requested_bsms.length(); |
|
4737 if (cur_class_local_bsm_count > 0) { |
|
4738 int noes = cp.outputEntries.length(); |
|
4739 entry** oes = (entry**) cp.outputEntries.base(); |
|
4740 PTRLIST_QSORT(cp.requested_bsms, outputEntry_cmp); |
|
4741 // append the BootstrapMethods attribute (after the InnerClasses attr): |
|
4742 putref(cp.sym[cpool::s_BootstrapMethods]); |
|
4743 int sizeOffset = (int)wpoffset(); |
|
4744 byte* sizewp = wp; |
|
4745 putu4(-99); // attr size will be patched |
|
4746 putu2(cur_class_local_bsm_count); |
|
4747 int written_bsms = 0; |
|
4748 for (int i = 0 ; i < cur_class_local_bsm_count ; i++) { |
|
4749 entry* e = (entry*)cp.requested_bsms.get(i); |
|
4750 assert(e->outputIndex != REQUESTED_NONE); |
|
4751 // output index is the index within the array |
|
4752 e->outputIndex = i; |
|
4753 putref(e->refs[0]); // bsm |
|
4754 putu2(e->nrefs-1); // number of args after bsm |
|
4755 for (int j = 1; j < e->nrefs; j++) { |
|
4756 putref(e->refs[j]); |
|
4757 } |
|
4758 written_bsms += 1; |
|
4759 } |
|
4760 assert(written_bsms == cur_class_local_bsm_count); // else insane |
|
4761 putu4_at(sizewp, (int)(wp - (sizewp+4))); // size of code attr |
|
4762 putu2_at(wp_at(naOffset), ++na); // increment class attr count |
|
4763 } |
|
4764 return na; |
|
4765 } |
|
4766 |
|
4767 void unpacker::write_classfile_tail() { |
|
4768 |
|
4769 cur_classfile_tail.empty(); |
|
4770 set_output(&cur_classfile_tail); |
|
4771 |
|
4772 int i, num; |
|
4773 |
|
4774 attr_definitions& ad = attr_defs[ATTR_CONTEXT_CLASS]; |
|
4775 |
|
4776 bool haveLongFlags = ad.haveLongFlags(); |
|
4777 julong kflags = class_flags_hi.getLong(class_flags_lo, haveLongFlags); |
|
4778 julong indexMask = ad.flagIndexMask(); |
|
4779 |
|
4780 cur_class = class_this.getRef(); |
|
4781 cur_super = class_super.getRef(); |
4521 CHECK; |
4782 CHECK; |
|
4783 |
|
4784 if (cur_super == cur_class) cur_super = null; |
|
4785 // special representation for java/lang/Object |
|
4786 |
|
4787 putu2((ushort)(kflags & ~indexMask)); |
|
4788 putref(cur_class); |
|
4789 putref(cur_super); |
|
4790 |
|
4791 putu2(num = class_interface_count.getInt()); |
|
4792 for (i = 0; i < num; i++) { |
|
4793 putref(class_interface.getRef()); |
|
4794 } |
|
4795 |
|
4796 write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD); |
|
4797 write_members(class_method_count.getInt(), ATTR_CONTEXT_METHOD); |
|
4798 CHECK; |
|
4799 |
|
4800 cur_class_has_local_ics = false; // may be set true by write_attrs |
|
4801 |
|
4802 int naOffset = (int)wpoffset(); // note the attr count location |
|
4803 int na = write_attrs(ATTR_CONTEXT_CLASS, (kflags & indexMask)); |
|
4804 CHECK; |
|
4805 |
|
4806 na = write_bsms(naOffset, na); |
|
4807 CHECK; |
|
4808 |
|
4809 // choose which inner classes (if any) pertain to k: |
|
4810 na = write_ics(naOffset, na); |
|
4811 CHECK; |
|
4812 |
4522 close_output(); |
4813 close_output(); |
|
4814 cp.computeOutputIndexes(); |
4523 |
4815 |
4524 // rewrite CP references in the tail |
4816 // rewrite CP references in the tail |
4525 cp.computeOutputIndexes(); |
|
4526 int nextref = 0; |
4817 int nextref = 0; |
4527 for (i = 0; i < (int)class_fixup_type.size(); i++) { |
4818 for (i = 0; i < (int)class_fixup_type.size(); i++) { |
4528 int type = class_fixup_type.getByte(i); |
4819 int type = class_fixup_type.getByte(i); |
4529 byte* fixp = wp_at(class_fixup_offset.get(i)); |
4820 byte* fixp = wp_at(class_fixup_offset.get(i)); |
4530 entry* e = (entry*)class_fixup_ref.get(nextref++); |
4821 entry* e = (entry*)class_fixup_ref.get(nextref++); |
4577 break; |
4868 break; |
4578 case CONSTANT_Fieldref: |
4869 case CONSTANT_Fieldref: |
4579 case CONSTANT_Methodref: |
4870 case CONSTANT_Methodref: |
4580 case CONSTANT_InterfaceMethodref: |
4871 case CONSTANT_InterfaceMethodref: |
4581 case CONSTANT_NameandType: |
4872 case CONSTANT_NameandType: |
|
4873 case CONSTANT_InvokeDynamic: |
4582 putu2(e.refs[0]->getOutputIndex()); |
4874 putu2(e.refs[0]->getOutputIndex()); |
4583 putu2(e.refs[1]->getOutputIndex()); |
4875 putu2(e.refs[1]->getOutputIndex()); |
4584 break; |
4876 break; |
|
4877 case CONSTANT_MethodHandle: |
|
4878 putu1(e.value.i); |
|
4879 putu2(e.refs[0]->getOutputIndex()); |
|
4880 break; |
|
4881 case CONSTANT_MethodType: |
|
4882 putu2(e.refs[0]->getOutputIndex()); |
|
4883 break; |
|
4884 case CONSTANT_BootstrapMethod: // should not happen |
4585 default: |
4885 default: |
4586 abort(ERROR_INTERNAL); |
4886 abort(ERROR_INTERNAL); |
4587 } |
4887 } |
4588 } |
4888 } |
4589 |
4889 |
4618 cur_file.data[1].set(null, 0); |
4918 cur_file.data[1].set(null, 0); |
4619 if (files_written < file_count) { |
4919 if (files_written < file_count) { |
4620 entry* e = file_name.getRef(); |
4920 entry* e = file_name.getRef(); |
4621 CHECK_0; |
4921 CHECK_0; |
4622 cur_file.name = e->utf8String(); |
4922 cur_file.name = e->utf8String(); |
4623 bool haveLongSize = ((archive_options & AO_HAVE_FILE_SIZE_HI) != 0); |
4923 bool haveLongSize = (testBit(archive_options, AO_HAVE_FILE_SIZE_HI)); |
4624 cur_file.size = file_size_hi.getLong(file_size_lo, haveLongSize); |
4924 cur_file.size = file_size_hi.getLong(file_size_lo, haveLongSize); |
4625 if ((archive_options & AO_HAVE_FILE_MODTIME) != 0) |
4925 if (testBit(archive_options, AO_HAVE_FILE_MODTIME)) |
4626 cur_file.modtime += file_modtime.getInt(); //relative to archive modtime |
4926 cur_file.modtime += file_modtime.getInt(); //relative to archive modtime |
4627 if ((archive_options & AO_HAVE_FILE_OPTIONS) != 0) |
4927 if (testBit(archive_options, AO_HAVE_FILE_OPTIONS)) |
4628 cur_file.options |= file_options.getInt() & ~suppress_file_options; |
4928 cur_file.options |= file_options.getInt() & ~suppress_file_options; |
4629 } else if (classes_written < class_count) { |
4929 } else if (classes_written < class_count) { |
4630 // there is a class for a missing file record |
4930 // there is a class for a missing file record |
4631 cur_file.options |= FO_IS_CLASS_STUB; |
4931 cur_file.options |= FO_IS_CLASS_STUB; |
4632 } |
4932 } |