1 30 31 38 39 package jbet; 40 import java.io.PrintStream ; 41 import java.util.*; 42 43 public class ProgramInfo 44 { 45 private ClassFilter system; 46 private ClassFilter rename; 47 public Hashtable classes; public Hashtable externs; public Hashtable renames; public String mainclass; 52 public static class PClass 53 { 54 public ClassInfo cr; public DagClassInfo vcr; public int flags; 57 public PClass superclass; 58 public Vector interfaces; 60 public static final int External = 1; public static final String [] flagnames = {"External"}; 62 63 public String toString() { 64 return cr.name() + " " + Util.flags2str (flags, flagnames); 65 } 66 67 public PClass interfaceAt (int i) { 68 return (PClass) interfaces.elementAt (i); 69 } 70 71 PClass() {} 72 73 PClass (ClassInfo _cr) { 74 cr = _cr; 75 superclass = null; 76 } 77 78 PClass (ClassInfo _cr, ProgramInfo pi) throws ClassFileException { 79 this (_cr, pi, false); 80 } 81 82 PClass (ClassInfo _cr, ProgramInfo pi, boolean load) throws ClassFileException { 83 cr = _cr; 84 85 if (cr.getSuperName() != null) { 86 superclass = (PClass) pi.classes.get (_cr.getSuperName()); 87 88 if (load && superclass == null) 89 throw new ClassFileNotFoundException (_cr.getSuperName()); 90 91 else if (superclass == null) 92 superclass = (PClass) pi.externs.get (_cr.getSuperName ()); 93 if (superclass == null) 94 throw new IllegalStateException ("cannot find superclass: " + _cr.getSuperName()); 95 } 96 97 if (cr.numInterfaces() > 0) { 98 interfaces = new Vector(); 99 100 for (int i = 0; i < cr.numInterfaces(); i++) { 101 String iname = cr.interfaceAt (i); 102 Object o = pi.classes.get (iname); 103 104 if (o == null) 105 o = pi.externs.get (iname); 106 107 if (o == null && load) { 108 throw new ClassFileNotFoundException (iname); 109 } 110 111 interfaces.addElement (o); 112 } 113 } 114 else 115 interfaces = Util.emptyVector; 116 } 117 } 118 119 public PClass getClassI (String name) 120 { 121 return (PClass) classes.get (name); 122 } 123 124 public PClass add (ClassInfo cr) throws ClassFileException 125 { 126 PClass ci = new PClass (); 127 128 ci.cr = cr; 129 130 if (rename.check (cr)) 131 renames.put (cr, "java/lang/Object"); 132 else if (system.check (cr)) { 133 ci.flags |= PClass.External; 134 externs.put (cr.name(), ci); 135 return ci; 136 } 137 else 138 renames.put (cr, cr.name()); 139 140 if (cr.getSuperName() != null) { 141 Object o = classes.get (cr.getSuperName()); 142 if (o == null) 143 o = externs.get (cr.getSuperName()); 144 145 if (o == null) 146 ci.superclass = add (Jbet.loader.getClass (cr.getSuperName())); 147 else 148 ci.superclass = (PClass) o; 149 } 150 151 if (cr.numInterfaces() > 0) { 152 ci.interfaces = new Vector(); 153 154 for (int i = 0; i < cr.numInterfaces(); i++) { 155 String iname = cr.interfaceAt (i); 156 Object o = classes.get (iname); 157 158 if (o == null) 159 o = externs.get (iname); 160 161 if (o == null) 162 ci.interfaces.addElement (add (Jbet.loader.getClass (iname))); 163 else 164 ci.interfaces.addElement (o); 165 } 166 } 167 else 168 ci.interfaces = Util.emptyVector; 169 170 HashSet newclasses = new HashSet(); 171 HashSet newexterns = new HashSet(); 172 boolean extern = false; 173 174 for (int i = 0; i < cr.numMethods(); i++) { 175 MethodInfo mi = cr.methodAt (i); 176 177 if (mi.code != null) { 178 179 if (mi.code.numEx() != 0) 180 for (int j = 0; j < mi.code.numEx(); j++) { 181 ExceptionRec er = mi.code.exAt (j); 182 183 if (er.catchType != null) 184 if (null == classes.get (er.catchType)) 185 add (Jbet.loader.getClass (er.catchType)); 186 } 187 188 for (Instruction ins = mi.code.first(); ins != null; ins = ins.next) { 189 if ((ins.usesClass() || ins.usesMethod()) && !ins.classRef().startsWith ("[")) { 190 if (rename.check (ins.classRef()) || !system.check (ins.classRef())) { 191 if (classes.get (ins.classRef()) == null) 192 newclasses.add (ins.classRef()); 193 } 194 else { 195 newexterns.add (ins.classRef()); 196 if (ins.descriptor() != null) { 197 if (ins.descriptor().ret.base == 'L') { 198 newexterns.add (ins.descriptor().ret.cname); 199 } 200 } 201 } 202 } 203 } 204 } else if ((mi.accessFlags & MethodInfo.ACC_NATIVE) != 0) { 205 if (mi.descriptor.ret.base == 'L') { 206 newexterns.add (mi.descriptor.ret.cname); 207 } 208 extern = true; 209 } 210 } 211 212 if (extern) { 213 ci.flags |= PClass.External; 214 externs.put (cr.name(), ci); 215 } else { 216 classes.put (cr.name(), ci); 217 218 for (Iterator i = newclasses.iterator(); i.hasNext(); ) { 219 String n = (String ) i.next(); 220 if (classes.get (n) == null && externs.get (n) == null) { 221 add (Jbet.loader.getClass (n)); 222 } 223 } 224 225 226 for (Iterator i = newexterns.iterator(); i.hasNext(); ) { 227 String n = (String ) i.next(); 228 PClass ci2 = new PClass(); 229 230 ci2.flags = PClass.External; 231 ci2.cr = Jbet.loader.getClass (n); 232 externs.put (n, ci2); 233 } 234 } 235 236 return ci; 237 } 238 240 247 248 public ProgramInfo (ClassInfo main, final ClassFilter systemc) throws ClassFileException 249 { 250 this (main, systemc, ClassFilter.NONE); 251 } 252 253 public ProgramInfo (ClassInfo main, final ClassFilter systemc, final ClassFilter renamec) throws ClassFileException 254 { 255 classes = new Hashtable(); 256 externs = new Hashtable(); 257 renames = new Hashtable(); 258 system = systemc; 259 rename = renamec; 260 261 add (main); 262 mainclass = main.name(); 263 } 264 265 public void finish () throws ClassFileException 266 { 267 String n = newPrivateName(); 268 269 for (Iterator i = new HashSet (renames.keySet()).iterator(); i.hasNext(); ) { 270 Object z = i.next(); 271 if ("java/lang/Object".equals (renames.get (z))) 272 renames.put (z, n + z.toString().replace ('/','$')); 273 } 274 275 Hashtable subs = new Hashtable(); 276 for (Iterator i = renames.keySet().iterator(); i.hasNext(); ) { 277 Object z = i.next(); 278 subs.put (z.toString(), renames.get (z).toString ()); 279 } 280 281 for (Iterator i = renames.keySet().iterator(); i.hasNext(); ) { 282 ClassInfo cr = (ClassInfo) i.next(); 283 ClassInfo newcr = new ClassInfo(cr); 284 285 newcr.relocate(subs); 286 newcr.dirty = true; 287 renames.put (cr, newcr); 288 289 Jbet.loader.putClass (newcr); 290 } 291 292 Hashtable oldc = classes; 293 classes = new Hashtable(); 294 295 for (Iterator i = renames.keySet().iterator(); i.hasNext(); ) { 296 Object z = i.next(); 297 PClass ci = (PClass) oldc.get (z.toString()); 298 299 if (ci == null) 300 throw new NullPointerException ("class not in list: " + z + " : " + z.getClass().getName()); 301 302 ci.cr = (ClassInfo) renames.get (z); 303 304 classes.put (ci.cr.name(), ci); 305 } 306 } 307 308 public void printinfo (PrintStream out) 309 { 310 out.println ("Main class " + mainclass); 311 312 for (Iterator i = classes.values().iterator(); i.hasNext(); ) { 313 out.println ("intern " + i.next()); 314 } 315 316 for (Iterator i = externs.values().iterator(); i.hasNext(); ) { 317 out.println ("extern " + i.next()); 318 } 319 } 320 321 public String newPrivateName () { 322 ClassInfo main = getClassI (mainclass).cr; 323 int n = 1; 324 while (null != classes.get (main.name() + "$" + n)) n++; 325 326 return main.name() + "$" + n; 327 } 328 329 public ClassInfo addPrivateClass () { 330 ClassInfo main = getClassI (mainclass).cr; 331 ClassInfo out = new ClassInfo (main.classPathElement, newPrivateName()); 332 try { 333 classes.put (out.name(), new PClass (out, this)); 334 return out; 335 } catch (ClassFileException e) { 336 throw new IllegalStateException ("could not add new class"); 337 } 338 } 339 340 public ClassInfo addPrivateClassFrom (ClassInfo in) throws ClassFileException { 341 Hashtable tmp = new Hashtable(); 342 tmp.put (in, newPrivateName()); 343 Util.RenameClasses (tmp, true); 344 return (ClassInfo) tmp.get (in); 345 } 346 347 348 349 public MethodInfo getclinit () { 350 ClassInfo mc = getClassI(mainclass).cr; 351 MethodInfo mi = mc.findMethod ("<clinit>", Descriptor.Void); 352 if (mi == null) { 353 mi = new MethodInfo ("<clinit>", new Descriptor (Descriptor.Void)); 354 mc.addMethod (mi); 355 mi.code = new Snippit(); 356 mi.code.push (new Instruction().setReturn()); 357 } 358 359 return mi; 360 } 361 362 363 364 public void addClinit (String name) { 365 MethodInfo mi = getclinit(); 366 367 370 mi.code.insertBefore (mi.code.first(), new Instruction().setPop()); 371 mi.code.insertBefore (mi.code.first(), new Instruction().setInvokeStatic ("java/lang/Class", "forName", 372 new Descriptor ("(Ljava/lang/String;)Ljava/lang/Class;"))); 373 mi.code.insertBefore (mi.code.first(), new Instruction().setSpush (name.replace ('/','.'))); 374 } 375 } 376 | Popular Tags |