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     }