1 /* |
1 /* |
2 * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
30 import com.sun.java.util.jar.pack.ConstantPool.Entry; |
30 import com.sun.java.util.jar.pack.ConstantPool.Entry; |
31 import com.sun.java.util.jar.pack.ConstantPool.Index; |
31 import com.sun.java.util.jar.pack.ConstantPool.Index; |
32 import com.sun.java.util.jar.pack.ConstantPool.MemberEntry; |
32 import com.sun.java.util.jar.pack.ConstantPool.MemberEntry; |
33 import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry; |
33 import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry; |
34 import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry; |
34 import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry; |
35 import java.io.*; |
|
36 import java.util.*; |
|
37 import com.sun.java.util.jar.pack.Package.Class; |
35 import com.sun.java.util.jar.pack.Package.Class; |
38 import com.sun.java.util.jar.pack.Package.File; |
36 import com.sun.java.util.jar.pack.Package.File; |
39 import com.sun.java.util.jar.pack.Package.InnerClass; |
37 import com.sun.java.util.jar.pack.Package.InnerClass; |
|
38 import java.io.ByteArrayOutputStream; |
|
39 import java.io.EOFException; |
|
40 import java.io.PrintStream; |
|
41 import java.io.FilterInputStream; |
|
42 import java.io.BufferedInputStream; |
|
43 import java.io.InputStream; |
|
44 import java.io.IOException; |
|
45 import java.util.ArrayList; |
|
46 import java.util.Map; |
|
47 import java.util.Arrays; |
|
48 import java.util.Collection; |
|
49 import java.util.Comparator; |
|
50 import java.util.HashSet; |
|
51 import java.util.HashMap; |
|
52 import java.util.Iterator; |
|
53 import java.util.List; |
|
54 import java.util.ListIterator; |
|
55 import java.util.Set; |
|
56 import static com.sun.java.util.jar.pack.Constants.*; |
40 |
57 |
41 /** |
58 /** |
42 * Reader for a package file. |
59 * Reader for a package file. |
43 * |
60 * |
44 * @see PackageWriter |
61 * @see PackageWriter |
416 case CONSTANT_Integer: |
433 case CONSTANT_Integer: |
417 cp_Int.expectLength(cpMap.length); |
434 cp_Int.expectLength(cpMap.length); |
418 cp_Int.readFrom(in); |
435 cp_Int.readFrom(in); |
419 for (int i = 0; i < cpMap.length; i++) { |
436 for (int i = 0; i < cpMap.length; i++) { |
420 int x = cp_Int.getInt(); // coding handles signs OK |
437 int x = cp_Int.getInt(); // coding handles signs OK |
421 cpMap[i] = ConstantPool.getLiteralEntry(new Integer(x)); |
438 cpMap[i] = ConstantPool.getLiteralEntry(x); |
422 } |
439 } |
423 cp_Int.doneDisbursing(); |
440 cp_Int.doneDisbursing(); |
424 break; |
441 break; |
425 case CONSTANT_Float: |
442 case CONSTANT_Float: |
426 cp_Float.expectLength(cpMap.length); |
443 cp_Float.expectLength(cpMap.length); |
427 cp_Float.readFrom(in); |
444 cp_Float.readFrom(in); |
428 for (int i = 0; i < cpMap.length; i++) { |
445 for (int i = 0; i < cpMap.length; i++) { |
429 int x = cp_Float.getInt(); |
446 int x = cp_Float.getInt(); |
430 float fx = Float.intBitsToFloat(x); |
447 float fx = Float.intBitsToFloat(x); |
431 cpMap[i] = ConstantPool.getLiteralEntry(new Float(fx)); |
448 cpMap[i] = ConstantPool.getLiteralEntry(fx); |
432 } |
449 } |
433 cp_Float.doneDisbursing(); |
450 cp_Float.doneDisbursing(); |
434 break; |
451 break; |
435 case CONSTANT_Long: |
452 case CONSTANT_Long: |
436 // cp_Long: |
453 // cp_Long: |
442 cp_Long_lo.readFrom(in); |
459 cp_Long_lo.readFrom(in); |
443 for (int i = 0; i < cpMap.length; i++) { |
460 for (int i = 0; i < cpMap.length; i++) { |
444 long hi = cp_Long_hi.getInt(); |
461 long hi = cp_Long_hi.getInt(); |
445 long lo = cp_Long_lo.getInt(); |
462 long lo = cp_Long_lo.getInt(); |
446 long x = (hi << 32) + ((lo << 32) >>> 32); |
463 long x = (hi << 32) + ((lo << 32) >>> 32); |
447 cpMap[i] = ConstantPool.getLiteralEntry(new Long(x)); |
464 cpMap[i] = ConstantPool.getLiteralEntry(x); |
448 } |
465 } |
449 cp_Long_hi.doneDisbursing(); |
466 cp_Long_hi.doneDisbursing(); |
450 cp_Long_lo.doneDisbursing(); |
467 cp_Long_lo.doneDisbursing(); |
451 break; |
468 break; |
452 case CONSTANT_Double: |
469 case CONSTANT_Double: |
460 for (int i = 0; i < cpMap.length; i++) { |
477 for (int i = 0; i < cpMap.length; i++) { |
461 long hi = cp_Double_hi.getInt(); |
478 long hi = cp_Double_hi.getInt(); |
462 long lo = cp_Double_lo.getInt(); |
479 long lo = cp_Double_lo.getInt(); |
463 long x = (hi << 32) + ((lo << 32) >>> 32); |
480 long x = (hi << 32) + ((lo << 32) >>> 32); |
464 double dx = Double.longBitsToDouble(x); |
481 double dx = Double.longBitsToDouble(x); |
465 cpMap[i] = ConstantPool.getLiteralEntry(new Double(dx)); |
482 cpMap[i] = ConstantPool.getLiteralEntry(dx); |
466 } |
483 } |
467 cp_Double_hi.doneDisbursing(); |
484 cp_Double_hi.doneDisbursing(); |
468 cp_Double_lo.doneDisbursing(); |
485 cp_Double_lo.doneDisbursing(); |
469 break; |
486 break; |
470 case CONSTANT_String: |
487 case CONSTANT_String: |
643 cp_Utf8_prefix.doneDisbursing(); |
660 cp_Utf8_prefix.doneDisbursing(); |
644 cp_Utf8_suffix.doneDisbursing(); |
661 cp_Utf8_suffix.doneDisbursing(); |
645 cp_Utf8_big_suffix.doneDisbursing(); |
662 cp_Utf8_big_suffix.doneDisbursing(); |
646 } |
663 } |
647 |
664 |
648 HashMap utf8Signatures; // Utf8Entry->SignatureEntry |
665 Map<Utf8Entry, SignatureEntry> utf8Signatures; |
649 |
666 |
650 void readSignatureBands(Entry[] cpMap) throws IOException { |
667 void readSignatureBands(Entry[] cpMap) throws IOException { |
651 // cp_Signature: |
668 // cp_Signature: |
652 // *cp_Signature_form :DELTA5 (cp_Utf8) |
669 // *cp_Signature_form :DELTA5 (cp_Utf8) |
653 // *cp_Signature_classes :UDELTA5 (cp_Class) |
670 // *cp_Signature_classes :UDELTA5 (cp_Class) |
661 } |
678 } |
662 cp_Signature_form.resetForSecondPass(); |
679 cp_Signature_form.resetForSecondPass(); |
663 cp_Signature_classes.expectLength(getIntTotal(numSigClasses)); |
680 cp_Signature_classes.expectLength(getIntTotal(numSigClasses)); |
664 cp_Signature_classes.readFrom(in); |
681 cp_Signature_classes.readFrom(in); |
665 cp_Signature_classes.setIndex(getCPIndex(CONSTANT_Class)); |
682 cp_Signature_classes.setIndex(getCPIndex(CONSTANT_Class)); |
666 utf8Signatures = new HashMap(); |
683 utf8Signatures = new HashMap<>(); |
667 for (int i = 0; i < cpMap.length; i++) { |
684 for (int i = 0; i < cpMap.length; i++) { |
668 Utf8Entry formRef = (Utf8Entry) cp_Signature_form.getRef(); |
685 Utf8Entry formRef = (Utf8Entry) cp_Signature_form.getRef(); |
669 ClassEntry[] classRefs = new ClassEntry[numSigClasses[i]]; |
686 ClassEntry[] classRefs = new ClassEntry[numSigClasses[i]]; |
670 for (int j = 0; j < classRefs.length; j++) { |
687 for (int j = 0; j < classRefs.length; j++) { |
671 classRefs[j] = (ClassEntry) cp_Signature_classes.getRef(); |
688 classRefs[j] = (ClassEntry) cp_Signature_classes.getRef(); |
861 ic_outer_class.expectLength(longICCount); |
878 ic_outer_class.expectLength(longICCount); |
862 ic_outer_class.readFrom(in); |
879 ic_outer_class.readFrom(in); |
863 ic_name.expectLength(longICCount); |
880 ic_name.expectLength(longICCount); |
864 ic_name.readFrom(in); |
881 ic_name.readFrom(in); |
865 ic_flags.resetForSecondPass(); |
882 ic_flags.resetForSecondPass(); |
866 ArrayList icList = new ArrayList(numInnerClasses); |
883 List<InnerClass> icList = new ArrayList<>(numInnerClasses); |
867 for (int i = 0; i < numInnerClasses; i++) { |
884 for (int i = 0; i < numInnerClasses; i++) { |
868 int flags = ic_flags.getInt(); |
885 int flags = ic_flags.getInt(); |
869 boolean longForm = (flags & ACC_IC_LONG_FORM) != 0; |
886 boolean longForm = (flags & ACC_IC_LONG_FORM) != 0; |
870 flags &= ~ACC_IC_LONG_FORM; |
887 flags &= ~ACC_IC_LONG_FORM; |
871 ClassEntry thisClass = (ClassEntry) ic_this_class.getRef(); |
888 ClassEntry thisClass = (ClassEntry) ic_this_class.getRef(); |
874 if (longForm) { |
891 if (longForm) { |
875 outerClass = (ClassEntry) ic_outer_class.getRef(); |
892 outerClass = (ClassEntry) ic_outer_class.getRef(); |
876 thisName = (Utf8Entry) ic_name.getRef(); |
893 thisName = (Utf8Entry) ic_name.getRef(); |
877 } else { |
894 } else { |
878 String n = thisClass.stringValue(); |
895 String n = thisClass.stringValue(); |
879 String[] parse = pkg.parseInnerClassName(n); |
896 String[] parse = Package.parseInnerClassName(n); |
880 assert(parse != null); |
897 assert(parse != null); |
881 String pkgOuter = parse[0]; |
898 String pkgOuter = parse[0]; |
882 //String number = parse[1]; |
899 //String number = parse[1]; |
883 String name = parse[2]; |
900 String name = parse[2]; |
884 if (pkgOuter == null) |
901 if (pkgOuter == null) |
903 ic_bands.doneDisbursing(); |
920 ic_bands.doneDisbursing(); |
904 } |
921 } |
905 |
922 |
906 void readLocalInnerClasses(Class cls) throws IOException { |
923 void readLocalInnerClasses(Class cls) throws IOException { |
907 int nc = class_InnerClasses_N.getInt(); |
924 int nc = class_InnerClasses_N.getInt(); |
908 ArrayList localICs = new ArrayList(nc); |
925 List<InnerClass> localICs = new ArrayList<>(nc); |
909 for (int i = 0; i < nc; i++) { |
926 for (int i = 0; i < nc; i++) { |
910 ClassEntry thisClass = (ClassEntry) class_InnerClasses_RC.getRef(); |
927 ClassEntry thisClass = (ClassEntry) class_InnerClasses_RC.getRef(); |
911 int flags = class_InnerClasses_F.getInt(); |
928 int flags = class_InnerClasses_F.getInt(); |
912 if (flags == 0) { |
929 if (flags == 0) { |
913 // A zero flag means copy a global IC here. |
930 // A zero flag means copy a global IC here. |
992 return pkg.cp.untypedIndexOf(se); |
1009 return pkg.cp.untypedIndexOf(se); |
993 } |
1010 } |
994 return -1; |
1011 return -1; |
995 } |
1012 } |
996 |
1013 |
997 Comparator entryOutputOrder = new Comparator() { |
1014 Comparator<Entry> entryOutputOrder = new Comparator<>() { |
998 public int compare(Object o0, Object o1) { |
1015 public int compare(Entry e0, Entry e1) { |
999 Entry e0 = (Entry) o0; |
|
1000 Entry e1 = (Entry) o1; |
|
1001 int k0 = getOutputIndex(e0); |
1016 int k0 = getOutputIndex(e0); |
1002 int k1 = getOutputIndex(e1); |
1017 int k1 = getOutputIndex(e1); |
1003 if (k0 >= 0 && k1 >= 0) |
1018 if (k0 >= 0 && k1 >= 0) |
1004 // If both have keys, use the keys. |
1019 // If both have keys, use the keys. |
1005 return k0 - k1; |
1020 return k0 - k1; |
1032 // record the local cp: |
1047 // record the local cp: |
1033 cls.setCPMap(reconstructLocalCPMap(cls)); |
1048 cls.setCPMap(reconstructLocalCPMap(cls)); |
1034 } |
1049 } |
1035 |
1050 |
1036 Entry[] reconstructLocalCPMap(Class cls) { |
1051 Entry[] reconstructLocalCPMap(Class cls) { |
1037 HashSet ldcRefs = (HashSet) ldcRefMap.get(cls); |
1052 Set<Entry> ldcRefs = ldcRefMap.get(cls); |
1038 HashSet cpRefs = new HashSet(); |
1053 Set<Entry> cpRefs = new HashSet<>(); |
1039 HashSet sigSet = new HashSet(); |
|
1040 |
1054 |
1041 // look for constant pool entries: |
1055 // look for constant pool entries: |
1042 cls.visitRefs(VRM_CLASSIC, cpRefs); |
1056 cls.visitRefs(VRM_CLASSIC, cpRefs); |
1043 |
1057 |
1044 // flesh out the local constant pool |
1058 // flesh out the local constant pool |
1062 ConstantPool.completeReferencesIn(cpRefs, true); |
1076 ConstantPool.completeReferencesIn(cpRefs, true); |
1063 } |
1077 } |
1064 |
1078 |
1065 // construct a local constant pool |
1079 // construct a local constant pool |
1066 int numDoubles = 0; |
1080 int numDoubles = 0; |
1067 for (Iterator i = cpRefs.iterator(); i.hasNext(); ) { |
1081 for (Entry e : cpRefs) { |
1068 Entry e = (Entry) i.next(); |
|
1069 if (e.isDoubleWord()) numDoubles++; |
1082 if (e.isDoubleWord()) numDoubles++; |
1070 assert(e.tag != CONSTANT_Signature) : (e); |
1083 assert(e.tag != CONSTANT_Signature) : (e); |
1071 } |
1084 } |
1072 Entry[] cpMap = new Entry[1+numDoubles+cpRefs.size()]; |
1085 Entry[] cpMap = new Entry[1+numDoubles+cpRefs.size()]; |
1073 int fillp = 1; |
1086 int fillp = 1; |
1074 |
1087 |
1075 // Add all ldc operands first. |
1088 // Add all ldc operands first. |
1076 if (ldcRefs != null) { |
1089 if (ldcRefs != null) { |
1077 assert(cpRefs.containsAll(ldcRefs)); |
1090 assert(cpRefs.containsAll(ldcRefs)); |
1078 for (Iterator i = ldcRefs.iterator(); i.hasNext(); ) { |
1091 for (Entry e : ldcRefs) { |
1079 Entry e = (Entry) i.next(); |
|
1080 cpMap[fillp++] = e; |
1092 cpMap[fillp++] = e; |
1081 } |
1093 } |
1082 assert(fillp == 1+ldcRefs.size()); |
1094 assert(fillp == 1+ldcRefs.size()); |
1083 cpRefs.removeAll(ldcRefs); |
1095 cpRefs.removeAll(ldcRefs); |
1084 ldcRefs = null; // done with it |
1096 ldcRefs = null; // done with it |
1085 } |
1097 } |
1086 |
1098 |
1087 // Next add all the two-byte references. |
1099 // Next add all the two-byte references. |
1088 HashSet wideRefs = cpRefs; |
1100 Set<Entry> wideRefs = cpRefs; |
1089 cpRefs = null; // do not use! |
1101 cpRefs = null; // do not use! |
1090 int narrowLimit = fillp; |
1102 int narrowLimit = fillp; |
1091 for (Iterator i = wideRefs.iterator(); i.hasNext(); ) { |
1103 for (Entry e : wideRefs) { |
1092 Entry e = (Entry) i.next(); |
|
1093 cpMap[fillp++] = e; |
1104 cpMap[fillp++] = e; |
1094 } |
1105 } |
1095 assert(fillp == narrowLimit+wideRefs.size()); |
1106 assert(fillp == narrowLimit+wideRefs.size()); |
1096 Arrays.sort(cpMap, 1, narrowLimit, entryOutputOrder); |
1107 Arrays.sort(cpMap, 1, narrowLimit, entryOutputOrder); |
1097 Arrays.sort(cpMap, narrowLimit, fillp, entryOutputOrder); |
1108 Arrays.sort(cpMap, narrowLimit, fillp, entryOutputOrder); |
1142 int totalNM = class_method_count.getIntTotal(); |
1153 int totalNM = class_method_count.getIntTotal(); |
1143 field_descr.expectLength(totalNF); |
1154 field_descr.expectLength(totalNF); |
1144 method_descr.expectLength(totalNM); |
1155 method_descr.expectLength(totalNM); |
1145 if (verbose > 1) Utils.log.fine("expecting #fields="+totalNF+" and #methods="+totalNM+" in #classes="+numClasses); |
1156 if (verbose > 1) Utils.log.fine("expecting #fields="+totalNF+" and #methods="+totalNM+" in #classes="+numClasses); |
1146 |
1157 |
1147 ArrayList fields = new ArrayList(totalNF); |
1158 List<Class.Field> fields = new ArrayList<>(totalNF); |
1148 field_descr.readFrom(in); |
1159 field_descr.readFrom(in); |
1149 for (int i = 0; i < classes.length; i++) { |
1160 for (int i = 0; i < classes.length; i++) { |
1150 Class c = classes[i]; |
1161 Class c = classes[i]; |
1151 int nf = class_field_count.getInt(); |
1162 int nf = class_field_count.getInt(); |
1152 for (int j = 0; j < nf; j++) { |
1163 for (int j = 0; j < nf; j++) { |
1158 class_field_count.doneDisbursing(); |
1169 class_field_count.doneDisbursing(); |
1159 field_descr.doneDisbursing(); |
1170 field_descr.doneDisbursing(); |
1160 countAndReadAttrs(ATTR_CONTEXT_FIELD, fields); |
1171 countAndReadAttrs(ATTR_CONTEXT_FIELD, fields); |
1161 fields = null; // release to GC |
1172 fields = null; // release to GC |
1162 |
1173 |
1163 ArrayList methods = new ArrayList(totalNM); |
1174 List<Class.Method> methods = new ArrayList<>(totalNM); |
1164 method_descr.readFrom(in); |
1175 method_descr.readFrom(in); |
1165 for (int i = 0; i < classes.length; i++) { |
1176 for (int i = 0; i < classes.length; i++) { |
1166 Class c = classes[i]; |
1177 Class c = classes[i]; |
1167 int nm = class_method_count.getInt(); |
1178 int nm = class_method_count.getInt(); |
1168 for (int j = 0; j < nm; j++) { |
1179 for (int j = 0; j < nm; j++) { |
1180 // attributes stay in the method attribute lists, however. |
1191 // attributes stay in the method attribute lists, however. |
1181 allCodes = buildCodeAttrs(methods); |
1192 allCodes = buildCodeAttrs(methods); |
1182 } |
1193 } |
1183 |
1194 |
1184 Code[] allCodes; |
1195 Code[] allCodes; |
1185 List codesWithFlags; |
1196 List<Code> codesWithFlags; |
1186 HashMap ldcRefMap = new HashMap(); // HashMap<Class, HashSet<Entry>> |
1197 Map<Class, Set<Entry>> ldcRefMap = new HashMap<>(); |
1187 |
1198 |
1188 Code[] buildCodeAttrs(List methods) { |
1199 Code[] buildCodeAttrs(List<Class.Method> methods) { |
1189 ArrayList codes = new ArrayList(methods.size()); |
1200 List<Code> codes = new ArrayList<>(methods.size()); |
1190 for (Iterator i = methods.iterator(); i.hasNext(); ) { |
1201 for (Class.Method m : methods) { |
1191 Class.Method m = (Class.Method) i.next(); |
|
1192 if (m.getAttribute(attrCodeEmpty) != null) { |
1202 if (m.getAttribute(attrCodeEmpty) != null) { |
1193 m.code = new Code(m); |
1203 m.code = new Code(m); |
1194 codes.add(m.code); |
1204 codes.add(m.code); |
1195 } |
1205 } |
1196 } |
1206 } |
1209 // ... |
1219 // ... |
1210 // code_attr_bands |
1220 // code_attr_bands |
1211 boolean attrsOK = testBit(archiveOptions, AO_HAVE_ALL_CODE_FLAGS); |
1221 boolean attrsOK = testBit(archiveOptions, AO_HAVE_ALL_CODE_FLAGS); |
1212 code_headers.expectLength(allCodes.length); |
1222 code_headers.expectLength(allCodes.length); |
1213 code_headers.readFrom(in); |
1223 code_headers.readFrom(in); |
1214 ArrayList longCodes = new ArrayList(allCodes.length / 10); |
1224 List<Code> longCodes = new ArrayList<>(allCodes.length / 10); |
1215 for (int i = 0; i < allCodes.length; i++) { |
1225 for (int i = 0; i < allCodes.length; i++) { |
1216 Code c = allCodes[i]; |
1226 Code c = allCodes[i]; |
1217 int sc = code_headers.getByte(); |
1227 int sc = code_headers.getByte(); |
1218 assert(sc == (sc & 0xFF)); |
1228 assert(sc == (sc & 0xFF)); |
1219 if (verbose > 2) |
1229 if (verbose > 2) |
1236 |
1246 |
1237 // Do the long headers now. |
1247 // Do the long headers now. |
1238 code_max_stack.readFrom(in); |
1248 code_max_stack.readFrom(in); |
1239 code_max_na_locals.readFrom(in); |
1249 code_max_na_locals.readFrom(in); |
1240 code_handler_count.readFrom(in); |
1250 code_handler_count.readFrom(in); |
1241 for (Iterator i = longCodes.iterator(); i.hasNext(); ) { |
1251 for (Code c : longCodes) { |
1242 Code c = (Code) i.next(); |
|
1243 c.setMaxStack( code_max_stack.getInt() ); |
1252 c.setMaxStack( code_max_stack.getInt() ); |
1244 c.setMaxNALocals( code_max_na_locals.getInt() ); |
1253 c.setMaxNALocals( code_max_na_locals.getInt() ); |
1245 c.setHandlerCount( code_handler_count.getInt() ); |
1254 c.setHandlerCount( code_handler_count.getInt() ); |
1246 } |
1255 } |
1247 code_max_stack.doneDisbursing(); |
1256 code_max_stack.doneDisbursing(); |
1384 Utils.log.fine("scanning flags and attrs for "+Attribute.contextName(ctype)+"["+holders.size()+"]"); |
1393 Utils.log.fine("scanning flags and attrs for "+Attribute.contextName(ctype)+"["+holders.size()+"]"); |
1385 } |
1394 } |
1386 |
1395 |
1387 // Fetch the attribute layout definitions which govern the bands |
1396 // Fetch the attribute layout definitions which govern the bands |
1388 // we are about to read. |
1397 // we are about to read. |
1389 Attribute.Layout[] defs = new Attribute.Layout[attrDefs[ctype].size()]; |
1398 List<Attribute.Layout> defList = attrDefs.get(ctype); |
1390 attrDefs[ctype].toArray(defs); |
1399 Attribute.Layout[] defs = new Attribute.Layout[defList.size()]; |
|
1400 defList.toArray(defs); |
1391 IntBand xxx_flags_hi = getAttrBand(xxx_attr_bands, AB_FLAGS_HI); |
1401 IntBand xxx_flags_hi = getAttrBand(xxx_attr_bands, AB_FLAGS_HI); |
1392 IntBand xxx_flags_lo = getAttrBand(xxx_attr_bands, AB_FLAGS_LO); |
1402 IntBand xxx_flags_lo = getAttrBand(xxx_attr_bands, AB_FLAGS_LO); |
1393 IntBand xxx_attr_count = getAttrBand(xxx_attr_bands, AB_ATTR_COUNT); |
1403 IntBand xxx_attr_count = getAttrBand(xxx_attr_bands, AB_ATTR_COUNT); |
1394 IntBand xxx_attr_indexes = getAttrBand(xxx_attr_bands, AB_ATTR_INDEXES); |
1404 IntBand xxx_attr_indexes = getAttrBand(xxx_attr_bands, AB_ATTR_INDEXES); |
1395 IntBand xxx_attr_calls = getAttrBand(xxx_attr_bands, AB_ATTR_CALLS); |
1405 IntBand xxx_attr_calls = getAttrBand(xxx_attr_bands, AB_ATTR_CALLS); |
1448 for (int ai = 0; bits != 0; ai++) { |
1458 for (int ai = 0; bits != 0; ai++) { |
1449 if ((bits & (1L<<ai)) == 0) continue; |
1459 if ((bits & (1L<<ai)) == 0) continue; |
1450 bits -= (1L<<ai); |
1460 bits -= (1L<<ai); |
1451 nfa += 1; |
1461 nfa += 1; |
1452 } |
1462 } |
1453 ArrayList ha = new ArrayList(nfa + noa); |
1463 List<Attribute> ha = new ArrayList<>(nfa + noa); |
1454 h.attributes = ha; |
1464 h.attributes = ha; |
1455 bits = attrBits; // iterate again |
1465 bits = attrBits; // iterate again |
1456 for (int ai = 0; bits != 0; ai++) { |
1466 for (int ai = 0; bits != 0; ai++) { |
1457 if ((bits & (1L<<ai)) == 0) continue; |
1467 if ((bits & (1L<<ai)) == 0) continue; |
1458 bits -= (1L<<ai); |
1468 bits -= (1L<<ai); |
1514 Attribute.Layout def = defs[ai]; |
1524 Attribute.Layout def = defs[ai]; |
1515 if (def == null) continue; // unused index |
1525 if (def == null) continue; // unused index |
1516 if (predef != isPredefinedAttr(ctype, ai)) |
1526 if (predef != isPredefinedAttr(ctype, ai)) |
1517 continue; // wrong pass |
1527 continue; // wrong pass |
1518 int totalCount = totalCounts[ai]; |
1528 int totalCount = totalCounts[ai]; |
1519 Band[] ab = (Band[]) attrBandTable.get(def); |
1529 Band[] ab = attrBandTable.get(def); |
1520 if (def == attrInnerClassesEmpty) { |
1530 if (def == attrInnerClassesEmpty) { |
1521 // Special case. |
1531 // Special case. |
1522 // Size the bands as if using the following layout: |
1532 // Size the bands as if using the following layout: |
1523 // [RCH TI[ (0)[] ()[RCNH RUNH] ]]. |
1533 // [RCH TI[ (0)[] ()[RCNH RUNH] ]]. |
1524 class_InnerClasses_N.expectLength(totalCount); |
1534 class_InnerClasses_N.expectLength(totalCount); |
1569 void badAttrIndex(int ai, int ctype) throws IOException { |
1579 void badAttrIndex(int ai, int ctype) throws IOException { |
1570 throw new IOException("Unknown attribute index "+ai+" for "+ |
1580 throw new IOException("Unknown attribute index "+ai+" for "+ |
1571 ATTR_CONTEXT_NAME[ctype]+" attribute"); |
1581 ATTR_CONTEXT_NAME[ctype]+" attribute"); |
1572 } |
1582 } |
1573 |
1583 |
|
1584 @SuppressWarnings("unchecked") |
1574 void readAttrs(int ctype, Collection holders) throws IOException { |
1585 void readAttrs(int ctype, Collection holders) throws IOException { |
1575 // Decode band values into attributes. |
1586 // Decode band values into attributes. |
1576 HashSet sawDefs = new HashSet(); |
1587 Set<Attribute.Layout> sawDefs = new HashSet<>(); |
1577 ByteArrayOutputStream buf = new ByteArrayOutputStream(); |
1588 ByteArrayOutputStream buf = new ByteArrayOutputStream(); |
1578 for (Iterator i = holders.iterator(); i.hasNext(); ) { |
1589 for (Iterator i = holders.iterator(); i.hasNext(); ) { |
1579 final Attribute.Holder h = (Attribute.Holder) i.next(); |
1590 final Attribute.Holder h = (Attribute.Holder) i.next(); |
1580 if (h.attributes == null) continue; |
1591 if (h.attributes == null) continue; |
1581 for (ListIterator j = h.attributes.listIterator(); j.hasNext(); ) { |
1592 for (ListIterator<Attribute> j = h.attributes.listIterator(); j.hasNext(); ) { |
1582 Attribute a = (Attribute) j.next(); |
1593 Attribute a = j.next(); |
1583 Attribute.Layout def = a.layout(); |
1594 Attribute.Layout def = a.layout(); |
1584 if (def.bandCount == 0) { |
1595 if (def.bandCount == 0) { |
1585 if (def == attrInnerClassesEmpty) { |
1596 if (def == attrInnerClassesEmpty) { |
1586 // Special logic to read this attr. |
1597 // Special logic to read this attr. |
1587 readLocalInnerClasses((Class) h); |
1598 readLocalInnerClasses((Class) h); |
1593 sawDefs.add(def); |
1604 sawDefs.add(def); |
1594 boolean isCV = (ctype == ATTR_CONTEXT_FIELD && def == attrConstantValue); |
1605 boolean isCV = (ctype == ATTR_CONTEXT_FIELD && def == attrConstantValue); |
1595 if (isCV) setConstantValueIndex((Class.Field)h); |
1606 if (isCV) setConstantValueIndex((Class.Field)h); |
1596 if (verbose > 2) |
1607 if (verbose > 2) |
1597 Utils.log.fine("read "+a+" in "+h); |
1608 Utils.log.fine("read "+a+" in "+h); |
1598 final Band[] ab = (Band[]) attrBandTable.get(def); |
1609 final Band[] ab = attrBandTable.get(def); |
1599 // Read one attribute of type def from ab into a byte array. |
1610 // Read one attribute of type def from ab into a byte array. |
1600 buf.reset(); |
1611 buf.reset(); |
1601 Object fixups = a.unparse(new Attribute.ValueStream() { |
1612 Object fixups = a.unparse(new Attribute.ValueStream() { |
1602 public int getInt(int bandIndex) { |
1613 public int getInt(int bandIndex) { |
1603 return ((IntBand) ab[bandIndex]).getInt(); |
1614 return ((IntBand) ab[bandIndex]).getInt(); |
1615 if (isCV) setConstantValueIndex(null); // clean up |
1626 if (isCV) setConstantValueIndex(null); // clean up |
1616 } |
1627 } |
1617 } |
1628 } |
1618 |
1629 |
1619 // Mark the bands we just used as done disbursing. |
1630 // Mark the bands we just used as done disbursing. |
1620 for (Iterator i = sawDefs.iterator(); i.hasNext(); ) { |
1631 for (Attribute.Layout def : sawDefs) { |
1621 Attribute.Layout def = (Attribute.Layout) i.next(); |
|
1622 if (def == null) continue; // unused index |
1632 if (def == null) continue; // unused index |
1623 Band[] ab = (Band[]) attrBandTable.get(def); |
1633 Band[] ab = attrBandTable.get(def); |
1624 for (int j = 0; j < ab.length; j++) { |
1634 for (int j = 0; j < ab.length; j++) { |
1625 ab[j].doneDisbursing(); |
1635 ab[j].doneDisbursing(); |
1626 } |
1636 } |
1627 } |
1637 } |
1628 |
1638 |
1776 |
1786 |
1777 private void readByteCodeOps() throws IOException { |
1787 private void readByteCodeOps() throws IOException { |
1778 // scratch buffer for collecting code:: |
1788 // scratch buffer for collecting code:: |
1779 byte[] buf = new byte[1<<12]; |
1789 byte[] buf = new byte[1<<12]; |
1780 // record of all switch opcodes (these are variable-length) |
1790 // record of all switch opcodes (these are variable-length) |
1781 ArrayList allSwitchOps = new ArrayList(); |
1791 List<Integer> allSwitchOps = new ArrayList<>(); |
1782 for (int k = 0; k < allCodes.length; k++) { |
1792 for (int k = 0; k < allCodes.length; k++) { |
1783 Code c = allCodes[k]; |
1793 Code c = allCodes[k]; |
1784 scanOneMethod: |
1794 scanOneMethod: |
1785 for (int i = 0; ; i++) { |
1795 for (int i = 0; ; i++) { |
1786 int bc = bc_codes.getByte(); |
1796 int bc = bc_codes.getByte(); |
1864 } |
1874 } |
1865 } |
1875 } |
1866 |
1876 |
1867 // To size instruction bands correctly, we need info on switches: |
1877 // To size instruction bands correctly, we need info on switches: |
1868 bc_case_count.readFrom(in); |
1878 bc_case_count.readFrom(in); |
1869 for (Iterator i = allSwitchOps.iterator(); i.hasNext(); ) { |
1879 for (Integer i : allSwitchOps) { |
1870 int bc = ((Integer)i.next()).intValue(); |
1880 int bc = i.intValue(); |
1871 int caseCount = bc_case_count.getInt(); |
1881 int caseCount = bc_case_count.getInt(); |
1872 bc_label.expectMoreLength(1+caseCount); // default label + cases |
1882 bc_label.expectMoreLength(1+caseCount); // default label + cases |
1873 bc_case_value.expectMoreLength(bc == _tableswitch ? 1 : caseCount); |
1883 bc_case_value.expectMoreLength(bc == _tableswitch ? 1 : caseCount); |
1874 } |
1884 } |
1875 bc_case_count.resetForSecondPass(); |
1885 bc_case_count.resetForSecondPass(); |
1890 byte[] codeOps = code.bytes; |
1900 byte[] codeOps = code.bytes; |
1891 code.bytes = null; // just for now, while we accumulate bits |
1901 code.bytes = null; // just for now, while we accumulate bits |
1892 |
1902 |
1893 Class curClass = code.thisClass(); |
1903 Class curClass = code.thisClass(); |
1894 |
1904 |
1895 HashSet ldcRefSet = (HashSet) ldcRefMap.get(curClass); |
1905 Set<Entry> ldcRefSet = ldcRefMap.get(curClass); |
1896 if (ldcRefSet == null) |
1906 if (ldcRefSet == null) |
1897 ldcRefMap.put(curClass, ldcRefSet = new HashSet()); |
1907 ldcRefMap.put(curClass, ldcRefSet = new HashSet<>()); |
1898 |
1908 |
1899 ClassEntry thisClass = curClass.thisClass; |
1909 ClassEntry thisClass = curClass.thisClass; |
1900 ClassEntry superClass = curClass.superClass; |
1910 ClassEntry superClass = curClass.superClass; |
1901 ClassEntry newClass = null; // class of last _new opcode |
1911 ClassEntry newClass = null; // class of last _new opcode |
1902 |
1912 |