1 cananian 1.1.2.1 // INClassLoader.java, created Thu Jan 27 22:18:13 1999 by cananian 2 cananian 1.1.2.1 // Copyright (C) 1999 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1.2.1 package harpoon.Interpret.Quads; 5 cananian 1.1.2.1 6 cananian 1.1.2.1 import harpoon.ClassFile.HClass; 7 cananian 1.1.2.1 import harpoon.ClassFile.HField; 8 cananian 1.1.2.1 import harpoon.ClassFile.HMethod; 9 cananian 1.1.2.4 import harpoon.ClassFile.Loader; 10 cananian 1.1.2.2 import harpoon.ClassFile.NoSuchClassException; 11 cananian 1.1.2.1 12 cananian 1.1.2.4 import java.io.InputStream; 13 cananian 1.1.2.4 14 cananian 1.1.2.1 /** 15 cananian 1.1.2.1 * <code>INClassLoader</code> provides implementations for (some of) the native 16 cananian 1.1.2.1 * methods in <code>java.lang.ClassLoader</code> and 17 cananian 1.1.2.1 * <code>java.lang.ClassLoader.NativeLibrary</code>. 18 cananian 1.1.2.1 * 19 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 20 cananian 1.2 * @version $Id: INClassLoader.java,v 1.2 2002/02/25 21:05:45 cananian Exp $ 21 cananian 1.1.2.1 */ 22 cananian 1.1.2.1 public class INClassLoader { 23 cananian 1.1.2.1 static final void register(StaticState ss) { 24 cananian 1.1.2.4 try{ ss.register(findSystemClass0(ss)); } catch (NoSuchMethodError e){} 25 cananian 1.1.2.4 /*try*/{ ss.register(getSystemResourceAsStream0(ss)); }/* catch (NoSuchMethodError e) {}*/ 26 cananian 1.1.2.4 try{ ss.register(init(ss)); } catch (NoSuchMethodError e) {} 27 cananian 1.1.2.1 // JDK 1.2 only 28 cananian 1.1.2.3 try{ss.register(getCallerClassLoader(ss));}catch(NoSuchMethodError e){} 29 cananian 1.1.2.2 try { // the following are ClassLoader.NativeLibrary methods. 30 cananian 1.1.2.1 try { ss.register(NLload(ss)); } catch (NoSuchMethodError e) {} 31 cananian 1.1.2.1 try { ss.register(NLunload(ss)); } catch (NoSuchMethodError e) {} 32 cananian 1.1.2.2 } catch (NoSuchClassException e) { /* ignore */ } 33 cananian 1.1.2.4 } 34 cananian 1.1.2.4 // ClassLoader.findSystemClass0 behaves (in our implementation) exactly 35 cananian 1.1.2.4 // like Class.forName 36 cananian 1.1.2.4 private static final NativeMethod findSystemClass0(StaticState ss0) { 37 cananian 1.1.2.4 final HClass hc = ss0.linker.forName("java.lang.ClassLoader"); 38 cananian 1.1.2.4 final HMethod hm = 39 cananian 1.1.2.4 hc.getMethod("findSystemClass0", new HClass[] { ss0.HCstring } ); 40 cananian 1.1.2.4 return new NativeMethod() { 41 cananian 1.1.2.4 HMethod getMethod() { return hm; } 42 cananian 1.1.2.4 // implementation borrowed from INClass.forName 43 cananian 1.1.2.4 // throws ClassNotFoundException 44 cananian 1.1.2.4 Object invoke(StaticState ss, Object[] params) 45 cananian 1.1.2.4 throws InterpretedThrowable { 46 cananian 1.1.2.4 // params[0] is 'this' because findSystemClass is non-static 47 cananian 1.1.2.4 String clsname = ss.ref2str((ObjectRef)params[1]); 48 cananian 1.1.2.4 try { 49 cananian 1.1.2.4 return INClass.forClass(ss, ss.linker.forName(clsname)); 50 cananian 1.1.2.4 } catch (NoSuchClassException e) { 51 cananian 1.1.2.4 ObjectRef obj = ss.makeThrowable(ss.HCclassnotfoundE); 52 cananian 1.1.2.4 throw new InterpretedThrowable(obj, ss); 53 cananian 1.1.2.4 } 54 cananian 1.1.2.4 } 55 cananian 1.1.2.4 }; 56 cananian 1.1.2.4 } 57 cananian 1.1.2.4 // getSystemResourceAsStream0 is identical in functionality to 58 cananian 1.1.2.4 // Loader.getResourceAsStream(). But we must wrap the result. 59 cananian 1.1.2.4 private static final NativeMethod getSystemResourceAsStream0(StaticState ss0) { 60 cananian 1.1.2.4 final HClass hc = ss0.linker.forName("java.lang.ClassLoader"); 61 cananian 1.1.2.4 final HMethod hm = 62 cananian 1.1.2.4 hc.getMethod("getSystemResourceAsStream0", new HClass[] { ss0.HCstring } ); 63 cananian 1.1.2.4 return new NativeMethod() { 64 cananian 1.1.2.4 HMethod getMethod() { return hm; } 65 cananian 1.1.2.4 Object invoke(StaticState ss, Object[] params) { 66 cananian 1.1.2.4 String resname = ss.ref2str((ObjectRef)params[0]); 67 cananian 1.1.2.4 InputStream is = Loader.getResourceAsStream(resname); 68 cananian 1.1.2.4 if (is==null) return null; // unsuccessful. 69 cananian 1.1.2.4 // okay, now create new 'interpreted' FileInputStream from 70 cananian 1.1.2.4 // the real one. 71 cananian 1.1.2.4 return INFileInputStream.openInputStream(ss, is); 72 cananian 1.1.2.4 } 73 cananian 1.1.2.4 }; 74 cananian 1.1.2.4 } 75 cananian 1.1.2.4 // do-nothing 'init' method (initialization of class loader) 76 cananian 1.1.2.4 private static final NativeMethod init(StaticState ss0) { 77 cananian 1.1.2.4 final HClass hc = ss0.linker.forName("java.lang.ClassLoader"); 78 cananian 1.1.2.4 final HMethod hm = 79 cananian 1.1.2.4 hc.getMethod("init", new HClass[0] ); 80 cananian 1.1.2.4 return new NativeMethod() { 81 cananian 1.1.2.4 HMethod getMethod() { return hm; } 82 cananian 1.1.2.4 Object invoke(StaticState ss, Object[] params) { 83 cananian 1.1.2.4 // do nothing. 84 cananian 1.1.2.4 return null; 85 cananian 1.1.2.4 } 86 cananian 1.1.2.4 }; 87 cananian 1.1.2.1 } 88 cananian 1.1.2.3 // Returns the caller's class loader 89 cananian 1.1.2.3 private static final NativeMethod getCallerClassLoader(StaticState ss0) { 90 cananian 1.1.2.3 final HClass hc = ss0.linker.forName("java.lang.ClassLoader"); 91 cananian 1.1.2.3 final HMethod hm = 92 cananian 1.1.2.3 hc.getMethod("getCallerClassLoader", new HClass[0] ); 93 cananian 1.1.2.3 return new NativeMethod() { 94 cananian 1.1.2.3 HMethod getMethod() { return hm; } 95 cananian 1.1.2.3 Object invoke(StaticState ss, Object[] params) { 96 cananian 1.1.2.3 // always return null. 97 cananian 1.1.2.3 return null; 98 cananian 1.1.2.3 } 99 cananian 1.1.2.3 }; 100 cananian 1.1.2.3 } 101 cananian 1.1.2.3 102 cananian 1.1.2.3 // ------------ ClassLoader.NativeLibrary implementations --------- 103 cananian 1.1.2.3 104 cananian 1.1.2.1 static long handle=0; // help make unique non-zero handles 105 cananian 1.1.2.1 // Load the named native library. 106 cananian 1.1.2.1 private static final NativeMethod NLload(StaticState ss0) { 107 cananian 1.1.2.1 final HClass hc = 108 cananian 1.1.2.1 ss0.linker.forName("java.lang.ClassLoader$NativeLibrary"); 109 cananian 1.1.2.1 final HMethod hm = 110 cananian 1.1.2.1 hc.getMethod("load", new HClass[] { ss0.HCstring } ); 111 cananian 1.1.2.1 final HField handleF = hc.getField("handle"); 112 cananian 1.1.2.1 return new NativeMethod() { 113 cananian 1.1.2.1 HMethod getMethod() { return hm; } 114 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) { 115 cananian 1.1.2.1 ObjectRef _this = (ObjectRef) params[0]; 116 cananian 1.1.2.1 ObjectRef _name = (ObjectRef) params[1]; 117 cananian 1.1.2.1 String name = ss.ref2str(_name); 118 cananian 1.1.2.1 System.err.println("LOADING NATIVE LIBRARY "+name); 119 cananian 1.1.2.1 // don't actually load it; just do nothing. 120 cananian 1.1.2.1 // we have to set the handle to be non-zero, though. 121 cananian 1.1.2.1 _this.update(handleF, new Long(++handle)); 122 cananian 1.1.2.1 return null; 123 cananian 1.1.2.1 } 124 cananian 1.1.2.1 }; 125 cananian 1.1.2.1 } 126 cananian 1.1.2.1 // Unload the named native library. 127 cananian 1.1.2.1 private static final NativeMethod NLunload(StaticState ss0) { 128 cananian 1.1.2.1 final HClass hc = 129 cananian 1.1.2.1 ss0.linker.forName("java.lang.ClassLoader$NativeLibrary"); 130 cananian 1.1.2.1 final HMethod hm = 131 cananian 1.1.2.1 hc.getMethod("unload", new HClass[0] ); 132 cananian 1.1.2.1 final HField nameF = hc.getField("name"); 133 cananian 1.1.2.1 final HField handleF = hc.getField("handle"); 134 cananian 1.1.2.1 return new NativeMethod() { 135 cananian 1.1.2.1 HMethod getMethod() { return hm; } 136 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) { 137 cananian 1.1.2.1 ObjectRef _this = (ObjectRef) params[0]; 138 cananian 1.1.2.1 ObjectRef _name = (ObjectRef) _this.get(nameF); 139 cananian 1.1.2.1 String name = ss.ref2str(_name); 140 cananian 1.1.2.1 System.err.println("UNLOADING NATIVE LIBRARY "+name); 141 cananian 1.1.2.1 // don't actually unload it; just do nothing. 142 cananian 1.1.2.1 // we will clear the handle field to zero, though. 143 cananian 1.1.2.1 _this.update(handleF, new Long(0)); 144 cananian 1.1.2.1 return null; 145 cananian 1.1.2.1 } 146 cananian 1.1.2.1 }; 147 cananian 1.1.2.1 } 148 cananian 1.2 }