1 cananian 1.1.2.1 // DataReflectionMemberList.java, created Sat Oct 16 13:43:17 1999 by cananian
  2 cananian 1.1.2.1 // Copyright (C) 1999 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.1.2.1 package harpoon.Backend.Runtime1;
  5 cananian 1.1.2.1 
  6 cananian 1.1.2.1 import harpoon.Analysis.ClassHierarchy;
  7 cananian 1.1.2.1 import harpoon.Backend.Generic.Frame;
  8 cananian 1.1.2.1 import harpoon.Backend.Generic.Runtime.ObjectBuilder.ObjectInfo;
  9 cananian 1.1.2.1 import harpoon.Backend.Generic.Runtime.ObjectBuilder;
 10 cananian 1.1.2.1 import harpoon.Backend.Maps.NameMap;
 11 cananian 1.1.2.1 import harpoon.ClassFile.HClass;
 12 cananian 1.1.2.3 import harpoon.ClassFile.HConstructor;
 13 cananian 1.1.2.1 import harpoon.ClassFile.HDataElement;
 14 cananian 1.1.2.1 import harpoon.ClassFile.HField;
 15 cananian 1.1.2.1 import harpoon.ClassFile.HMember;
 16 cananian 1.1.2.1 import harpoon.ClassFile.HMethod;
 17 cananian 1.1.2.1 import harpoon.IR.Tree.Stm;
 18 cananian 1.1.2.1 import harpoon.IR.Tree.TreeFactory;
 19 cananian 1.1.2.1 import harpoon.IR.Tree.ALIGN;
 20 cananian 1.1.2.1 import harpoon.IR.Tree.CONST;
 21 cananian 1.1.2.1 import harpoon.IR.Tree.LABEL;
 22 cananian 1.1.2.1 import harpoon.IR.Tree.SEGMENT;
 23 cananian 1.1.2.1 import harpoon.Temp.Label;
 24 cananian 1.1.2.1 
 25 cananian 1.1.2.1 import java.util.ArrayList;
 26 cananian 1.1.2.1 import java.util.Arrays;
 27 cananian 1.1.2.1 import java.util.Collections;
 28 cananian 1.1.2.1 import java.util.Comparator;
 29 cananian 1.1.2.1 import java.util.Iterator;
 30 cananian 1.1.2.1 import java.util.List;
 31 cananian 1.1.2.1 /**
 32 cananian 1.1.2.1  * <code>DataReflectionMemberList</code> creates tables which the JNI interface
 33 cananian 1.1.2.1  * will use.  This includes:<OL>
 34 cananian 1.1.2.1  * <LI>a table to map <code>java.lang.reflect.Field</code> objects to field
 35 cananian 1.1.2.1  *     information structures, sorted in order of the (non-relocatable)
 36 cananian 1.1.2.1  *     <code>Field</code> object address.
 37 cananian 1.1.2.1  *     (begins at <code>field2info_start</code>, ends at
 38 cananian 1.1.2.1  *      <code>field2info_end</code>)
 39 cananian 1.1.2.1  * <LI>a table to map <code>java.lang.reflect.Method</code> objects to method
 40 cananian 1.1.2.1  *     information structures, sorted in order of the (non-relocatable)
 41 cananian 1.1.2.1  *     <code>Method</code> object address.
 42 cananian 1.1.2.1  *     (begins at <code>method2info_start</code>, ends at
 43 cananian 1.1.2.1  *      <code>method2info_end</code>)
 44 cananian 1.1.2.1  * <LI>Static <Code>java.lang.reflect.Field</code> objects.  As the JDK
 45 cananian 1.1.2.1  *     dictates, these contain no actual field data; however, table #1 above
 46 cananian 1.1.2.1  *     is keyed by the object address to fetch the actual field information
 47 cananian 1.1.2.1  *     structures.
 48 cananian 1.1.2.1  * <LI>Static <Code>java.lang.reflect.Method</code> objects.  As the JDK
 49 cananian 1.1.2.1  *     dictates, these contain no actual method data; however, table #2 above
 50 cananian 1.1.2.1  *     is keyed by the object address to fetch the actual method information
 51 cananian 1.1.2.1  *     structures.
 52 cananian 1.1.2.1  * </OL>
 53 cananian 1.1.2.1  * 
 54 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 55 cananian 1.6      * @version $Id: DataReflectionMemberList.java,v 1.6 2004/02/08 03:20:58 cananian Exp $
 56 cananian 1.1.2.1  */
 57 cananian 1.1.2.1 public class DataReflectionMemberList extends Data {
 58 cananian 1.1.2.1     final NameMap m_nm;
 59 cananian 1.1.2.1     final ObjectBuilder m_ob;
 60 cananian 1.4         final boolean pointersAreLong;
 61 cananian 1.1.2.1     
 62 cananian 1.1.2.1     /** Creates a <code>DataReflectionMemberList</code>. */
 63 cananian 1.1.2.1     public DataReflectionMemberList(Frame f, HClass hc, ClassHierarchy ch) {
 64 cananian 1.1.2.1         super("reflection-data-method-list", hc, f);
 65 cananian 1.1.2.6         this.m_nm = f.getRuntime().getNameMap();
 66 cananian 1.1.2.1         this.m_ob = ((Runtime) f.getRuntime()).ob;
 67 cananian 1.4             this.pointersAreLong = f.pointersAreLong();
 68 cananian 1.1.2.1         // only build one of these (so we can make sure the
 69 cananian 1.1.2.1         // table is properly sorted); wait until hc is
 70 cananian 1.1.2.1         // java.lang.Object
 71 cananian 1.1.2.1         this.root = (hc==linker.forName("java.lang.Object")) ?
 72 cananian 1.1.2.1             build(ch) : null;
 73 cananian 1.1.2.1     }
 74 cananian 1.1.2.1     private HDataElement build(ClassHierarchy ch) {
 75 cananian 1.1.2.1         // okay, some preliminaries first: build ordered list of
 76 cananian 1.1.2.1         // methods.
 77 cananian 1.1.2.1         List orderedMethods = new ArrayList(ch.callableMethods());
 78 cananian 1.1.2.1         List orderedFields = new ArrayList();
 79 cananian 1.6             for (Object hcO : ch.classes()) {
 80 cananian 1.6                 HClass hc = (HClass) hcO;
 81 cananian 1.1.2.1             orderedFields.addAll(Arrays.asList(hc.getDeclaredFields()));
 82 cananian 1.1.2.1         }
 83 cananian 1.1.2.1 
 84 cananian 1.1.2.1         List stmlist = new ArrayList(6);
 85 cananian 1.1.2.1         // change to table data segment.
 86 cananian 1.1.2.1         stmlist.add(new SEGMENT(tf, null, SEGMENT.REFLECTION_DATA));
 87 cananian 1.1.2.1         // build field object -> field info table.
 88 cananian 1.1.2.1         stmlist.add(buildMember2Info(orderedFields, false));
 89 cananian 1.1.2.1         // build method object -> method info table.
 90 cananian 1.1.2.1         stmlist.add(buildMember2Info(orderedMethods, true));
 91 cananian 1.1.2.1         // change to object data segment.
 92 cananian 1.1.2.1         stmlist.add(new SEGMENT(tf, null, SEGMENT.REFLECTION_OBJECTS));
 93 cananian 1.1.2.1         // build actual field objects
 94 cananian 1.1.2.5         stmlist.add(buildMemberObjects(orderedFields));
 95 cananian 1.1.2.5         // build actual constructor/method objects
 96 cananian 1.1.2.5         stmlist.add(buildMemberObjects(orderedMethods));
 97 cananian 1.1.2.1         // yay, done.
 98 cananian 1.1.2.1         return (HDataElement) Stm.toStm(stmlist);
 99 cananian 1.1.2.1     }
100 cananian 1.1.2.1     private Label memberLabel(HMember hm, String suffix) {
101 cananian 1.1.2.1         if (hm instanceof HField)
102 cananian 1.1.2.1             return m_nm.label((HField)hm, suffix);
103 cananian 1.1.2.1         else return m_nm.label((HMethod)hm, suffix);
104 cananian 1.1.2.1     }
105 cananian 1.1.2.1     private Stm buildMember2Info(List ordered, boolean membersAreMethods) {
106 cananian 1.1.2.1         String member = membersAreMethods ? "method" : "field";
107 cananian 1.1.2.1         List stmlist = new ArrayList(3+2*ordered.size());
108 cananian 1.1.2.1         // make a ordered table mapping Field objects to field info structures.
109 cananian 1.5             stmlist.add(new ALIGN(tf, null, // align table to pointer size
110 cananian 1.5                                   pointersAreLong ? 8 : 4));
111 cananian 1.1.2.1         stmlist.add(new LABEL(tf, null,
112 cananian 1.1.2.1                               new Label(m_nm.c_function_name
113 cananian 1.1.2.1                                         (member+"2info_start")), true));
114 cananian 1.6             for (Object hmO : ordered) {
115 cananian 1.6                 HMember hm = (HMember) hmO;
116 cananian 1.1.2.2             stmlist.add(new LABEL(tf, null,
117 cananian 1.1.2.2                                   memberLabel(hm, "reflectinfo"), true));
118 cananian 1.1.2.1             stmlist.add(_DATUM(memberLabel(hm, "obj")));
119 cananian 1.1.2.1             stmlist.add(_DATUM(memberLabel(hm, "info")));
120 cananian 1.1.2.2             stmlist.add(_DATUM(m_nm.label(hm.getDeclaringClass(),"classobj")));
121 cananian 1.1.2.2             stmlist.add(_DATUM(new CONST(tf, null, hm.getModifiers())));
122 cananian 1.4                 // padding for 64-bit platforms.
123 cananian 1.4                 if (pointersAreLong)
124 cananian 1.4                     stmlist.add(_DATUM(new CONST(tf, null, 0)));
125 cananian 1.1.2.1         }
126 cananian 1.1.2.1         stmlist.add(new LABEL(tf, null,
127 cananian 1.1.2.1                               new Label(m_nm.c_function_name
128 cananian 1.1.2.1                                         (member+"2info_end")), true));
129 cananian 1.3             // We need to put something after the label to keep gcc from
130 cananian 1.3             // moving <xxx>2info_end into the .bss section when compiling with
131 cananian 1.3             // the PreciseC backend.
132 cananian 1.3             stmlist.add(_DATUM(new Label(m_nm.c_function_name
133 cananian 1.3                                          (member+"2info_end"))));
134 cananian 1.3             // okay, done.
135 cananian 1.1.2.1         return Stm.toStm(stmlist);
136 cananian 1.1.2.1     }
137 cananian 1.1.2.5     private Stm buildMemberObjects(List ordered) {
138 cananian 1.1.2.1         List stmlist = new ArrayList(ordered.size());
139 cananian 1.1.2.1         final HClass HCclass = linker.forName("java.lang.Class");
140 cananian 1.1.2.1         for (Iterator it=ordered.iterator(); it.hasNext(); ) {
141 cananian 1.1.2.1             final HMember hm = (HMember) it.next();
142 cananian 1.1.2.5             final HClass type = linker.forName
143 cananian 1.1.2.5                 ("java.lang.reflect." +
144 cananian 1.1.2.5                  (hm instanceof HField ? "Field" :
145 cananian 1.1.2.5                   hm instanceof HConstructor ? "Constructor" : "Method"));
146 cananian 1.1.2.1             // make an ObjectInfo -- that doesn't actual provide any info.
147 cananian 1.1.2.1             ObjectInfo info = new ObjectInfo() {
148 cananian 1.1.2.1                 public HClass type() { return type; }
149 cananian 1.1.2.1                 public Label label() { return memberLabel(hm, "obj"); }
150 cananian 1.1.2.1                 public Object get(HField hf) {
151 cananian 1.1.2.4                     if (hf.equals(HFclazz)) {
152 cananian 1.1.2.1                         final HClass hc = hf.getDeclaringClass();
153 cananian 1.1.2.1                         return new ObjectInfo() {
154 cananian 1.1.2.1                             public HClass type() { return HCclass; }
155 cananian 1.1.2.1                             public Label label() {
156 cananian 1.1.2.1                                 return m_nm.label(hc, "classobj");
157 cananian 1.1.2.1                             }
158 cananian 1.1.2.1                             public Object get(HField hff) {
159 cananian 1.1.2.1                                 throw new Error("Not building this object");
160 cananian 1.1.2.1                             }
161 cananian 1.1.2.1                         };
162 cananian 1.1.2.1                     }
163 cananian 1.1.2.1                     //XXX: Methods and Field objects have lots of fields.
164 cananian 1.1.2.1                     //we basically zero-fill everything.
165 cananian 1.1.2.4                     if (hf.equals(HFslot)) return new Integer(0);
166 cananian 1.1.2.1                     return null;
167 cananian 1.1.2.1                 }
168 cananian 1.1.2.4                 HField HFclazz = null, HFslot = null;
169 cananian 1.1.2.4                 {
170 cananian 1.1.2.4                     // our hacked reflection classes don't have these fields,
171 cananian 1.1.2.4                     // don't have a cow.
172 cananian 1.1.2.4                     try {
173 cananian 1.1.2.4                         HFclazz=type.getField("clazz");
174 cananian 1.1.2.4                         HFslot=type.getField("slot");
175 cananian 1.1.2.4                     } catch (NoSuchFieldError e) { /* ignore */ }
176 cananian 1.1.2.4                 }
177 cananian 1.1.2.1             };
178 cananian 1.1.2.1             stmlist.add(m_ob.buildObject(tf, info, true));
179 cananian 1.1.2.1         }
180 cananian 1.1.2.1         return Stm.toStm(stmlist);
181 cananian 1.1.2.1     }
182 cananian 1.2     }