1 cananian 1.1.2.1 // INClass.java, created Mon Dec 28 21:24:34 1998 by cananian 2 cananian 1.1.2.3 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1.2.3 // 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.2 import harpoon.ClassFile.HClass; 7 cananian 1.1.2.2 import harpoon.ClassFile.HMethod; 8 cananian 1.1.2.5 import harpoon.ClassFile.NoSuchClassException; 9 cananian 1.1.2.1 10 cananian 1.1.2.7 import harpoon.Util.Util; 11 cananian 1.1.2.7 12 cananian 1.1.2.1 import java.lang.reflect.Modifier; 13 cananian 1.1.2.1 import java.util.Hashtable; 14 cananian 1.1.2.1 /** 15 cananian 1.1.2.1 * <code>INClass</code> provides implementations of the native methods in 16 cananian 1.1.2.1 * <code>java.lang.Class</code>. 17 cananian 1.1.2.1 * 18 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 19 cananian 1.4 * @version $Id: INClass.java,v 1.4 2002/04/10 03:05:50 cananian Exp $ 20 cananian 1.1.2.1 */ 21 cananian 1.1.2.5 public class INClass { 22 cananian 1.1.2.1 static final void register(StaticState ss) { 23 cananian 1.1.2.7 try { // JDK 1.2 only 24 cananian 1.1.2.7 ss.register(forName0(ss)); 25 cananian 1.1.2.7 } catch (NoSuchMethodError e) { // JDK 1.1 fallback. 26 cananian 1.1.2.7 ss.register(forName(ss)); 27 cananian 1.1.2.7 } 28 cananian 1.1.2.5 ss.register(getComponentType(ss)); 29 cananian 1.1.2.5 ss.register(getInterfaces(ss)); 30 cananian 1.1.2.5 ss.register(getModifiers(ss)); 31 cananian 1.1.2.5 ss.register(getName(ss)); 32 cananian 1.1.2.5 ss.register(getPrimitiveClass(ss)); 33 cananian 1.1.2.5 ss.register(getSuperclass(ss)); 34 cananian 1.1.2.5 ss.register(isArray(ss)); 35 cananian 1.1.2.5 ss.register(isInterface(ss)); 36 cananian 1.1.2.5 ss.register(isPrimitive(ss)); 37 cananian 1.1.2.7 try { // JDK 1.2 only 38 cananian 1.1.2.7 ss.register(newInstance0(ss)); 39 cananian 1.1.2.7 } catch (NoSuchMethodError e) { // JDK 1.1 fallback. 40 cananian 1.1.2.7 ss.register(newInstance(ss)); 41 cananian 1.1.2.7 } 42 cananian 1.1.2.1 // registry for name->class mapping 43 cananian 1.1.2.5 ss.putNativeClosure(ss.HCclass, new Hashtable()); 44 cananian 1.1.2.4 // JDK 1.2 only 45 cananian 1.1.2.5 try { ss.register(registerNatives(ss)); } catch (NoSuchMethodError e){} 46 cananian 1.1.2.6 try { ss.register(getClassLoader0(ss)); } catch (NoSuchMethodError e){} 47 cananian 1.1.2.1 } 48 cananian 1.1.2.1 static final ObjectRef forClass(StaticState ss, HClass hc) 49 cananian 1.1.2.1 throws InterpretedThrowable { 50 cananian 1.1.2.5 Hashtable registry = (Hashtable) ss.getNativeClosure(ss.HCclass); 51 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) registry.get(hc); 52 cananian 1.1.2.1 if (obj!=null) return obj; 53 cananian 1.1.2.5 obj = new ObjectRef(ss, ss.HCclass); 54 cananian 1.1.2.5 Method.invoke(ss, ss.HCclass.getConstructor(new HClass[0]), 55 cananian 1.1.2.1 new Object[] { obj } ); 56 cananian 1.1.2.1 obj.putClosure(hc); 57 cananian 1.1.2.1 registry.put(hc, obj); 58 cananian 1.1.2.1 return obj; 59 cananian 1.1.2.1 } 60 cananian 1.1.2.5 private static final NativeMethod forName(StaticState ss0) { 61 cananian 1.1.2.1 final HMethod hm = 62 cananian 1.1.2.5 ss0.HCclass.getMethod("forName", new HClass[] { ss0.HCstring }); 63 cananian 1.1.2.1 return new NativeMethod() { 64 cananian 1.1.2.1 HMethod getMethod() { return hm; } 65 cananian 1.1.2.1 // throws ClassNotFoundException 66 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) 67 cananian 1.1.2.1 throws InterpretedThrowable { 68 cananian 1.1.2.1 String clsname = ss.ref2str((ObjectRef)params[0]); 69 cananian 1.1.2.1 try { 70 cananian 1.1.2.5 return forClass(ss, ss.linker.forName(clsname)); 71 cananian 1.1.2.5 } catch (NoSuchClassException e) { 72 cananian 1.1.2.5 ObjectRef obj = ss.makeThrowable(ss.HCclassnotfoundE); 73 cananian 1.1.2.1 throw new InterpretedThrowable(obj, ss); 74 cananian 1.1.2.1 } 75 cananian 1.1.2.1 } 76 cananian 1.1.2.1 }; 77 cananian 1.1.2.1 } 78 cananian 1.1.2.7 // JDK 1.2 version of forName() 79 cananian 1.1.2.7 private static final NativeMethod forName0(StaticState ss0) { 80 cananian 1.1.2.7 final HMethod hm = ss0.HCclass.getMethod 81 cananian 1.1.2.7 ("forName0", 82 cananian 1.1.2.7 "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"); 83 cananian 1.1.2.7 return new NativeMethod() { 84 cananian 1.1.2.7 HMethod getMethod() { return hm; } 85 cananian 1.1.2.7 // throws ClassNotFoundException 86 cananian 1.1.2.7 Object invoke(StaticState ss, Object[] params) 87 cananian 1.1.2.7 throws InterpretedThrowable { 88 cananian 1.1.2.7 String name = ss.ref2str((ObjectRef) params[0]); 89 cananian 1.1.2.7 boolean initialize = ((Boolean) params[1]).booleanValue(); 90 cananian 1.1.2.7 ObjectRef loader = (ObjectRef) params[2]; 91 cananian 1.3.2.1 assert loader==null : "Haven't implemented class loading "+ 92 cananian 1.3.2.1 "from a ClassLoader object."; 93 cananian 1.3.2.1 assert initialize : "Haven't implemented uninitialized "+ 94 cananian 1.3.2.1 "class loading."; 95 cananian 1.1.2.7 try { 96 cananian 1.1.2.7 return forClass(ss, ss.linker.forName(name)); 97 cananian 1.1.2.7 } catch (NoSuchClassException e) { 98 cananian 1.1.2.7 ObjectRef obj = ss.makeThrowable(ss.HCclassnotfoundE); 99 cananian 1.1.2.7 throw new InterpretedThrowable(obj, ss); 100 cananian 1.1.2.7 } 101 cananian 1.1.2.7 } 102 cananian 1.1.2.7 }; 103 cananian 1.1.2.7 } 104 cananian 1.1.2.5 private static final NativeMethod getPrimitiveClass(StaticState ss0) { 105 cananian 1.1.2.1 final HMethod hm = 106 cananian 1.1.2.5 ss0.HCclass.getMethod("getPrimitiveClass", 107 cananian 1.1.2.5 new HClass[] {ss0.HCstring}); 108 cananian 1.1.2.1 return new NativeMethod() { 109 cananian 1.1.2.1 HMethod getMethod() { return hm; } 110 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) 111 cananian 1.1.2.1 throws InterpretedThrowable { 112 cananian 1.1.2.1 String name = ss.ref2str((ObjectRef)params[0]); 113 cananian 1.1.2.1 if (name.equals("boolean")) return forClass(ss,HClass.Boolean); 114 cananian 1.1.2.1 if (name.equals("byte")) return forClass(ss,HClass.Byte); 115 cananian 1.1.2.1 if (name.equals("char")) return forClass(ss,HClass.Char); 116 cananian 1.1.2.1 if (name.equals("double")) return forClass(ss,HClass.Double); 117 cananian 1.1.2.1 if (name.equals("float")) return forClass(ss,HClass.Float); 118 cananian 1.1.2.1 if (name.equals("int")) return forClass(ss,HClass.Int); 119 cananian 1.1.2.1 if (name.equals("long")) return forClass(ss,HClass.Long); 120 cananian 1.1.2.1 if (name.equals("short")) return forClass(ss,HClass.Short); 121 cananian 1.1.2.1 if (name.equals("void")) return forClass(ss,HClass.Void); 122 cananian 1.1.2.1 // oops. throw exception. 123 cananian 1.1.2.5 ObjectRef obj = ss.makeThrowable(ss.HCclassnotfoundE); 124 cananian 1.1.2.1 throw new InterpretedThrowable(obj, ss); 125 cananian 1.1.2.1 } 126 cananian 1.1.2.1 }; 127 cananian 1.1.2.1 } 128 cananian 1.1.2.5 private static final NativeMethod getName(StaticState ss0) { 129 cananian 1.1.2.5 final HMethod hm = ss0.HCclass.getMethod("getName", new HClass[0]); 130 cananian 1.1.2.1 return new NativeMethod() { 131 cananian 1.1.2.1 HMethod getMethod() { return hm; } 132 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) { 133 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 134 cananian 1.1.2.1 String name = ((HClass)obj.getClosure()).getName(); 135 cananian 1.1.2.1 return ss.makeString(name); 136 cananian 1.1.2.1 } 137 cananian 1.1.2.1 }; 138 cananian 1.1.2.1 } 139 cananian 1.1.2.5 private static final NativeMethod getSuperclass(StaticState ss0) { 140 cananian 1.1.2.5 final HMethod hm=ss0.HCclass.getMethod("getSuperclass", new HClass[0]); 141 cananian 1.1.2.1 return new NativeMethod() { 142 cananian 1.1.2.1 HMethod getMethod() { return hm; } 143 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) { 144 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 145 cananian 1.1.2.1 HClass hc = (HClass) obj.getClosure(); 146 cananian 1.1.2.1 return forClass(ss, hc.getSuperclass()); 147 cananian 1.1.2.1 } 148 cananian 1.1.2.1 }; 149 cananian 1.1.2.1 } 150 cananian 1.1.2.5 private static final NativeMethod getInterfaces(StaticState ss0) { 151 cananian 1.1.2.5 final HMethod hm=ss0.HCclass.getMethod("getInterfaces", new HClass[0]); 152 cananian 1.1.2.1 return new NativeMethod() { 153 cananian 1.1.2.1 HMethod getMethod() { return hm; } 154 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) { 155 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 156 cananian 1.1.2.1 HClass hc = (HClass) obj.getClosure(); 157 cananian 1.1.2.1 HClass in[] = hc.getInterfaces(); 158 cananian 1.1.2.5 ArrayRef af=new ArrayRef(ss,ss.HCclassA, new int[]{in.length}); 159 cananian 1.1.2.1 for (int i=0; i<in.length; i++) 160 cananian 1.1.2.1 af.update(i, forClass(ss, in[i])); 161 cananian 1.1.2.1 return af; 162 cananian 1.1.2.1 } 163 cananian 1.1.2.1 }; 164 cananian 1.1.2.1 } 165 cananian 1.1.2.5 private static final NativeMethod getComponentType(StaticState ss0) { 166 cananian 1.1.2.5 final HMethod hm = ss0.HCclass.getMethod("getComponentType", 167 cananian 1.1.2.5 new HClass[0]); 168 cananian 1.1.2.1 return new NativeMethod() { 169 cananian 1.1.2.1 HMethod getMethod() { return hm; } 170 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) { 171 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 172 cananian 1.1.2.1 HClass hc = (HClass) obj.getClosure(); 173 cananian 1.1.2.1 return forClass(ss, hc.getComponentType()); 174 cananian 1.1.2.1 } 175 cananian 1.1.2.1 }; 176 cananian 1.1.2.1 } 177 cananian 1.1.2.5 private static final NativeMethod getModifiers(StaticState ss0) { 178 cananian 1.1.2.5 final HMethod hm = ss0.HCclass.getMethod("getModifiers",new HClass[0]); 179 cananian 1.1.2.1 return new NativeMethod() { 180 cananian 1.1.2.1 HMethod getMethod() { return hm; } 181 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) { 182 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 183 cananian 1.1.2.1 HClass hc = (HClass) obj.getClosure(); 184 cananian 1.1.2.1 return new Integer(hc.getModifiers()); 185 cananian 1.1.2.1 } 186 cananian 1.1.2.1 }; 187 cananian 1.1.2.1 } 188 cananian 1.1.2.5 private static final NativeMethod newInstance(StaticState ss0) { 189 cananian 1.1.2.5 final HMethod hm0 = ss0.HCclass.getMethod("newInstance",new HClass[0]); 190 cananian 1.1.2.1 return new NativeMethod() { 191 cananian 1.1.2.1 HMethod getMethod() { return hm0; } 192 cananian 1.1.2.1 private InterpretedThrowable inst(StaticState ss) 193 cananian 1.1.2.1 throws InterpretedThrowable { 194 cananian 1.1.2.5 ObjectRef obj = ss.makeThrowable(ss.HCinstantiationE); 195 cananian 1.1.2.1 return new InterpretedThrowable(obj, ss); 196 cananian 1.1.2.1 } 197 cananian 1.1.2.1 private InterpretedThrowable illacc(StaticState ss) 198 cananian 1.1.2.1 throws InterpretedThrowable { 199 cananian 1.1.2.5 ObjectRef obj = ss.makeThrowable(ss.HCillegalaccessE); 200 cananian 1.1.2.1 return new InterpretedThrowable(obj, ss); 201 cananian 1.1.2.1 } 202 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) { 203 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 204 cananian 1.1.2.1 try { 205 cananian 1.1.2.1 HClass hc = (HClass) obj.getClosure(); 206 cananian 1.1.2.1 if (hc.isInterface() || 207 cananian 1.1.2.1 Modifier.isAbstract(hc.getModifiers())) 208 cananian 1.1.2.1 throw inst(ss); 209 cananian 1.1.2.1 HMethod hm = hc.getConstructor(new HClass[0]); 210 cananian 1.1.2.8 int modf = hm.getModifiers(); 211 cananian 1.1.2.8 if (Modifier.isPrivate(modf)) 212 cananian 1.1.2.1 throw illacc(ss); 213 cananian 1.1.2.8 if (!Modifier.isPublic(modf)) { 214 cananian 1.1.2.8 // package or protected. 215 cananian 1.1.2.8 HClass context = ss.getCaller().getDeclaringClass(); 216 cananian 1.1.2.8 if (context.getPackage().equals(hc.getPackage()) || 217 cananian 1.1.2.8 (Modifier.isProtected(modf) && 218 cananian 1.1.2.8 context.isInstanceOf(hc))) 219 cananian 1.1.2.8 /* this case is okay. */; 220 cananian 1.1.2.8 else throw illacc(ss); 221 cananian 1.1.2.8 } 222 cananian 1.1.2.1 obj = new ObjectRef(ss, hc); 223 cananian 1.1.2.1 Method.invoke(ss, hm, new Object[] { obj } ); 224 cananian 1.1.2.1 return obj; 225 cananian 1.1.2.1 } catch (InterpretedThrowable e) { 226 cananian 1.1.2.1 throw inst(ss); 227 cananian 1.1.2.1 } 228 cananian 1.1.2.7 } 229 cananian 1.1.2.7 }; 230 cananian 1.1.2.7 } 231 cananian 1.1.2.7 // JDK 1.2 stub. 232 cananian 1.1.2.7 private static final NativeMethod newInstance0(StaticState ss0) { 233 cananian 1.1.2.7 final HMethod hm = ss0.HCclass.getMethod("newInstance0",new HClass[0]); 234 cananian 1.1.2.7 return new NativeMethod() { 235 cananian 1.1.2.7 HMethod getMethod() { return hm; } 236 cananian 1.1.2.7 Object invoke(StaticState ss, Object[] params) { 237 cananian 1.1.2.7 return newInstance(ss).invoke(ss, params); 238 cananian 1.1.2.1 } 239 cananian 1.1.2.1 }; 240 cananian 1.1.2.1 } 241 cananian 1.1.2.5 private static final NativeMethod isInterface(StaticState ss0) { 242 cananian 1.1.2.5 final HMethod hm = ss0.HCclass.getMethod("isInterface", new HClass[0]); 243 cananian 1.1.2.1 return new NativeMethod() { 244 cananian 1.1.2.1 HMethod getMethod() { return hm; } 245 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) { 246 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 247 cananian 1.1.2.1 HClass hc = (HClass) obj.getClosure(); 248 cananian 1.1.2.1 return new Boolean(hc.isInterface()); 249 cananian 1.1.2.1 } 250 cananian 1.1.2.1 }; 251 cananian 1.1.2.1 } 252 cananian 1.1.2.5 private static final NativeMethod isArray(StaticState ss0) { 253 cananian 1.1.2.5 final HMethod hm = ss0.HCclass.getMethod("isArray", new HClass[0]); 254 cananian 1.1.2.1 return new NativeMethod() { 255 cananian 1.1.2.1 HMethod getMethod() { return hm; } 256 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) { 257 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 258 cananian 1.1.2.1 HClass hc = (HClass) obj.getClosure(); 259 cananian 1.1.2.1 return new Boolean(hc.isArray()); 260 cananian 1.1.2.1 } 261 cananian 1.1.2.1 }; 262 cananian 1.1.2.1 } 263 cananian 1.1.2.5 private static final NativeMethod isPrimitive(StaticState ss0) { 264 cananian 1.1.2.5 final HMethod hm = ss0.HCclass.getMethod("isPrimitive", new HClass[0]); 265 cananian 1.1.2.1 return new NativeMethod() { 266 cananian 1.1.2.1 HMethod getMethod() { return hm; } 267 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) { 268 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 269 cananian 1.1.2.1 HClass hc = (HClass) obj.getClosure(); 270 cananian 1.1.2.1 return new Boolean(hc.isPrimitive()); 271 cananian 1.1.2.1 } 272 cananian 1.1.2.1 }; 273 cananian 1.1.2.4 } 274 cananian 1.1.2.4 // JDK 1.2 only: Class.registerNatives() 275 cananian 1.1.2.5 private static final NativeMethod registerNatives(StaticState ss0) { 276 cananian 1.1.2.4 final HMethod hm = 277 cananian 1.1.2.5 ss0.HCclass.getMethod("registerNatives",new HClass[0]); 278 cananian 1.1.2.6 return new NullNativeMethod(hm); 279 cananian 1.1.2.6 } 280 cananian 1.1.2.6 // JDK 1.2 only: Class.getClassLoader0() 281 cananian 1.1.2.6 private static final NativeMethod getClassLoader0(StaticState ss0) { 282 cananian 1.1.2.6 // always return 'null', indicating the boot class loader. 283 cananian 1.1.2.6 final HMethod hm = 284 cananian 1.1.2.6 ss0.HCclass.getMethod("getClassLoader0",new HClass[0]); 285 cananian 1.1.2.4 return new NullNativeMethod(hm); 286 cananian 1.1.2.1 } 287 cananian 1.2 }