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 }