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 }