1 34 package jarg; 35 36 import java.util.Arrays ; 37 import java.util.Comparator ; 38 39 import org.apache.bcel.classfile.*; 40 import org.apache.bcel.generic.*; 41 import org.apache.bcel.Constants; 42 43 49 class ConstantPoolSorter { 50 private ConstantPoolSorter() { 51 } 52 53 static ConstantPoolGen reshapeConstantPool(Constant[] cs) { 54 Constant[] css = (Constant[])cs.clone(); 56 57 Arrays.sort(css, cpcomparator); 59 System.arraycopy(css, 0, css, 1, css.length-1); 60 css[0] = null; 61 62 for (int i=1; i<css.length-2; i++) { 64 Constant c = css[i]; 65 if (c != null) { 66 switch (c.getTag()) { 67 case Constants.CONSTANT_Long: 68 case Constants.CONSTANT_Double: 69 System.arraycopy(css, i+1, css, i+2, css.length-(i+2)); 70 css[i+1] = null; 71 break; 72 } 73 } 74 } 75 76 Constant[] newcs = new Constant[css.length]; 78 try { 79 for (int i=0; i<css.length; i++) { 80 Constant c = css[i]; 81 if (c != null) { 82 Constant cc = (Constant)c.clone(); 83 reindexConstants(cc, css, cs); 84 newcs[i] = cc; 85 } 86 } 87 } catch (CloneNotSupportedException ex) { 88 ex.printStackTrace(); 89 } 90 ConstantPoolGen cpg = new ConstantPoolGen(newcs); 91 92 return cpg; 100 } 101 102 private static CPComparator cpcomparator = new CPComparator(); 103 private static class CPComparator implements Comparator { 104 public int compare(Object o1, Object o2) { 105 Constant c1 = (Constant)o1; 106 Constant c2 = (Constant)o2; 107 int r = 0; 108 109 if (o1 == null) { 110 return 1; 111 } 112 if (o2 == null) { 113 return -1; 114 } 115 byte t1 = c1.getTag(); 116 byte t2 = c2.getTag(); 117 if (t1 != t2) { 118 r = getSortWeightOfConstantPoolTag(t1) 119 - getSortWeightOfConstantPoolTag(t2); 120 } else { 121 switch (t1) { 122 case Constants.CONSTANT_Utf8: { 123 ConstantUtf8 u1 = (ConstantUtf8)c1; 124 ConstantUtf8 u2 = (ConstantUtf8)c2; 125 r = u1.getBytes().compareTo(u2.getBytes()); 126 } break; 127 case Constants.CONSTANT_String: { 128 ConstantString s1 = (ConstantString)c1; 129 ConstantString s2 = (ConstantString)c2; 130 r = s1.getStringIndex() - s2.getStringIndex(); 131 } break; 132 case Constants.CONSTANT_NameAndType: { 133 ConstantNameAndType n1 = (ConstantNameAndType)c1; 134 ConstantNameAndType n2 = (ConstantNameAndType)c2; 135 r = n1.getNameIndex() - n2.getNameIndex(); 136 if (r == 0) { 137 r = n1.getSignatureIndex() - n2.getSignatureIndex(); 138 } 139 } break; 140 case Constants.CONSTANT_Class: { 141 ConstantClass s1 = (ConstantClass)c1; 142 ConstantClass s2 = (ConstantClass)c2; 143 r = s1.getNameIndex() - s2.getNameIndex(); 144 } break; 145 case Constants.CONSTANT_Fieldref: { 146 ConstantFieldref f1 = (ConstantFieldref)c1; 147 ConstantFieldref f2 = (ConstantFieldref)c2; 148 r = f1.getClassIndex() - f2.getClassIndex(); 149 if (r == 0) { 150 r = f1.getNameAndTypeIndex() - f2.getNameAndTypeIndex(); 151 } 152 } break; 153 case Constants.CONSTANT_Methodref: { 154 ConstantMethodref f1 = (ConstantMethodref)c1; 155 ConstantMethodref f2 = (ConstantMethodref)c2; 156 r = f1.getClassIndex() - f2.getClassIndex(); 157 if (r == 0) { 158 r = f1.getNameAndTypeIndex() - f2.getNameAndTypeIndex(); 159 } 160 } break; 161 case Constants.CONSTANT_InterfaceMethodref: { 162 ConstantInterfaceMethodref f1 = (ConstantInterfaceMethodref)c1; 163 ConstantInterfaceMethodref f2 = (ConstantInterfaceMethodref)c2; 164 r = f1.getClassIndex() - f2.getClassIndex(); 165 if (r == 0) { 166 r = f1.getNameAndTypeIndex() - f2.getNameAndTypeIndex(); 167 } 168 } break; 169 case Constants.CONSTANT_Integer: { 170 ConstantInteger n1 = (ConstantInteger)c1; 171 ConstantInteger n2 = (ConstantInteger)c2; 172 r = n1.getBytes() - n2.getBytes(); 173 } break; 174 case Constants.CONSTANT_Float: { 175 ConstantFloat n1 = (ConstantFloat)c1; 176 ConstantFloat n2 = (ConstantFloat)c2; 177 float nn1 = n1.getBytes(); 178 float nn2 = n2.getBytes(); 179 if (nn1 < nn2) { r = -1; 180 } else if (nn1 > nn2) { r = 1; 181 } else { r = 0; 182 } 183 } break; 184 case Constants.CONSTANT_Long: { 185 ConstantLong n1 = (ConstantLong)c1; 186 ConstantLong n2 = (ConstantLong)c2; 187 long nn1 = n1.getBytes(); 188 long nn2 = n2.getBytes(); 189 if (nn1 < nn2) { r = -1; 190 } else if (nn1 > nn2) { r = 1; 191 } else { r = 0; 192 } 193 } break; 194 case Constants.CONSTANT_Double: { 195 ConstantDouble n1 = (ConstantDouble)c1; 196 ConstantDouble n2 = (ConstantDouble)c2; 197 double nn1 = n1.getBytes(); 198 double nn2 = n2.getBytes(); 199 if (nn1 < nn2) { r = -1; 200 } else if (nn1 > nn2) { r = 1; 201 } else { r = 0; 202 } 203 } break; 204 default: throw new RuntimeException ("Unknown constant tag : " + t1); 206 } 207 } 208 return r; 209 } 210 public boolean equals(Object obj) { 211 return false; 212 } 213 } 214 215 private static int getSortWeightOfConstantPoolTag(int tag) { 216 int r = 0; 217 switch (tag) { 218 case Constants.CONSTANT_String: r = 1; break; 219 case Constants.CONSTANT_NameAndType: r = 2; break; 220 case Constants.CONSTANT_Fieldref: r = 3; break; 221 case Constants.CONSTANT_Methodref: r = 4; break; 222 case Constants.CONSTANT_InterfaceMethodref: r = 5; break; 223 case Constants.CONSTANT_Class: r = 6; break; 224 case Constants.CONSTANT_Integer: r = 7; break; 225 case Constants.CONSTANT_Float: r = 8; break; 226 case Constants.CONSTANT_Long: r = 9; break; 227 case Constants.CONSTANT_Double: r = 10; break; 228 case Constants.CONSTANT_Utf8: r = 11; break; 229 default: throw new RuntimeException ("Unknown constant tag : " + tag); 242 } 243 return r; 244 } 245 246 private static int findIndex(Constant[] cs, Constant c) { 247 for (int i=0; i<cs.length; i++) { 248 if (cs[i] == c) { 249 return i; 250 } 251 } 252 return -1; 253 } 254 255 private static void reindexConstants(Constant c, Constant[] css, Constant[] constants) { 256 switch(c.getTag()) { 257 case Constants.CONSTANT_String: { 258 ConstantString s = (ConstantString)c; 259 ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()]; 260 int idx = findIndex(css, u8); 261 s.setStringIndex(idx); 262 } break; 263 case Constants.CONSTANT_Class: { 264 ConstantClass s = (ConstantClass)c; 265 ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()]; 266 int idx = findIndex(css, u8); 267 s.setNameIndex(idx); 268 } break; 269 case Constants.CONSTANT_NameAndType: { 270 ConstantNameAndType n = (ConstantNameAndType)c; 271 ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()]; 272 ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()]; 273 int idx = findIndex(css, u8); 274 int idx2 = findIndex(css, u8_2); 275 n.setNameIndex(idx); 276 n.setSignatureIndex(idx2); 277 } break; 278 case Constants.CONSTANT_Utf8: 279 case Constants.CONSTANT_Double: 280 case Constants.CONSTANT_Float: 281 case Constants.CONSTANT_Long: 282 case Constants.CONSTANT_Integer: 283 break; 284 case Constants.CONSTANT_InterfaceMethodref: 285 case Constants.CONSTANT_Methodref: 286 case Constants.CONSTANT_Fieldref: { 287 ConstantCP m = (ConstantCP)c; 288 ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()]; 289 ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()]; 290 int idx = findIndex(css, clazz); 291 int idx2 = findIndex(css, n); 292 m.setClassIndex(idx); 293 m.setNameAndTypeIndex(idx2); 294 } break; 295 default: throw new RuntimeException ("Unknown constant type " + c); 297 } 298 } 299 300 } 367
| Popular Tags
|