View Javadoc

1   // BasicReflectionImpl.java, created Mon Dec 16 20:56:31 2002 by mcmartin
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.Runtime;
5   
6   import java.util.Set;
7   import java.lang.reflect.Array;
8   import java.lang.reflect.Constructor;
9   import java.lang.reflect.Field;
10  import java.lang.reflect.InvocationTargetException;
11  import java.lang.reflect.Member;
12  import java.lang.reflect.Method;
13  import java.lang.reflect.Modifier;
14  import joeq.Class.PrimordialClassLoader;
15  import joeq.Class.jq_Class;
16  import joeq.Class.jq_ClassInitializer;
17  import joeq.Class.jq_Field;
18  import joeq.Class.jq_Initializer;
19  import joeq.Class.jq_InstanceField;
20  import joeq.Class.jq_InstanceMethod;
21  import joeq.Class.jq_Member;
22  import joeq.Class.jq_Method;
23  import joeq.Class.jq_NameAndDesc;
24  import joeq.Class.jq_Primitive;
25  import joeq.Class.jq_Reference;
26  import joeq.Class.jq_StaticField;
27  import joeq.Class.jq_StaticMethod;
28  import joeq.Class.jq_Type;
29  import joeq.Memory.Address;
30  import joeq.UTF.Utf8;
31  import jwutil.util.Assert;
32  import jwutil.util.Convert;
33  
34  /***
35   * @author  John Whaley <jwhaley@alum.mit.edu>
36   * @version $Id: BasicReflectionImpl.java 2218 2005-03-14 22:14:51Z joewhaley $
37   */
38  public class BasicReflectionImpl implements Reflection.Delegate {
39  
40      public static boolean REPORT_JDK_ERRORS = false;
41      
42      public final jq_Reference getTypeOf(Object o) {
43          return (jq_Reference) getJQType(o.getClass());
44      }
45      
46      // Map between our jq_Type objects and JDK Class objects
47      public final jq_Type getJQType(Class c) {
48          if (c.isPrimitive()) {
49              if (c == Byte.TYPE) return jq_Primitive.BYTE;
50              if (c == Character.TYPE) return jq_Primitive.CHAR;
51              if (c == Double.TYPE) return jq_Primitive.DOUBLE;
52              if (c == Float.TYPE) return jq_Primitive.FLOAT;
53              if (c == Integer.TYPE) return jq_Primitive.INT;
54              if (c == Long.TYPE) return jq_Primitive.LONG;
55              if (c == Short.TYPE) return jq_Primitive.SHORT;
56              if (c == Boolean.TYPE) return jq_Primitive.BOOLEAN;
57              if (c == Void.TYPE) return jq_Primitive.VOID;
58              Assert.UNREACHABLE(c.toString());
59              return null;
60          }
61          String className = c.getName().replace('.','/');
62          if (!className.startsWith("[")) className = "L"+className+";";
63          className = joeq.ClassLib.ClassLibInterface.convertClassLibDesc(className);
64          return PrimordialClassLoader.loader.getOrCreateBSType(className);
65      }
66      public final Class getJDKType(jq_Type c) {
67          if (c.getJavaLangClassObject() != null)
68              return c.getJavaLangClassObject();
69          if (c.isPrimitiveType()) 
70              return getJDKType((jq_Primitive)c);
71          else
72              return getJDKType((jq_Reference)c);
73      }
74      public final Class getJDKType(jq_Primitive c) {
75          if (c.getJavaLangClassObject() != null)
76              return c.getJavaLangClassObject();
77          // cannot compare to jq_Primitive types here, as they may not
78          // have been initialized yet.  so we compare descriptors instead.
79          if (c.getDesc() == Utf8.BYTE_DESC) return Byte.TYPE;
80          if (c.getDesc() == Utf8.CHAR_DESC) return Character.TYPE;
81          if (c.getDesc() == Utf8.DOUBLE_DESC) return Double.TYPE;
82          if (c.getDesc() == Utf8.FLOAT_DESC) return Float.TYPE;
83          if (c.getDesc() == Utf8.INT_DESC) return Integer.TYPE;
84          if (c.getDesc() == Utf8.LONG_DESC) return Long.TYPE;
85          if (c.getDesc() == Utf8.SHORT_DESC) return Short.TYPE;
86          if (c.getDesc() == Utf8.BOOLEAN_DESC) return Boolean.TYPE;
87          if (c.getDesc() == Utf8.VOID_DESC) return Void.TYPE;
88          Assert.UNREACHABLE(c.getName());
89          return null;
90      }
91      public Class getJDKType(jq_Reference c) {
92          if (c.getJavaLangClassObject() != null)
93              return c.getJavaLangClassObject();
94          try {
95              return Class.forName(c.getJDKName(), false, Reflection.class.getClassLoader());
96              //return Class.forName(c.getJDKName(), false, c.getClassLoader());
97          } catch (ClassNotFoundException x) {
98              if (REPORT_JDK_ERRORS && !c.getJDKName().startsWith("joeq.ClassLib") && !c.getJDKName().startsWith("L&"))
99                  Debug.writeln("Note: "+c.getJDKName()+" was not found in host jdk");
100             return null;
101         } catch (NoClassDefFoundError nce) {
102             if (REPORT_JDK_ERRORS) Debug.writeln("Note: "+c.getJDKName()+" could not be loaded in host jdk (tried Class.forName)");
103             return null;
104         }
105     }
106     
107     // Map between our jq_Member objects and JDK Member objects
108     public final jq_Field getJQMember(Field f) {
109         jq_Class c = (jq_Class)getJQType(f.getDeclaringClass());
110         //if (c == null) return null;
111         jq_NameAndDesc nd = new jq_NameAndDesc(Utf8.get(f.getName()), getJQType(f.getType()).getDesc());
112         nd = joeq.ClassLib.ClassLibInterface.convertClassLibNameAndDesc(c, nd);
113         jq_Field m = (jq_Field)c.getDeclaredMember(nd);
114         if (m == null) {
115             if (!Utf8.NO_NEW) {
116                 //SystemInterface.debugwriteln("Reference to jdk field "+f.toString()+" does not exist, creating "+c+"."+nd);
117                 if (Modifier.isStatic(f.getModifiers()))
118                     m = c.getOrCreateStaticField(nd);
119                 else
120                     m = c.getOrCreateInstanceField(nd);
121             }
122         }
123         return m;
124     }
125     public final jq_Method getJQMember(Method f) {
126         jq_Class c = (jq_Class)getJQType(f.getDeclaringClass());
127         //if (c == null) return null;
128         StringBuffer desc = new StringBuffer();
129         desc.append('(');
130         Class[] param_types = f.getParameterTypes();
131         for (int i=0; i<param_types.length; ++i) {
132             desc.append(getJQType(param_types[i]).getDesc().toString());
133         }
134         desc.append(')');
135         desc.append(getJQType(f.getReturnType()).getDesc().toString());
136         jq_NameAndDesc nd = new jq_NameAndDesc(Utf8.get(f.getName()), Utf8.get(desc.toString()));
137         nd = joeq.ClassLib.ClassLibInterface.convertClassLibNameAndDesc(c, nd);
138         jq_Method m = (jq_Method)c.getDeclaredMember(nd);
139         if (m == null) {
140             if (!Utf8.NO_NEW) {
141                 //SystemInterface.debugwriteln("Reference to jdk method "+f.toString()+" does not exist, creating "+c+"."+nd);
142                 if (Modifier.isStatic(f.getModifiers()))
143                     m = c.getOrCreateStaticMethod(nd);
144                 else
145                     m = c.getOrCreateInstanceMethod(nd);
146             }
147         }
148         return m;
149     }
150     public final jq_Initializer getJQMember(Constructor f) {
151         jq_Class c = (jq_Class)getJQType(f.getDeclaringClass());
152         //if (c == null) return null;
153         StringBuffer desc = new StringBuffer();
154         desc.append('(');
155         Class[] param_types = f.getParameterTypes();
156         for (int i=0; i<param_types.length; ++i) {
157             desc.append(getJQType(param_types[i]).getDesc().toString());
158         }
159         desc.append(")V");
160         jq_NameAndDesc nd = new jq_NameAndDesc(Utf8.get("<init>"), Utf8.get(desc.toString()));
161         nd = joeq.ClassLib.ClassLibInterface.convertClassLibNameAndDesc(c, nd);
162         jq_Initializer m = (jq_Initializer)c.getDeclaredMember(nd);
163         if (m == null) {
164             if (!Utf8.NO_NEW) {
165                 //SystemInterface.debugwriteln("Reference to jdk constructor "+f.toString()+" does not exist, creating "+c+"."+nd);
166                 m = (jq_Initializer)c.getOrCreateInstanceMethod(nd);
167             }
168         }
169         return m;
170     }
171     public boolean USE_DECLARED_FIELDS_CACHE = true;
172     private static java.util.HashMap declaredFieldsCache;
173     public final Field getJDKField(Class c, String name) {
174         Field[] fields = null;
175         if (USE_DECLARED_FIELDS_CACHE) {
176             if (declaredFieldsCache == null) declaredFieldsCache = new java.util.HashMap();
177             else fields = (Field[])declaredFieldsCache.get(c);
178             if (fields == null) {
179                 try {
180                     fields = c.getDeclaredFields();
181                 } catch (NoClassDefFoundError x) {
182                     if (REPORT_JDK_ERRORS) Debug.writeln("Note: "+c+" could not be loaded in host jdk");
183                     return null;
184                 }
185                 declaredFieldsCache.put(c, fields);
186             }
187         } else {
188             try {
189                 fields = c.getDeclaredFields();
190             } catch (NoClassDefFoundError x) {
191                 if (REPORT_JDK_ERRORS) Debug.writeln("Note: "+c+" could not be loaded in host jdk");
192                 return null;
193             }
194         }
195         for (int i=0; i<fields.length; ++i) {
196             Field f2 = fields[i];
197             if (f2.getName().equals(name)) {
198                 //f2.setAccessible(true);
199                 return f2;
200             }
201         }
202         //jq.UNREACHABLE(c+"."+name);
203         return null;
204     }
205     public final Method getJDKMethod(Class c, String name, Class[] args) {
206         Method[] methods;
207         try {
208             methods = c.getDeclaredMethods();
209         } catch (NoClassDefFoundError x) {
210             if (REPORT_JDK_ERRORS) Debug.writeln("Note: "+c+" could not be loaded in host jdk");
211             return null;
212         }
213 uphere:
214         for (int i=0; i<methods.length; ++i) {
215             Method f2 = methods[i];
216             if (f2.getName().equals(name)) {
217                 Class[] args2 = f2.getParameterTypes();
218                 if (args.length != args2.length) continue uphere;
219                 for (int j=0; j<args.length; ++j) {
220                     if (!args[j].equals(args2[j])) continue uphere;
221                 }
222                 //f2.setAccessible(true);
223                 return f2;
224             }
225         }
226         //jq.UNREACHABLE(c+"."+name+" "+args);
227         return null;
228     }
229     public final Constructor getJDKConstructor(Class c, Class[] args) {
230         Constructor[] consts;
231         try {
232             consts = c.getDeclaredConstructors();
233         } catch (NoClassDefFoundError x) {
234             if (REPORT_JDK_ERRORS) Debug.writeln("Note: "+c+" could not be loaded in host jdk");
235             return null;
236         }
237 uphere:
238         for (int i=0; i<consts.length; ++i) {
239             Constructor f2 = consts[i];
240             Class[] args2 = f2.getParameterTypes();
241             if (args.length != args2.length) continue uphere;
242             for (int j=0; j<args.length; ++j) {
243                 if (!args[j].equals(args2[j])) continue uphere;
244             }
245             //f2.setAccessible(true);
246             return f2;
247         }
248         //jq.UNREACHABLE(c+".<init> "+args);
249         return null;
250     }
251     public final Member getJDKMember(jq_Member m) {
252         if (m.getJavaLangReflectMemberObject() != null)
253             return m.getJavaLangReflectMemberObject();
254         Class c = getJDKType(m.getDeclaringClass());
255         if (m instanceof jq_Field) {
256             Member ret = getJDKField(c, m.getName().toString());
257             if (ret == null) {
258                 // TODO: a synthetic field, so there is no java.lang.reflect.Field object yet.
259             }
260             return ret;
261         } else if (m instanceof jq_Initializer) {
262             jq_Initializer m2 = (jq_Initializer)m;
263             jq_Type[] param_types = m2.getParamTypes();
264             int num_of_args = param_types.length-1; // -1 for this ptr
265             Class[] args = new Class[num_of_args];
266             for (int i=0; i<num_of_args; ++i) {
267                 args[i] = getJDKType(param_types[i+1]);
268             }
269             Member ret = getJDKConstructor(c, args);
270             if (ret == null) {
271                 // TODO: a synthetic field, so there is no java.lang.reflect.Field object yet.
272             }
273             return ret;
274         } else if (m instanceof jq_ClassInitializer) {
275             return null; // <clinit> methods have no Method object
276         } else {
277             Assert._assert(m instanceof jq_Method);
278             jq_Method m2 = (jq_Method)m;
279             int offset = m2.isStatic()?0:1;
280             jq_Type[] param_types = m2.getParamTypes();
281             int num_of_args = param_types.length-offset;
282             Class[] args = new Class[num_of_args];
283             for (int i=0; i<num_of_args; ++i) {
284                 args[i] = getJDKType(param_types[i+offset]);
285             }
286             Member ret = getJDKMethod(c, m.getName().toString(), args);
287             if (ret == null) {
288                 // TODO: a synthetic field, so there is no java.lang.reflect.Field object yet.
289             }
290             return ret;
291         }
292     }
293     
294     // reflective invocations.
295     public void invokestatic_V(jq_StaticMethod m) throws Throwable {
296         Assert.UNREACHABLE();
297     }
298     public int invokestatic_I(jq_StaticMethod m) throws Throwable {
299         Assert.UNREACHABLE();
300         return 0;
301     }
302     public Object invokestatic_A(jq_StaticMethod m) throws Throwable {
303         Assert.UNREACHABLE();
304         return null;
305     }
306     public long invokestatic_J(jq_StaticMethod m) throws Throwable {
307         Assert.UNREACHABLE();
308         return 0L;
309     }
310     public void invokestatic_V(jq_StaticMethod m, Object arg1) throws Throwable {
311         Assert.UNREACHABLE();
312         return;
313     }
314     public void invokeinstance_V(jq_InstanceMethod m, Object dis) throws Throwable {
315         Assert.UNREACHABLE();
316         return;
317     }
318     public Object invokeinstance_A(jq_InstanceMethod m, Object dis) throws Throwable {
319         Assert.UNREACHABLE();
320         return null;
321     }
322     public void invokeinstance_V(jq_InstanceMethod m, Object dis, Object arg1) throws Throwable {
323         Assert.UNREACHABLE();
324         return;
325     }
326     public Object invokeinstance_A(jq_InstanceMethod m, Object dis, Object arg1) throws Throwable {
327         Assert.UNREACHABLE();
328         return null;
329     }
330     public boolean invokeinstance_Z(jq_InstanceMethod m, Object dis, Object arg1) throws Throwable {
331         Assert.UNREACHABLE();
332         return false;
333     }
334     public void invokeinstance_V(jq_InstanceMethod m, Object dis, Object arg1, Object arg2) throws Throwable {
335         Assert.UNREACHABLE();
336         return;
337     }
338     public void invokeinstance_V(jq_InstanceMethod m, Object dis, Object arg1, Object arg2, Object arg3) throws Throwable {
339         Assert.UNREACHABLE();
340         return;
341     }
342     public void invokeinstance_V(jq_InstanceMethod m, Object dis, Object arg1, Object arg2, Object arg3, long arg4) throws Throwable {
343           Assert.UNREACHABLE();
344             return;
345     }
346     public void invokeinstance_V(jq_InstanceMethod m, Object dis, Object arg1, int arg2, long arg3, int arg4) throws Throwable {
347             Assert.UNREACHABLE();
348             return;
349     }
350     public long invoke(jq_Method m, Object dis, Object[] args)
351         throws IllegalArgumentException, InvocationTargetException
352     {
353         Assert.UNREACHABLE();
354         return 0L;
355     }
356     public Address invokeA(jq_Method m, Object dis, Object[] args)
357         throws IllegalArgumentException, InvocationTargetException
358     {
359         Assert.UNREACHABLE();
360         return null;
361     }
362     
363     public int getfield_I(Object o, jq_InstanceField f) {
364         Assert._assert(f.getType() == jq_Primitive.INT || f.getType() == jq_Primitive.FLOAT);
365         Object q = Reflection.obj_trav.getInstanceFieldValue(o, f);
366         if (q == null) return 0;
367         return ((Integer)q).intValue();
368     }
369     public long getfield_L(Object o, jq_InstanceField f) {
370         Assert._assert(f.getType() == jq_Primitive.LONG || f.getType() == jq_Primitive.DOUBLE);
371         Object q = Reflection.obj_trav.getInstanceFieldValue(o, f);
372         if (q == null) return 0L;
373         return ((Long)q).longValue();
374     }
375     public float getfield_F(Object o, jq_InstanceField f) {
376         Assert._assert(f.getType() == jq_Primitive.FLOAT);
377         Object q = Reflection.obj_trav.getInstanceFieldValue(o, f);
378         if (q == null) return 0f;
379         return ((Float)q).floatValue();
380     }
381     public double getfield_D(Object o, jq_InstanceField f) {
382         Assert._assert(f.getType() == jq_Primitive.DOUBLE);
383         Object q = Reflection.obj_trav.getInstanceFieldValue(o, f);
384         if (q == null) return 0.;
385         return ((Double)q).doubleValue();
386     }
387     public Object getfield_A(Object o, jq_InstanceField f) {
388         Assert._assert(f.getType().isReferenceType() && !f.getType().isAddressType());
389         return Reflection.obj_trav.getInstanceFieldValue(o, f);
390     }
391     public Address getfield_P(Object o, jq_InstanceField f) {
392         Assert._assert(f.getType().isAddressType());
393         return (Address)Reflection.obj_trav.getInstanceFieldValue(o, f);
394     }
395     public byte getfield_B(Object o, jq_InstanceField f) {
396         Assert._assert(f.getType() == jq_Primitive.BYTE);
397         Object q = Reflection.obj_trav.getInstanceFieldValue(o, f);
398         if (q == null) return 0;
399         return ((Byte)q).byteValue();
400     }
401     public char getfield_C(Object o, jq_InstanceField f) {
402         Assert._assert(f.getType() == jq_Primitive.CHAR);
403         Object q = Reflection.obj_trav.getInstanceFieldValue(o, f);
404         if (q == null) return 0;
405         return ((Character)q).charValue();
406     }
407     public short getfield_S(Object o, jq_InstanceField f) {
408         Assert._assert(f.getType() == jq_Primitive.SHORT);
409         Object q = Reflection.obj_trav.getInstanceFieldValue(o, f);
410         if (q == null) return 0;
411         return ((Short)q).shortValue();
412     }
413     public boolean getfield_Z(Object o, jq_InstanceField f) {
414         Assert._assert(f.getType() == jq_Primitive.BOOLEAN);
415         Object q = Reflection.obj_trav.getInstanceFieldValue(o, f);
416         if (q == null) return false;
417         return ((Boolean)q).booleanValue();
418     }
419     public Object getfield(Object o, jq_InstanceField f) {
420         return Reflection.obj_trav.getInstanceFieldValue(o, f);
421     }
422     public void putfield_I(Object o, jq_InstanceField f, int v) {
423         Assert._assert(f.getType() == jq_Primitive.INT || f.getType() == jq_Primitive.FLOAT);
424         Reflection.obj_trav.putInstanceFieldValue(o, f, new Integer(v));
425         return;
426     }
427     public void putfield_L(Object o, jq_InstanceField f, long v) {
428         Assert._assert(f.getType() == jq_Primitive.LONG || f.getType() == jq_Primitive.DOUBLE);
429         Reflection.obj_trav.putInstanceFieldValue(o, f, new Long(v));
430         return;
431     }
432     public void putfield_F(Object o, jq_InstanceField f, float v) {
433         Assert._assert(f.getType() == jq_Primitive.FLOAT);
434         Reflection.obj_trav.putInstanceFieldValue(o, f, new Float(v));
435         return;
436     }
437     public void putfield_D(Object o, jq_InstanceField f, double v) {
438         Assert._assert(f.getType() == jq_Primitive.DOUBLE);
439         Reflection.obj_trav.putInstanceFieldValue(o, f, new Double(v));
440         return;
441     }
442     public void putfield_A(Object o, jq_InstanceField f, Object v) {
443         Reflection.obj_trav.putInstanceFieldValue(o, f, v);
444         return;
445     }
446     public void putfield_P(Object o, jq_InstanceField f, Address v) {
447         Assert._assert(f.getType().isAddressType());
448         Reflection.obj_trav.putInstanceFieldValue(o, f, v);
449         return;
450     }
451     public void putfield_B(Object o, jq_InstanceField f, byte v) {
452         Assert._assert(f.getType() == jq_Primitive.BYTE);
453         Reflection.obj_trav.putInstanceFieldValue(o, f, new Byte(v));
454         return;
455     }
456     public void putfield_C(Object o, jq_InstanceField f, char v) {
457         Assert._assert(f.getType() == jq_Primitive.CHAR);
458         Reflection.obj_trav.putInstanceFieldValue(o, f, new Character(v));
459         return;
460     }
461     public void putfield_S(Object o, jq_InstanceField f, short v) {
462         Assert._assert(f.getType() == jq_Primitive.SHORT);
463         Reflection.obj_trav.putInstanceFieldValue(o, f, new Short(v));
464         return;
465     }
466     public void putfield_Z(Object o, jq_InstanceField f, boolean v) {
467         Assert._assert(f.getType() == jq_Primitive.BOOLEAN);
468             Reflection.obj_trav.putInstanceFieldValue(o, f, Convert.getBoolean(v));
469             return;
470     }
471     
472     public int getstatic_I(jq_StaticField f) {
473         Assert._assert(f.getType() == jq_Primitive.INT || f.getType() == jq_Primitive.FLOAT);
474         Object o = Reflection.obj_trav.getStaticFieldValue(f);
475         if (o == null) return 0;
476         return ((Integer)o).intValue();
477     }
478     public long getstatic_L(jq_StaticField f) {
479         Assert._assert(f.getType() == jq_Primitive.LONG || f.getType() == jq_Primitive.DOUBLE);
480         Object o = Reflection.obj_trav.getStaticFieldValue(f);
481         if (o == null) return 0L;
482         return ((Long)o).longValue();
483     }
484     public float getstatic_F(jq_StaticField f) {
485         Assert._assert(f.getType() == jq_Primitive.FLOAT);
486         Object o = Reflection.obj_trav.getStaticFieldValue(f);
487         if (o == null) return 0L;
488         return ((Float)o).floatValue();
489     }
490     public double getstatic_D(jq_StaticField f) {
491         Assert._assert(f.getType() == jq_Primitive.DOUBLE);
492         Object o = Reflection.obj_trav.getStaticFieldValue(f);
493         if (o == null) return 0L;
494         return ((Double)o).doubleValue();
495     }
496     public Object getstatic_A(jq_StaticField f) {
497         Assert._assert(f.getType().isReferenceType() && !f.getType().isAddressType());
498         return Reflection.obj_trav.getStaticFieldValue(f);
499     }
500     public Address getstatic_P(jq_StaticField f) {
501         Assert._assert(f.getType().isAddressType());
502         Address a = (Address)Reflection.obj_trav.getStaticFieldValue(f);
503         return a;
504     }
505     public boolean getstatic_Z(jq_StaticField f) {
506         Assert._assert(f.getType() == jq_Primitive.BOOLEAN);
507             Object o = Reflection.obj_trav.getStaticFieldValue(f);
508             if (o == null) return false;
509             return ((Boolean)o).booleanValue();
510     }
511     public byte getstatic_B(jq_StaticField f) {
512         Assert._assert(f.getType() == jq_Primitive.BYTE);
513         Object o = Reflection.obj_trav.getStaticFieldValue(f);
514         if (o == null) return 0;
515         return ((Byte)o).byteValue();
516     }
517     public short getstatic_S(jq_StaticField f) {
518         Assert._assert(f.getType() == jq_Primitive.SHORT);
519         Object o = Reflection.obj_trav.getStaticFieldValue(f);
520         if (o == null) return 0;
521         return ((Short)o).shortValue();
522     }
523     public char getstatic_C(jq_StaticField f) {
524         Assert._assert(f.getType() == jq_Primitive.CHAR);
525         Object o = Reflection.obj_trav.getStaticFieldValue(f);
526         if (o == null) return 0;
527         return ((Character)o).charValue();
528     }
529     public void putstatic_I(jq_StaticField f, int v) {
530         Assert._assert(f.getType() == jq_Primitive.INT);
531         f.getDeclaringClass().setStaticData(f, v);
532     }
533     public void putstatic_L(jq_StaticField f, long v) {
534         Assert._assert(f.getType() == jq_Primitive.LONG);
535         f.getDeclaringClass().setStaticData(f, v);
536     }
537     public void putstatic_F(jq_StaticField f, float v) {
538         Assert._assert(f.getType() == jq_Primitive.FLOAT);
539         f.getDeclaringClass().setStaticData(f, v);
540     }
541     public void putstatic_D(jq_StaticField f, double v) {
542         Assert._assert(f.getType() == jq_Primitive.DOUBLE);
543         f.getDeclaringClass().setStaticData(f, v);
544     }
545     public void putstatic_A(jq_StaticField f, Object v) {
546         Assert._assert(v == null || TypeCheck.isAssignable(jq_Reference.getTypeOf(v), f.getType()));
547         Assert._assert(!f.getType().isAddressType());
548         f.getDeclaringClass().setStaticData(f, v);
549     }
550     public void putstatic_P(jq_StaticField f, Address v) {
551         Assert._assert(f.getType().isAddressType());
552         f.getDeclaringClass().setStaticData(f, v);
553     }
554     public void putstatic_Z(jq_StaticField f, boolean v) {
555         Assert._assert(f.getType() == jq_Primitive.BOOLEAN);
556         f.getDeclaringClass().setStaticData(f, v?1:0);
557     }
558     public void putstatic_B(jq_StaticField f, byte v) {
559         Assert._assert(f.getType() == jq_Primitive.BYTE);
560         f.getDeclaringClass().setStaticData(f, (int)v);
561     }
562     public void putstatic_S(jq_StaticField f, short v) {
563         Assert._assert(f.getType() == jq_Primitive.SHORT);
564         f.getDeclaringClass().setStaticData(f, (int)v);
565     }
566     public void putstatic_C(jq_StaticField f, char v) {
567         Assert._assert(f.getType() == jq_Primitive.CHAR);
568         f.getDeclaringClass().setStaticData(f, (int)v);
569     }
570     
571     public int arraylength(Object o) {
572         Assert._assert(getTypeOf(o).isArrayType());
573         return Array.getLength(o);
574     }
575     public Object arrayload_A(Object[] o, int i) {
576         return Reflection.obj_trav.mapValue(o[i]);
577     }
578     public Address arrayload_R(Address[] o, int i) {
579         return o[i];
580     }
581 
582     public void registerNullStaticFields(Set s) {
583         s.add(_declaredFieldsCache);
584     }
585 
586     public void initialize() {
587         _class = (jq_Class)PrimordialClassLoader.loader.getOrCreateBSType("Ljoeq/Runtime/BasicReflectionImpl;");
588         _declaredFieldsCache = _class.getOrCreateStaticField("declaredFieldsCache", "Ljava/util/HashMap;");
589     }
590     
591     public static jq_Class _class;
592     public static jq_StaticField _declaredFieldsCache;
593 }