1 cananian 1.1.2.6  // InterpreterOffsetMap.java, created Sat Mar 27 17:05:09 1999 by duncan
  2 cananian 1.1.2.5  // Copyright (C) 1998 Duncan Bryce <duncan@lcs.mit.edu>
  3 cananian 1.1.2.5  // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 duncan   1.1.2.1  package harpoon.Interpret.Tree;
  5 duncan   1.1.2.1  
  6 cananian 1.1.2.12 import harpoon.Analysis.ClassHierarchy;
  7 cananian 1.1.2.13 import harpoon.Backend.Analysis.InterfaceMethodMap;
  8 duncan   1.1.2.1  import harpoon.Backend.Maps.ClassDepthMap;
  9 duncan   1.1.2.1  import harpoon.Backend.Maps.MethodMap;
 10 duncan   1.1.2.8  import harpoon.Backend.Maps.DefaultNameMap;
 11 duncan   1.1.2.8  import harpoon.Backend.Maps.NameMap;
 12 duncan   1.1.2.1  import harpoon.ClassFile.HClass;
 13 duncan   1.1.2.1  import harpoon.ClassFile.HField;
 14 duncan   1.1.2.1  import harpoon.ClassFile.HMethod;
 15 duncan   1.1.2.1  import harpoon.Temp.Label;
 16 duncan   1.1.2.1  import harpoon.Util.Util;
 17 duncan   1.1.2.1  
 18 duncan   1.1.2.8  import java.util.Iterator;
 19 duncan   1.1.2.8  import java.util.HashMap;
 20 duncan   1.1.2.8  import java.util.Map;
 21 pnkfelix 1.1.2.9  import java.util.Set;
 22 duncan   1.1.2.1  import java.util.StringTokenizer;
 23 duncan   1.1.2.1  
 24 duncan   1.1.2.1  /**
 25 duncan   1.1.2.1   * A simple OffsetMap, used by the Tree Interpreter
 26 duncan   1.1.2.1   *
 27 duncan   1.1.2.1   * @author  Duncan Bryce <duncan@lcs.mit.edu>
 28 cananian 1.5       * @version $Id: InterpreterOffsetMap.java,v 1.5 2004/02/08 01:58:09 cananian Exp $
 29 duncan   1.1.2.1   */
 30 duncan   1.1.2.1  public class InterpreterOffsetMap extends OffsetMap {
 31 duncan   1.1.2.1  
 32 duncan   1.1.2.1      private ClassDepthMap       m_cdm;
 33 duncan   1.1.2.1      private FieldMap            m_fm;
 34 duncan   1.1.2.8      private Map                 m_field   = new HashMap();
 35 duncan   1.1.2.8      private Map                 m_labels  = new HashMap(); 
 36 duncan   1.1.2.8      private Map                 m_strings = new HashMap();
 37 duncan   1.1.2.1      private HClassInfo          m_hci;
 38 duncan   1.1.2.1      private InterfaceMethodMap  m_imm; 
 39 duncan   1.1.2.1      private MethodMap           m_cmm;
 40 duncan   1.1.2.8      private NameMap             m_nm;
 41 duncan   1.1.2.1  
 42 duncan   1.1.2.1      public InterpreterOffsetMap(ClassHierarchy ch) {
 43 cananian 1.1.2.16         this(ch, new DefaultNameMap(false));
 44 duncan   1.1.2.8      }
 45 duncan   1.1.2.8  
 46 duncan   1.1.2.8      /** Class constructor */
 47 duncan   1.1.2.8      public InterpreterOffsetMap(ClassHierarchy ch, NameMap nm) {
 48 duncan   1.1.2.1          m_hci = new HClassInfo();
 49 duncan   1.1.2.8          m_hci = new HClassInfo();
 50 duncan   1.1.2.8          int max = 0, depth;
 51 duncan   1.1.2.8          for (Iterator it=ch.classes().iterator();it.hasNext();){
 52 duncan   1.1.2.8              depth = m_hci.depth((HClass) it.next());
 53 duncan   1.1.2.8              max   = (depth>max) ? depth : max;
 54 duncan   1.1.2.8          }
 55 duncan   1.1.2.8          final int maxDepth = max;
 56 duncan   1.1.2.8  
 57 duncan   1.1.2.1          m_cmm = new MethodMap() {
 58 duncan   1.1.2.1              public int methodOrder(HMethod hm) { 
 59 duncan   1.1.2.1                  return m_hci.getMethodOffset(hm); }
 60 duncan   1.1.2.1          };
 61 duncan   1.1.2.1          m_cdm = new ClassDepthMap() {
 62 duncan   1.1.2.1              public int classDepth(HClass hc) { return m_hci.depth(hc); }
 63 duncan   1.1.2.8              public int maxDepth() { return maxDepth; } 
 64 duncan   1.1.2.1          };
 65 duncan   1.1.2.1          m_fm  = new FieldMap() {
 66 duncan   1.1.2.1              public int fieldOrder(HField hf) { 
 67 duncan   1.1.2.1                  return m_hci.getFieldOffset(hf); }
 68 duncan   1.1.2.1          };
 69 duncan   1.1.2.8          m_imm = new InterfaceMethodMap
 70 cananian 1.5                  (new net.cscott.jutil.IteratorEnumerator(ch.classes().iterator()));
 71 duncan   1.1.2.8          m_nm  = nm;
 72 duncan   1.1.2.1      }
 73 duncan   1.1.2.1  
 74 duncan   1.1.2.1      /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 75 duncan   1.1.2.1       *                                                           *
 76 duncan   1.1.2.1       *            Implementation of label mappings               *
 77 duncan   1.1.2.1       *                                                           *
 78 duncan   1.1.2.1       *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
 79 duncan   1.1.2.1  
 80 duncan   1.1.2.1      public Object decodeLabel(Label label) {
 81 cananian 1.1.2.14         if (Debug.DEBUG) Debug.db("DECODING: " + label);
 82 duncan   1.1.2.8          for (Iterator i = m_labels.keySet().iterator(); i.hasNext();) {
 83 duncan   1.1.2.8              Object next = i.next();
 84 duncan   1.1.2.1              Label lNext = (Label)m_labels.get(next);
 85 duncan   1.1.2.8              if (lNext.toString().equals(label.toString())) { 
 86 cananian 1.1.2.14                 if (Debug.DEBUG) Debug.db("Returning: " + next);
 87 duncan   1.1.2.1                  return next;
 88 duncan   1.1.2.8              }
 89 duncan   1.1.2.8          }
 90 duncan   1.1.2.8          for (Iterator i = m_strings.keySet().iterator(); i.hasNext();) { 
 91 duncan   1.1.2.8              Object next = i.next();
 92 duncan   1.1.2.8              Label lNext = (Label)m_strings.get(next);
 93 duncan   1.1.2.8              if (lNext.toString().equals(label.toString())) { 
 94 cananian 1.1.2.14                 if (Debug.DEBUG) Debug.db("Returning: " + next);
 95 duncan   1.1.2.8                  return next;
 96 duncan   1.1.2.8              }
 97 duncan   1.1.2.1          }
 98 duncan   1.1.2.8              
 99 duncan   1.1.2.1          throw new Error("Label not found in map: " + label);
100 duncan   1.1.2.1      }
101 duncan   1.1.2.11     
102 duncan   1.1.2.11     public Label jlClass(HClass hc) { return null; } 
103 duncan   1.1.2.1  
104 duncan   1.1.2.1      /** Returns the label corresponding to the specified HClass */
105 duncan   1.1.2.1      public Label label(HClass hc) { 
106 duncan   1.1.2.8          if (!m_labels.containsKey(hc)) {
107 duncan   1.1.2.8              m_labels.put(hc, new Label(m_nm.mangle(hc)));
108 duncan   1.1.2.8  }
109 duncan   1.1.2.8          return (Label)m_labels.get(hc);
110 duncan   1.1.2.1      }
111 duncan   1.1.2.1              
112 duncan   1.1.2.1      /** Returns the label corresponding to the specified static field */
113 duncan   1.1.2.1      public Label label(HField hf) { 
114 cananian 1.3.2.1          assert hf.isStatic();
115 duncan   1.1.2.8          if (!m_labels.containsKey(hf)) {
116 duncan   1.1.2.8              m_labels.put(hf, new Label(m_nm.mangle(hf)));
117 duncan   1.1.2.1          }
118 duncan   1.1.2.8          return (Label)m_labels.get(hf);
119 duncan   1.1.2.1      }
120 duncan   1.1.2.1  
121 duncan   1.1.2.1      /** Returns the label corrensponding to the specified method.  This
122 duncan   1.1.2.1       *  method is not necessarily static */
123 duncan   1.1.2.1      public Label label(HMethod hm) { 
124 duncan   1.1.2.8          if (!m_labels.containsKey(hm)) {
125 duncan   1.1.2.8              m_labels.put(hm, new Label(m_nm.mangle(hm))); 
126 duncan   1.1.2.1          }
127 duncan   1.1.2.8          return (Label)m_labels.get(hm);
128 duncan   1.1.2.1      }
129 duncan   1.1.2.1  
130 duncan   1.1.2.1      /** Returns the label corresponding to the specified String constant */
131 duncan   1.1.2.1      public Label label(String stringConstant) { 
132 duncan   1.1.2.8          if (!m_strings.containsKey(stringConstant)) {
133 duncan   1.1.2.8              m_strings.put(stringConstant, 
134 duncan   1.1.2.8                            new Label(m_nm.mangle(stringConstant)));
135 duncan   1.1.2.1          }
136 duncan   1.1.2.8          return (Label)m_strings.get(stringConstant);
137 duncan   1.1.2.8      }
138 duncan   1.1.2.8  
139 pnkfelix 1.1.2.9      public Set stringConstants() { 
140 pnkfelix 1.1.2.9          return m_strings.keySet();
141 duncan   1.1.2.8      }
142 duncan   1.1.2.8  
143 duncan   1.1.2.8      public Map stringConstantMap() { 
144 duncan   1.1.2.8          return m_strings;
145 duncan   1.1.2.1      }
146 duncan   1.1.2.1  
147 duncan   1.1.2.1      /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
148 duncan   1.1.2.1       *                                                           *
149 duncan   1.1.2.1       *            Implementation of offset methods               *
150 duncan   1.1.2.1       *                                                           *
151 duncan   1.1.2.1       *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
152 duncan   1.1.2.1  
153 duncan   1.1.2.1  
154 duncan   1.1.2.1      /** Returns the offset of the class pointer */
155 duncan   1.1.2.8      public int clazzPtrOffset(HClass hc)   { 
156 cananian 1.3.2.1          assert !hc.isPrimitive() : "" + hc;
157 duncan   1.1.2.1          return -1;
158 duncan   1.1.2.1      }
159 duncan   1.1.2.1  
160 duncan   1.1.2.1      /** If hc is an array type, returns the offset of its component
161 duncan   1.1.2.1       *  type's class pointer */
162 duncan   1.1.2.1      public int componentTypeOffset(HClass hc) { 
163 cananian 1.3.2.1          assert hc.isArray();
164 duncan   1.1.2.1          return -1;
165 duncan   1.1.2.1      }
166 duncan   1.1.2.1  
167 duncan   1.1.2.1      /** Returns the size of the display information of the specified class */
168 duncan   1.1.2.8      public int displaySize() {
169 duncan   1.1.2.8          return m_cdm.maxDepth();
170 duncan   1.1.2.1      }
171 duncan   1.1.2.1  
172 duncan   1.1.2.1      /** Returns the offset of the first array element if hc is an array
173 duncan   1.1.2.1       *  type, otherwise generates an assertion failure */
174 duncan   1.1.2.1      public int elementsOffset(HClass hc) { 
175 cananian 1.3.2.1          assert hc.isArray();
176 duncan   1.1.2.1          return 0; 
177 duncan   1.1.2.1      }
178 duncan   1.1.2.1  
179 duncan   1.1.2.1      /** Returns the offset of the first field in an object of the
180 duncan   1.1.2.1       *  specified type */
181 duncan   1.1.2.1      public int fieldsOffset(HClass hc) { 
182 cananian 1.3.2.1          assert (!hc.isPrimitive()) && (!hc.isArray());
183 duncan   1.1.2.1          return 0;
184 duncan   1.1.2.1      }
185 duncan   1.1.2.1  
186 duncan   1.1.2.1      /** Returns the offset of the hashcode of the specified object */
187 duncan   1.1.2.1      public int hashCodeOffset(HClass hc) { 
188 cananian 1.3.2.1          assert !hc.isPrimitive();
189 duncan   1.1.2.1          return -2; 
190 duncan   1.1.2.1      }
191 duncan   1.1.2.1  
192 duncan   1.1.2.1      /** If hc is a class type, or an interface, returns the offset from
193 duncan   1.1.2.1       *  the class pointer of the pointer to implemented interfaces */
194 duncan   1.1.2.1      public int interfaceListOffset(HClass hc) { 
195 cananian 1.3.2.1          assert !hc.isPrimitive() && !hc.isArray();
196 duncan   1.1.2.8          return -4;
197 duncan   1.1.2.1      }
198 duncan   1.1.2.1  
199 duncan   1.1.2.1      /** If hc is an array type, returns the offset of its length field */
200 duncan   1.1.2.1      public int lengthOffset(HClass hc) { 
201 cananian 1.3.2.1          assert hc.isArray();
202 duncan   1.1.2.1          return -3; 
203 duncan   1.1.2.1      }
204 duncan   1.1.2.1  
205 duncan   1.1.2.8      /** Returns the offset from the class pointer of this class's pointer
206 duncan   1.1.2.8       *  in the display */
207 duncan   1.1.2.8      public int offset(HClass hc) { 
208 cananian 1.3.2.1          assert !hc.isPrimitive() && !hc.isInterface();
209 duncan   1.1.2.8          return m_cdm.classDepth(hc);
210 duncan   1.1.2.8      }
211 duncan   1.1.2.8  
212 duncan   1.1.2.1      /** Returns the offset from the object reference of the specified 
213 duncan   1.1.2.1       *  non-static field */
214 duncan   1.1.2.1      public int offset(HField hf) { 
215 cananian 1.3.2.1          assert !hf.isStatic();
216 duncan   1.1.2.1          return m_fm.fieldOrder(hf);
217 duncan   1.1.2.1      }
218 duncan   1.1.2.1  
219 duncan   1.1.2.1      /** Returns the offset from the class pointer of the specified
220 duncan   1.1.2.1       *  non-static method */
221 duncan   1.1.2.1      public int offset(HMethod hm) { 
222 cananian 1.3.2.1          assert !hm.isStatic();
223 duncan   1.1.2.1          HClass hc = hm.getDeclaringClass(); 
224 duncan   1.1.2.1      
225 duncan   1.1.2.4          if (hc.isInterface()) return -m_imm.methodOrder(hm) +
226 duncan   1.1.2.4                                    interfaceListOffset(hc) - 1;
227 duncan   1.1.2.8          else return m_cmm.methodOrder(hm) + displaySize();
228 duncan   1.1.2.1      }
229 duncan   1.1.2.1  
230 duncan   1.1.2.1      /** Returns the size of the specified class */
231 duncan   1.1.2.1      public int size(HClass hc) { 
232 duncan   1.1.2.1          int size;
233 duncan   1.1.2.1          return 1;
234 duncan   1.1.2.1      }
235 duncan   1.1.2.1  
236 duncan   1.1.2.1      /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
237 duncan   1.1.2.1       *                                                           *
238 duncan   1.1.2.1       *                    Utility methods                        *
239 duncan   1.1.2.1       *                                                           *
240 duncan   1.1.2.1       *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
241 duncan   1.1.2.1  
242 duncan   1.1.2.1  
243 duncan   1.1.2.1    private String getFieldSignature(HField hf)
244 duncan   1.1.2.1      {
245 duncan   1.1.2.1        String token = null;
246 duncan   1.1.2.1        for (StringTokenizer st = new StringTokenizer(hf.toString());
247 duncan   1.1.2.1             st.hasMoreTokens();)
248 duncan   1.1.2.1          {
249 duncan   1.1.2.1            token = st.nextToken();
250 duncan   1.1.2.1          }
251 duncan   1.1.2.1        return hf.getDeclaringClass() + "_" + token;
252 duncan   1.1.2.1      }
253 duncan   1.1.2.10 
254 duncan   1.1.2.10     public int wordsize() { return 1; } 
255 cananian 1.1.2.13 
256 cananian 1.1.2.13     // stub for old FieldMap interface
257 cananian 1.1.2.13     abstract class FieldMap {
258 cananian 1.1.2.13         public abstract int fieldOrder(HField hf);
259 cananian 1.1.2.13     }
260 duncan   1.1.2.1  }
261 duncan   1.1.2.1  
262 duncan   1.1.2.1  
263 cananian 1.2