1
2
3
4 package joeq.Runtime;
5
6 import java.util.Iterator;
7 import java.io.PrintStream;
8 import java.lang.reflect.Field;
9 import java.lang.reflect.Modifier;
10 import joeq.Class.jq_Class;
11 import joeq.Class.jq_InstanceField;
12 import joeq.Class.jq_StaticField;
13 import joeq.ClassLib.ClassLibInterface;
14 import joeq.Main.jq;
15 import joeq.UTF.Utf8;
16 import jwutil.util.Assert;
17
18 /***
19 * ObjectTraverser
20 *
21 * @author John Whaley <jwhaley@alum.mit.edu>
22 * @version $Id: ObjectTraverser.java 2475 2006-12-24 09:44:50Z joewhaley $
23 */
24 public abstract class ObjectTraverser {
25
26 public abstract void initialize();
27 public abstract Object mapStaticField(jq_StaticField f);
28 public abstract Object mapInstanceField(Object o, jq_InstanceField f);
29 public abstract Object mapValue(Object o);
30
31 public static
32 public static final PrintStream out = System.out;
33
34 public static final java.lang.Object NO_OBJECT = new java.lang.Object();
35
36 public Object getStaticFieldValue(jq_StaticField f) {
37 if (jq.IsBootstrapping) {
38 java.lang.Object result = this.mapStaticField(f);
39 if (result != NO_OBJECT) return this.mapValue(result);
40 }
41
42 if (TRACE) out.println("Getting value of static field "+f+" via reflection");
43 Field f2 = (Field) f.getJavaLangReflectMemberObject();
44 if (f2 == null) {
45 Class c = Reflection.getJDKType(f.getDeclaringClass());
46 String fieldName = f.getName().toString();
47 f2 = lookupField(c, fieldName);
48 if (f2 == null) {
49 out.println("Cannot find static field "+f);
50 return null;
51 }
52 }
53 return getStaticFieldValue_reflection(f2);
54 }
55
56 public static Field lookupField(Class c, String fieldName) {
57 Field f2 = Reflection.getJDKField(c, fieldName);
58 if (f2 == null) {
59 jq_Class klass = (jq_Class)Reflection.getJQType(c);
60 for (Iterator i = ClassLibInterface.DEFAULT.getImplementationClassDescs(klass.getDesc()); i.hasNext(); ) {
61 Utf8 u = (Utf8)i.next();
62 if (TRACE) out.println("Checking mirror class "+u);
63 String s = u.toString();
64 Assert._assert(s.charAt(0) == 'L');
65 try {
66 c = Class.forName(s.substring(1, s.length()-1).replace('/', '.'));
67 f2 = Reflection.getJDKField(c, fieldName);
68 if (f2 != null) break;
69 } catch (ClassNotFoundException x) {
70 if (TRACE) out.println("Mirror class "+s+" doesn't exist");
71 }
72 }
73 }
74 return f2;
75 }
76
77 public Object getStaticFieldValue_reflection(Field f2) {
78 f2.setAccessible(true);
79 Assert._assert((f2.getModifiers() & Modifier.STATIC) != 0);
80 try {
81 Object o = f2.get(null);
82 if (jq.IsBootstrapping) o = this.mapValue(o);
83 return o;
84 } catch (IllegalAccessException x) {
85 Assert.UNREACHABLE();
86 return null;
87 }
88 }
89
90 public Object getInstanceFieldValue(Object base, jq_InstanceField f) {
91 if (jq.IsBootstrapping) {
92 java.lang.Object result = this.mapInstanceField(base, f);
93 if (result != NO_OBJECT) return this.mapValue(result);
94 }
95
96 if (TRACE) out.println("Getting value of instance field "+f+" via reflection");
97 Field f2 = (Field) f.getJavaLangReflectMemberObject();
98 if (f2 == null) {
99 Class c = Reflection.getJDKType(f.getDeclaringClass());
100 String fieldName = f.getName().toString();
101 f2 = lookupField(c, fieldName);
102 if (f2 == null) {
103 out.println("Cannot find instance field "+f);
104 return null;
105 }
106 }
107 return getInstanceFieldValue_reflection(base, f2);
108 }
109 public Object getInstanceFieldValue_reflection(Object base, Field f2) {
110 f2.setAccessible(true);
111 Assert._assert((f2.getModifiers() & Modifier.STATIC) == 0);
112 try {
113 Object o = f2.get(base);
114 if (jq.IsBootstrapping) o = this.mapValue(o);
115 return o;
116 } catch (IllegalAccessException x) {
117 Assert.UNREACHABLE();
118 return null;
119 } catch (IllegalArgumentException x) {
120 System.err.println("Cannot access "+f2+" in object of type "+base.getClass());
121 throw x;
122 }
123 }
124
125 public void putStaticFieldValue(jq_StaticField f, Object o) {
126 Field f2 = (Field) f.getJavaLangReflectMemberObject();
127 if (f2 == null) {
128 Class c = Reflection.getJDKType(f.getDeclaringClass());
129 String fieldName = f.getName().toString();
130 f2 = lookupField(c, fieldName);
131 }
132 putStaticFieldValue_reflection(f2, o);
133 }
134 public void putStaticFieldValue_reflection(Field f2, Object o) {
135 if (TRACE) out.println("Setting value of static field "+f2+" via reflection");
136 f2.setAccessible(true);
137 Assert._assert((f2.getModifiers() & Modifier.STATIC) != 0);
138 try {
139 f2.set(null, o);
140 } catch (IllegalAccessException x) {
141 Assert.UNREACHABLE();
142 }
143 }
144
145 public void putInstanceFieldValue(Object base, jq_InstanceField f, Object o) {
146 Field f2 = (Field) f.getJavaLangReflectMemberObject();
147 if (f2 == null) {
148 Class c = Reflection.getJDKType(f.getDeclaringClass());
149 String fieldName = f.getName().toString();
150 f2 = lookupField(c, fieldName);
151 }
152 putInstanceFieldValue_reflection(base, f2, o);
153 }
154 public void putInstanceFieldValue_reflection(Object base, Field f2, Object o) {
155 if (TRACE) out.println("Setting value of static field "+f2+" via reflection");
156 f2.setAccessible(true);
157 Assert._assert((f2.getModifiers() & Modifier.STATIC) == 0);
158 try {
159 f2.set(base, o);
160 } catch (IllegalAccessException x) {
161 Assert.UNREACHABLE();
162 }
163 }
164 }