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