1 duncan   1.1.2.1 // INClass.java, created Mon Dec 28 21:24:34 1998 by cananian
  2 cananian 1.1.2.2 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.1.2.2 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 duncan   1.1.2.1 package harpoon.Interpret.Tree;
  5 duncan   1.1.2.1 
  6 duncan   1.1.2.1 import harpoon.ClassFile.HClass;
  7 duncan   1.1.2.1 import harpoon.ClassFile.HMethod;
  8 cananian 1.1.2.3 import harpoon.ClassFile.NoSuchClassException;
  9 duncan   1.1.2.1 
 10 duncan   1.1.2.1 import java.lang.reflect.Modifier;
 11 duncan   1.1.2.1 import java.util.Hashtable;
 12 duncan   1.1.2.1 /**
 13 duncan   1.1.2.1  * <code>INClass</code> provides implementations of the native methods in
 14 duncan   1.1.2.1  * <code>java.lang.Class</code>.
 15 duncan   1.1.2.1  * 
 16 duncan   1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 17 cananian 1.2      * @version $Id: INClass.java,v 1.2 2002/02/25 21:05:50 cananian Exp $
 18 duncan   1.1.2.1  */
 19 cananian 1.1.2.3 public class INClass {
 20 duncan   1.1.2.1     static final void register(StaticState ss) {
 21 cananian 1.1.2.3         ss.register(forName(ss));
 22 cananian 1.1.2.3         ss.register(getComponentType(ss));
 23 cananian 1.1.2.3         ss.register(getInterfaces(ss));
 24 cananian 1.1.2.3         ss.register(getModifiers(ss));
 25 cananian 1.1.2.3         ss.register(getName(ss));
 26 cananian 1.1.2.3         ss.register(getPrimitiveClass(ss));
 27 cananian 1.1.2.3         ss.register(getSuperclass(ss));
 28 cananian 1.1.2.3         ss.register(isArray(ss));
 29 cananian 1.1.2.3         ss.register(isInterface(ss));
 30 cananian 1.1.2.3         ss.register(isPrimitive(ss));
 31 cananian 1.1.2.3         ss.register(newInstance(ss));
 32 duncan   1.1.2.1         // registry for name->class mapping
 33 cananian 1.1.2.3         ss.putNativeClosure(ss.HCclass, new Hashtable());
 34 cananian 1.1.2.3         // JDK 1.2 only
 35 cananian 1.1.2.3         try { ss.register(registerNatives(ss)); } catch (NoSuchMethodError e){}
 36 duncan   1.1.2.1     }
 37 duncan   1.1.2.1     static final ObjectRef forClass(StaticState ss, HClass hc)
 38 duncan   1.1.2.1         throws InterpretedThrowable {
 39 cananian 1.1.2.3         Hashtable registry = (Hashtable) ss.getNativeClosure(ss.HCclass);
 40 duncan   1.1.2.1         ObjectRef obj = (ObjectRef) registry.get(hc);
 41 duncan   1.1.2.1         if (obj!=null) return obj;
 42 cananian 1.1.2.3         obj = new ObjectRef(ss, ss.HCclass);
 43 cananian 1.1.2.3         Method.invoke(ss, ss.HCclass.getConstructor(new HClass[0]),
 44 duncan   1.1.2.1                       new Object[] { obj } );
 45 duncan   1.1.2.1         obj.putClosure(hc);
 46 duncan   1.1.2.1         registry.put(hc, obj);
 47 duncan   1.1.2.1         return obj;
 48 duncan   1.1.2.1     }
 49 cananian 1.1.2.3     private static final NativeMethod forName(StaticState ss0) {
 50 duncan   1.1.2.1         final HMethod hm =
 51 cananian 1.1.2.3             ss0.HCclass.getMethod("forName", new HClass[] { ss0.HCstring });
 52 duncan   1.1.2.1         return new NativeMethod() {
 53 duncan   1.1.2.1             HMethod getMethod() { return hm; }
 54 duncan   1.1.2.1             // throws ClassNotFoundException
 55 duncan   1.1.2.1             Object invoke(StaticState ss, Object[] params)
 56 duncan   1.1.2.1                 throws InterpretedThrowable {
 57 duncan   1.1.2.1                 String clsname = ss.ref2str((ObjectRef)params[0]);
 58 duncan   1.1.2.1                 try {
 59 cananian 1.1.2.3                     return forClass(ss, ss.linker.forName(clsname));
 60 cananian 1.1.2.3                 } catch (NoSuchClassException e) {
 61 cananian 1.1.2.3                     ObjectRef obj = ss.makeThrowable(ss.HCclassnotfoundE);
 62 duncan   1.1.2.1                     throw new InterpretedThrowable(obj, ss);
 63 duncan   1.1.2.1                 }
 64 duncan   1.1.2.1             }
 65 duncan   1.1.2.1         };
 66 duncan   1.1.2.1     }
 67 cananian 1.1.2.3     private static final NativeMethod getPrimitiveClass(StaticState ss0) {
 68 duncan   1.1.2.1         final HMethod hm =
 69 cananian 1.1.2.3             ss0.HCclass.getMethod("getPrimitiveClass",
 70 cananian 1.1.2.3                                   new HClass[] {ss0.HCstring});
 71 duncan   1.1.2.1         return new NativeMethod() {
 72 duncan   1.1.2.1             HMethod getMethod() { return hm; }
 73 duncan   1.1.2.1             Object invoke(StaticState ss, Object[] params)
 74 duncan   1.1.2.1                 throws InterpretedThrowable {
 75 duncan   1.1.2.1                 String name = ss.ref2str((ObjectRef)params[0]);
 76 duncan   1.1.2.1                 if (name.equals("boolean")) return forClass(ss,HClass.Boolean);
 77 duncan   1.1.2.1                 if (name.equals("byte"))    return forClass(ss,HClass.Byte);
 78 duncan   1.1.2.1                 if (name.equals("char"))    return forClass(ss,HClass.Char);
 79 duncan   1.1.2.1                 if (name.equals("double"))  return forClass(ss,HClass.Double);
 80 duncan   1.1.2.1                 if (name.equals("float"))   return forClass(ss,HClass.Float);
 81 duncan   1.1.2.1                 if (name.equals("int"))     return forClass(ss,HClass.Int);
 82 duncan   1.1.2.1                 if (name.equals("long"))    return forClass(ss,HClass.Long);
 83 duncan   1.1.2.1                 if (name.equals("short"))   return forClass(ss,HClass.Short);
 84 duncan   1.1.2.1                 if (name.equals("void"))    return forClass(ss,HClass.Void);
 85 duncan   1.1.2.1                 // oops.  throw exception.
 86 cananian 1.1.2.3                 ObjectRef obj = ss.makeThrowable(ss.HCclassnotfoundE);
 87 duncan   1.1.2.1                 throw new InterpretedThrowable(obj, ss);
 88 duncan   1.1.2.1             }
 89 duncan   1.1.2.1         };
 90 duncan   1.1.2.1     }
 91 cananian 1.1.2.3     private static final NativeMethod getName(StaticState ss0) {
 92 cananian 1.1.2.3         final HMethod hm = ss0.HCclass.getMethod("getName", new HClass[0]);
 93 duncan   1.1.2.1         return new NativeMethod() {
 94 duncan   1.1.2.1             HMethod getMethod() { return hm; }
 95 duncan   1.1.2.1             Object invoke(StaticState ss, Object[] params) {
 96 duncan   1.1.2.1                 ObjectRef obj = (ObjectRef) params[0];
 97 duncan   1.1.2.1                 String name = ((HClass)obj.getClosure()).getName();
 98 duncan   1.1.2.1                 return ss.makeString(name);
 99 duncan   1.1.2.1             }
100 duncan   1.1.2.1         };
101 duncan   1.1.2.1     }
102 cananian 1.1.2.3     private static final NativeMethod getSuperclass(StaticState ss0) {
103 cananian 1.1.2.3         final HMethod hm=ss0.HCclass.getMethod("getSuperclass", new HClass[0]);
104 duncan   1.1.2.1         return new NativeMethod() {
105 duncan   1.1.2.1             HMethod getMethod() { return hm; }
106 duncan   1.1.2.1             Object invoke(StaticState ss, Object[] params) {
107 duncan   1.1.2.1                 ObjectRef obj = (ObjectRef) params[0];
108 duncan   1.1.2.1                 HClass hc = (HClass) obj.getClosure();
109 duncan   1.1.2.1                 return forClass(ss, hc.getSuperclass());
110 duncan   1.1.2.1             }
111 duncan   1.1.2.1         };
112 duncan   1.1.2.1     }
113 cananian 1.1.2.3     private static final NativeMethod getInterfaces(StaticState ss0) {
114 cananian 1.1.2.3         final HMethod hm=ss0.HCclass.getMethod("getInterfaces", new HClass[0]);
115 duncan   1.1.2.1         return new NativeMethod() {
116 duncan   1.1.2.1             HMethod getMethod() { return hm; }
117 duncan   1.1.2.1             Object invoke(StaticState ss, Object[] params) {
118 duncan   1.1.2.1                 ObjectRef obj = (ObjectRef) params[0];
119 duncan   1.1.2.1                 HClass hc = (HClass) obj.getClosure();
120 duncan   1.1.2.1                 HClass in[] = hc.getInterfaces();
121 cananian 1.1.2.3                 ArrayRef af=new ArrayRef(ss,ss.HCclassA, new int[]{in.length});
122 duncan   1.1.2.1                 for (int i=0; i<in.length; i++)
123 duncan   1.1.2.1                     af.update(i, forClass(ss, in[i]));
124 duncan   1.1.2.1                 return af;
125 duncan   1.1.2.1             }
126 duncan   1.1.2.1         };
127 duncan   1.1.2.1     }
128 cananian 1.1.2.3     private static final NativeMethod getComponentType(StaticState ss0) {
129 cananian 1.1.2.3         final HMethod hm = ss0.HCclass.getMethod("getComponentType",
130 cananian 1.1.2.3                                                  new HClass[0]);
131 duncan   1.1.2.1         return new NativeMethod() {
132 duncan   1.1.2.1             HMethod getMethod() { return hm; }
133 duncan   1.1.2.1             Object invoke(StaticState ss, Object[] params) {
134 duncan   1.1.2.1                 ObjectRef obj = (ObjectRef) params[0];
135 duncan   1.1.2.1                 HClass hc = (HClass) obj.getClosure();
136 duncan   1.1.2.1                 return forClass(ss, hc.getComponentType());
137 duncan   1.1.2.1             }
138 duncan   1.1.2.1         };
139 duncan   1.1.2.1     }
140 cananian 1.1.2.3     private static final NativeMethod getModifiers(StaticState ss0) {
141 cananian 1.1.2.3         final HMethod hm = ss0.HCclass.getMethod("getModifiers",new HClass[0]);
142 duncan   1.1.2.1         return new NativeMethod() {
143 duncan   1.1.2.1             HMethod getMethod() { return hm; }
144 duncan   1.1.2.1             Object invoke(StaticState ss, Object[] params) {
145 duncan   1.1.2.1                 ObjectRef obj = (ObjectRef) params[0];
146 duncan   1.1.2.1                 HClass hc = (HClass) obj.getClosure();
147 duncan   1.1.2.1                 return new Integer(hc.getModifiers());
148 duncan   1.1.2.1             }
149 duncan   1.1.2.1         };
150 duncan   1.1.2.1     }
151 cananian 1.1.2.3     private static final NativeMethod newInstance(StaticState ss0) {
152 cananian 1.1.2.3         final HMethod hm0 = ss0.HCclass.getMethod("newInstance",new HClass[0]);
153 duncan   1.1.2.1         return new NativeMethod() {
154 duncan   1.1.2.1             HMethod getMethod() { return hm0; }
155 duncan   1.1.2.1             private InterpretedThrowable inst(StaticState ss)
156 duncan   1.1.2.1                 throws InterpretedThrowable {
157 cananian 1.1.2.3                 ObjectRef obj = ss.makeThrowable(ss.HCinstantiationE);
158 duncan   1.1.2.1                 return new InterpretedThrowable(obj, ss);
159 duncan   1.1.2.1             }
160 duncan   1.1.2.1             private InterpretedThrowable illacc(StaticState ss)
161 duncan   1.1.2.1                 throws InterpretedThrowable {
162 cananian 1.1.2.3                 ObjectRef obj = ss.makeThrowable(ss.HCillegalaccessE);
163 duncan   1.1.2.1                 return new InterpretedThrowable(obj, ss);
164 duncan   1.1.2.1             }
165 duncan   1.1.2.1             Object invoke(StaticState ss, Object[] params) {
166 duncan   1.1.2.1                 ObjectRef obj = (ObjectRef) params[0];
167 duncan   1.1.2.1                 try {
168 duncan   1.1.2.1                     HClass hc = (HClass) obj.getClosure();
169 duncan   1.1.2.1                     if (hc.isInterface() || 
170 duncan   1.1.2.1                         Modifier.isAbstract(hc.getModifiers()))
171 duncan   1.1.2.1                         throw inst(ss);
172 duncan   1.1.2.1                     HMethod hm = hc.getConstructor(new HClass[0]);
173 duncan   1.1.2.1                     if (!Modifier.isPublic(hm.getModifiers()))
174 duncan   1.1.2.1                         throw illacc(ss);
175 duncan   1.1.2.1                     obj = new ObjectRef(ss, hc);
176 duncan   1.1.2.1                     Method.invoke(ss, hm, new Object[] { obj } );
177 duncan   1.1.2.1                     return obj;
178 duncan   1.1.2.1                 } catch (InterpretedThrowable e) {
179 duncan   1.1.2.1                     throw inst(ss);
180 duncan   1.1.2.1                 }
181 duncan   1.1.2.1             }
182 duncan   1.1.2.1         };
183 duncan   1.1.2.1     }
184 cananian 1.1.2.3     private static final NativeMethod isInterface(StaticState ss0) {
185 cananian 1.1.2.3         final HMethod hm = ss0.HCclass.getMethod("isInterface", new HClass[0]);
186 duncan   1.1.2.1         return new NativeMethod() {
187 duncan   1.1.2.1             HMethod getMethod() { return hm; }
188 duncan   1.1.2.1             Object invoke(StaticState ss, Object[] params) {
189 duncan   1.1.2.1                 ObjectRef obj = (ObjectRef) params[0];
190 duncan   1.1.2.1                 HClass hc = (HClass) obj.getClosure();
191 duncan   1.1.2.1                 return new Boolean(hc.isInterface());
192 duncan   1.1.2.1             }
193 duncan   1.1.2.1         };
194 duncan   1.1.2.1     }
195 cananian 1.1.2.3     private static final NativeMethod isArray(StaticState ss0) {
196 cananian 1.1.2.3         final HMethod hm = ss0.HCclass.getMethod("isArray", new HClass[0]);
197 duncan   1.1.2.1         return new NativeMethod() {
198 duncan   1.1.2.1             HMethod getMethod() { return hm; }
199 duncan   1.1.2.1             Object invoke(StaticState ss, Object[] params) {
200 duncan   1.1.2.1                 ObjectRef obj = (ObjectRef) params[0];
201 duncan   1.1.2.1                 HClass hc = (HClass) obj.getClosure();
202 duncan   1.1.2.1                 return new Boolean(hc.isArray());
203 duncan   1.1.2.1             }
204 duncan   1.1.2.1         };
205 duncan   1.1.2.1     }
206 cananian 1.1.2.3     private static final NativeMethod isPrimitive(StaticState ss0) {
207 cananian 1.1.2.3         final HMethod hm = ss0.HCclass.getMethod("isPrimitive", new HClass[0]);
208 duncan   1.1.2.1         return new NativeMethod() {
209 duncan   1.1.2.1             HMethod getMethod() { return hm; }
210 duncan   1.1.2.1             Object invoke(StaticState ss, Object[] params) {
211 duncan   1.1.2.1                 ObjectRef obj = (ObjectRef) params[0];
212 duncan   1.1.2.1                 HClass hc = (HClass) obj.getClosure();
213 duncan   1.1.2.1                 return new Boolean(hc.isPrimitive());
214 duncan   1.1.2.1             }
215 duncan   1.1.2.1         };
216 cananian 1.1.2.3     }
217 cananian 1.1.2.3     // JDK 1.2 only: Class.registerNatives()
218 cananian 1.1.2.3     private static final NativeMethod registerNatives(StaticState ss0) {
219 cananian 1.1.2.3         final HMethod hm =
220 cananian 1.1.2.3             ss0.HCclass.getMethod("registerNatives",new HClass[0]);
221 cananian 1.1.2.3         return new NullNativeMethod(hm);
222 duncan   1.1.2.1     }
223 cananian 1.2     }