1 duncan   1.1.2.1  // StaticState.java, created Mon Dec 28 00:36:44 1998 by cananian
  2 cananian 1.1.2.6  // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.1.2.6  // 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 duncan   1.1.2.1  import harpoon.ClassFile.CachingCodeFactory;
  7 duncan   1.1.2.1  import harpoon.ClassFile.HClass;
  8 duncan   1.1.2.1  import harpoon.ClassFile.HCodeFactory;
  9 duncan   1.1.2.1  import harpoon.ClassFile.HField;
 10 duncan   1.1.2.1  import harpoon.ClassFile.HMethod;
 11 cananian 1.1.2.10 import harpoon.ClassFile.Linker;
 12 duncan   1.1.2.1  import harpoon.Temp.Label;
 13 duncan   1.1.2.1  import harpoon.Util.Tuple;
 14 duncan   1.1.2.9  import harpoon.Util.HClassUtil;
 15 duncan   1.1.2.1  import harpoon.Util.Util;
 16 duncan   1.1.2.1  
 17 duncan   1.1.2.1  import java.io.PrintWriter;
 18 duncan   1.1.2.1  import java.util.Hashtable;
 19 duncan   1.1.2.1  import java.util.Stack;
 20 duncan   1.1.2.1  
 21 duncan   1.1.2.1  /**
 22 duncan   1.1.2.1   * <code>StaticState</code> contains the (static) execution context.
 23 duncan   1.1.2.1   * 
 24 duncan   1.1.2.1   * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 25 cananian 1.4       * @version $Id: StaticState.java,v 1.4 2002/04/10 03:06:02 cananian Exp $
 26 duncan   1.1.2.1   */
 27 duncan   1.1.2.1  final class StaticState extends HCLibrary {
 28 duncan   1.1.2.4      
 29 duncan   1.1.2.1      /** mapping of classes to their static fields. */
 30 duncan   1.1.2.1      final private Hashtable classInfo = new Hashtable();// no unloading.
 31 duncan   1.1.2.1      final private Hashtable nonclassInfo = new Hashtable();   
 32 duncan   1.1.2.1  
 33 cananian 1.1.2.10     /** which linker to use. */
 34 cananian 1.1.2.10     Linker linker;
 35 duncan   1.1.2.1      /** which code representation to use. */
 36 duncan   1.1.2.1      HCodeFactory hcf;
 37 duncan   1.1.2.1      /** used to map fields & methods to labels */
 38 cananian 1.3.2.2      final InterpreterOffsetMap map; 
 39 duncan   1.1.2.1      
 40 duncan   1.1.2.3      // Class constructor 
 41 cananian 1.1.2.10     StaticState(Linker linker, HCodeFactory hcf, InterpreterOffsetMap map) { 
 42 cananian 1.1.2.10         this(linker, hcf, null, map);     //prof is null for no profiling.
 43 duncan   1.1.2.1      }
 44 duncan   1.1.2.1  
 45 cananian 1.1.2.10     StaticState(Linker linker, HCodeFactory hcf, PrintWriter prof,
 46 cananian 1.1.2.10                 InterpreterOffsetMap map) {
 47 cananian 1.1.2.10         super(linker); this.linker = linker;
 48 duncan   1.1.2.4          // Only translate trees in canonical form 
 49 duncan   1.1.2.1          this.hcf = hcf; this.prof = prof; this.map = map;
 50 duncan   1.1.2.1          Support.registerNative(this);
 51 duncan   1.1.2.1      }
 52 duncan   1.1.2.1  
 53 duncan   1.1.2.1      private static class ClassHeader {
 54 duncan   1.1.2.1          FieldValueList fvl=null;
 55 duncan   1.1.2.1      }
 56 duncan   1.1.2.1  
 57 duncan   1.1.2.1      private void put(HClass cls, FieldValueList fvl) {
 58 duncan   1.1.2.1          ((ClassHeader)classInfo.get(cls)).fvl = fvl;
 59 duncan   1.1.2.1      }
 60 duncan   1.1.2.1  
 61 duncan   1.1.2.3  
 62 duncan   1.1.2.3      /************************************************************
 63 duncan   1.1.2.3       *                                                          *
 64 duncan   1.1.2.3       *                     CLASS LOADING                        *
 65 duncan   1.1.2.3       *                                                          *
 66 duncan   1.1.2.3       ***********************************************************/
 67 duncan   1.1.2.3  
 68 duncan   1.1.2.1      boolean isLoaded(HClass cls) { return classInfo.get(cls)!=null; }
 69 duncan   1.1.2.3  
 70 duncan   1.1.2.1      void load(HClass cls) throws InterpretedThrowable {
 71 cananian 1.3.2.1          assert !isLoaded(cls);
 72 duncan   1.1.2.1          HClass sc = cls.getSuperclass();
 73 duncan   1.1.2.1          if (sc!=null && !isLoaded(sc)) load(sc); // load superclasses first.
 74 duncan   1.1.2.1          System.err.println("LOADING "+cls);
 75 duncan   1.1.2.3  
 76 duncan   1.1.2.3          // Map [HClass --> FieldValueList]
 77 duncan   1.1.2.3          //
 78 duncan   1.1.2.1          classInfo.put(cls, new ClassHeader());
 79 duncan   1.1.2.1          
 80 duncan   1.1.2.1          // Map [class pointer --> HClass]
 81 duncan   1.1.2.1          // 
 82 duncan   1.1.2.1          Label clsLabel = map.label(cls);
 83 duncan   1.1.2.1          map(clsLabel, cls);
 84 duncan   1.1.2.1          
 85 duncan   1.1.2.1          loadStaticFields(clsLabel, cls);
 86 duncan   1.1.2.1          loadNonStaticFields(clsLabel, cls);
 87 duncan   1.1.2.1          loadMethods(clsLabel, cls);
 88 duncan   1.1.2.4          if (!(cls.isInterface() || cls.isPrimitive())) 
 89 duncan   1.1.2.8              loadDisplay(clsLabel, cls, map.displaySize());
 90 duncan   1.1.2.4          else  
 91 duncan   1.1.2.4              loadDisplay(clsLabel, cls);
 92 duncan   1.1.2.4          
 93 duncan   1.1.2.4          if (!(cls.isPrimitive() || cls.isArray())) 
 94 duncan   1.1.2.4              loadInterfaces(clsLabel, cls);
 95 duncan   1.1.2.4          
 96 duncan   1.1.2.4          // execute <clinit>() 
 97 duncan   1.1.2.1          HMethod hm = cls.getClassInitializer();
 98 duncan   1.1.2.1          if (hm!=null) Method.invoke(this, hm, new Object[0]);
 99 cananian 1.3.2.1          assert isLoaded(cls);
100 duncan   1.1.2.1      }
101 duncan   1.1.2.1  
102 duncan   1.1.2.4      private void loadDisplay(Label clsLabel, HClass current, int size) { 
103 duncan   1.1.2.4          for (int i=0; i<size; i++) { 
104 duncan   1.1.2.4              map(new ClazPointer(clsLabel, this, i), ConstPointer.NULL_POINTER);
105 duncan   1.1.2.4          }
106 duncan   1.1.2.4          loadDisplay(clsLabel, current);
107 duncan   1.1.2.4      }
108 duncan   1.1.2.4  
109 duncan   1.1.2.1      private void loadDisplay(Label clsLabel, HClass current) {
110 duncan   1.1.2.4          HClass sc;
111 duncan   1.1.2.1  
112 duncan   1.1.2.9          sc = getSuperclass(current);
113 duncan   1.1.2.3          if (sc!=null) loadDisplay(clsLabel, sc);
114 duncan   1.1.2.1  
115 duncan   1.1.2.8          map(new ClazPointer(clsLabel, this, map.offset(current)),
116 duncan   1.1.2.3              new ConstPointer(map.label(current), this));
117 duncan   1.1.2.4  
118 duncan   1.1.2.9      }
119 duncan   1.1.2.9      
120 duncan   1.1.2.9      private HClass getSuperclass(HClass cls) { 
121 duncan   1.1.2.9          if (cls.isArray()) { 
122 cananian 1.1.2.10             HClass obj  = linker.forName("java.lang.Object");
123 duncan   1.1.2.9              int    dims = HClassUtil.dims(cls);
124 duncan   1.1.2.9              HClass base = HClassUtil.baseClass(cls);
125 duncan   1.1.2.9              if (base.isPrimitive()) 
126 duncan   1.1.2.9                  return obj;
127 duncan   1.1.2.9              else if (base.getDescriptor().equals(obj.getDescriptor()))
128 cananian 1.1.2.12                 return HClassUtil.arrayClass(linker, obj, dims-1);
129 duncan   1.1.2.9              else 
130 cananian 1.1.2.12                 return HClassUtil.arrayClass(linker, base.getSuperclass(), dims);
131 duncan   1.1.2.9          }
132 duncan   1.1.2.9          else { 
133 duncan   1.1.2.9              return cls.getSuperclass();
134 duncan   1.1.2.9          }
135 duncan   1.1.2.1      }
136 duncan   1.1.2.1  
137 duncan   1.1.2.1      private void loadInterfaces(Label clsLabel, HClass cls) {
138 duncan   1.1.2.1          // Make interface list
139 duncan   1.1.2.1          HClass[] interfaces = cls.getInterfaces();
140 duncan   1.1.2.5          InterfaceList iList = new InterfaceList(interfaces.length+1);
141 duncan   1.1.2.1          for (int i=0; i<interfaces.length; i++) {
142 duncan   1.1.2.1              iList.addInterface
143 duncan   1.1.2.1                  (new ConstPointer(map.label(interfaces[i]), this), i);
144 duncan   1.1.2.1              HMethod[] hm = interfaces[i].getDeclaredMethods();
145 duncan   1.1.2.5              for (int j=0; j<hm.length; j++) {
146 duncan   1.1.2.5                  map(new ClazPointer(clsLabel, this, map.offset(hm[j])), 
147 duncan   1.1.2.4                      hm[j]);
148 duncan   1.1.2.5              }
149 duncan   1.1.2.1          }
150 duncan   1.1.2.5  
151 duncan   1.1.2.5          // NULL-terminate the interface list
152 duncan   1.1.2.5          iList.addInterface(ConstPointer.NULL_POINTER, interfaces.length);
153 duncan   1.1.2.1          
154 duncan   1.1.2.5          //
155 duncan   1.1.2.1          map(new ClazPointer(clsLabel, this, map.interfaceListOffset(cls)),
156 duncan   1.1.2.1              new InterfaceListPointer(iList, 0));
157 duncan   1.1.2.1      }
158 duncan   1.1.2.5  
159 duncan   1.1.2.1   
160 duncan   1.1.2.1      private void loadMethods(Label clsLabel, HClass current) {
161 duncan   1.1.2.1          HClass sc = current.getSuperclass();
162 duncan   1.1.2.1  
163 duncan   1.1.2.1          if (sc!=null) loadMethods(clsLabel, sc);
164 duncan   1.1.2.1  
165 duncan   1.1.2.1          HMethod[] mt = current.getDeclaredMethods();
166 duncan   1.1.2.1          for (int i=0; i<mt.length; i++) {
167 duncan   1.1.2.1              // Attempt to map a label directly to the method
168 duncan   1.1.2.1              // (even for non-static methods)
169 duncan   1.1.2.1              map(map.label(mt[i]), mt[i]);
170 duncan   1.1.2.1              
171 duncan   1.1.2.1              if (!mt[i].isStatic()) {
172 duncan   1.1.2.1                  map(new ClazPointer(clsLabel, this, map.offset(mt[i])), 
173 duncan   1.1.2.1                      mt[i]);
174 duncan   1.1.2.1              }
175 duncan   1.1.2.1          }
176 duncan   1.1.2.1      }
177 duncan   1.1.2.1  
178 duncan   1.1.2.1      private void loadStaticFields(Label clsLabel, HClass current) {
179 duncan   1.1.2.1          HField[] fl = current.getDeclaredFields();
180 duncan   1.1.2.1          for (int i=0; i<fl.length; i++) {                   
181 duncan   1.1.2.1              if (fl[i].isStatic()) {
182 duncan   1.1.2.1                  map(map.label(fl[i]), fl[i]);
183 duncan   1.1.2.1                  update(fl[i], Ref.defaultValue(fl[i])); 
184 duncan   1.1.2.1              }
185 duncan   1.1.2.1          }
186 duncan   1.1.2.1      }
187 duncan   1.1.2.1  
188 duncan   1.1.2.1      private void loadNonStaticFields(Label clsLabel, HClass current) {
189 duncan   1.1.2.1          HClass sc = current.getSuperclass();
190 duncan   1.1.2.1  
191 duncan   1.1.2.1          if (sc!=null) loadNonStaticFields(clsLabel, sc);
192 duncan   1.1.2.1          
193 duncan   1.1.2.1          HField[] fl = current.getDeclaredFields();
194 duncan   1.1.2.1          for (int i=0; i<fl.length; i++) {
195 duncan   1.1.2.1              if (!fl[i].isStatic()) {
196 duncan   1.1.2.1                  map(current, map.offset(fl[i]), fl[i]);
197 duncan   1.1.2.1              }
198 duncan   1.1.2.1          }
199 duncan   1.1.2.1      }
200 duncan   1.1.2.1  
201 duncan   1.1.2.3      /************************************************************
202 duncan   1.1.2.3       *                                                          *
203 duncan   1.1.2.3       *             STATIC DATA ACCESS METHODS                   *
204 duncan   1.1.2.3       * (Methods to access an _interpreted_ class's static data) *
205 duncan   1.1.2.3       *                                                          *
206 duncan   1.1.2.3       ***********************************************************/
207 duncan   1.1.2.3  
208 duncan   1.1.2.1  
209 duncan   1.1.2.1      HField getField(ConstPointer ptr) {
210 duncan   1.1.2.1          return (HField)classInfo.get(ptr.getBase());
211 duncan   1.1.2.1      }
212 duncan   1.1.2.1          
213 duncan   1.1.2.1      /** Returns the non-static field pointed to by ptr */
214 duncan   1.1.2.1      HField getField(FieldPointer ptr) {
215 duncan   1.1.2.1          HField result = null;
216 duncan   1.1.2.1          HClass type = ((ObjectRef)ptr.getBase()).type; 
217 duncan   1.1.2.1          Long offset = new Long(ptr.getOffset());
218 duncan   1.1.2.1  
219 duncan   1.1.2.1          for (; type!=null; type = type.getSuperclass()) {
220 duncan   1.1.2.1              result = (HField)classInfo.get
221 duncan   1.1.2.1                  (new Tuple(new Object[] { type, offset }));
222 duncan   1.1.2.1              if (result != null) return result;
223 duncan   1.1.2.1          }
224 duncan   1.1.2.1  
225 duncan   1.1.2.1          throw new Error("Couldn't find field: " + ptr);
226 duncan   1.1.2.1      }
227 duncan   1.1.2.1  
228 duncan   1.1.2.1      /** Returns an <code>HClass</code> representing the type pointed
229 duncan   1.1.2.1       *  to by label */
230 duncan   1.1.2.1      HClass getHClass(Label label) { 
231 duncan   1.1.2.1          if (classInfo.containsKey(label)) {  // the class has been loaded
232 duncan   1.1.2.1              return (HClass)classInfo.get(label);
233 duncan   1.1.2.1          }
234 duncan   1.1.2.1          else { // the class has not been loaded.  
235 duncan   1.1.2.1              HClass hc = (HClass)map.decodeLabel(label); 
236 duncan   1.1.2.1              load(hc); 
237 cananian 1.3.2.1              assert classInfo.containsKey(label) : label.toString();
238 duncan   1.1.2.1              return (HClass)classInfo.get(label);
239 duncan   1.1.2.1          }
240 duncan   1.1.2.1      }
241 duncan   1.1.2.1  
242 duncan   1.1.2.1      /** Returns the data pointed to by ptr */
243 duncan   1.1.2.1      Object getValue(ClazPointer ptr) { 
244 cananian 1.3.2.1          assert classInfo.containsKey(ptr) : ptr.toString();
245 duncan   1.1.2.1          return classInfo.get(ptr); 
246 duncan   1.1.2.1      }
247 duncan   1.1.2.1      
248 duncan   1.1.2.1      /** Returns the HMethod with the specified label */
249 duncan   1.1.2.1      Object getValue(ConstPointer ptr) { 
250 duncan   1.1.2.4          // Do null-pointer check
251 duncan   1.1.2.4          if (ptr==ConstPointer.NULL_POINTER) { 
252 duncan   1.1.2.4              return new Integer(0);
253 duncan   1.1.2.4          }
254 duncan   1.1.2.4          else { 
255 duncan   1.1.2.4              if (!classInfo.containsKey(ptr.getBase())) {
256 duncan   1.1.2.4                  classInfo.put(ptr.getBase(), 
257 duncan   1.1.2.4                                map.decodeLabel((Label)ptr.getBase()));
258 duncan   1.1.2.4              }
259 duncan   1.1.2.4              
260 cananian 1.3.2.1              assert classInfo.containsKey(ptr.getBase());
261 duncan   1.1.2.4              if (classInfo.get(ptr.getBase()) instanceof HField) {
262 duncan   1.1.2.4                  return get((HField)classInfo.get(ptr.getBase())); 
263 duncan   1.1.2.4              }
264 duncan   1.1.2.4              else {
265 duncan   1.1.2.4                  return classInfo.get(ptr.getBase());
266 duncan   1.1.2.4              }
267 duncan   1.1.2.1          }
268 duncan   1.1.2.1      }
269 duncan   1.1.2.1  
270 duncan   1.1.2.1      /** Updates the static field which label points at */
271 duncan   1.1.2.1      void updateFieldValue(ConstPointer ptr, Object value) {
272 duncan   1.1.2.1          update((HField)classInfo.get(ptr.getBase()), value);
273 duncan   1.1.2.1      }
274 duncan   1.1.2.3  
275 duncan   1.1.2.3      /************************************************************
276 duncan   1.1.2.3       *                                                          *
277 duncan   1.1.2.3       *      UTILITY METHODS TO AID IN STATIC DATA ACCESS        *
278 duncan   1.1.2.3       *                                                          *
279 duncan   1.1.2.3       ***********************************************************/
280 duncan   1.1.2.3  
281 duncan   1.1.2.3      // Returns the value of the static field "sf"
282 duncan   1.1.2.3      // Throws an error if "sf" is not static
283 cananian 1.1.2.10     Object get(HField sf) {
284 cananian 1.3.2.1          assert sf.isStatic();
285 duncan   1.1.2.1          HClass cls = sf.getDeclaringClass();
286 duncan   1.1.2.1          if (!isLoaded(cls)) load(cls);
287 duncan   1.1.2.1          return FieldValueList.get(get(cls), sf);
288 duncan   1.1.2.1      }
289 duncan   1.1.2.1  
290 duncan   1.1.2.3      // Returns the FieldValueList associated with "cls"
291 duncan   1.1.2.1      private FieldValueList get(HClass cls) {
292 cananian 1.3.2.1          assert isLoaded(cls);
293 duncan   1.1.2.1          return ((ClassHeader)classInfo.get(cls)).fvl;
294 duncan   1.1.2.1      }
295 duncan   1.1.2.1  
296 duncan   1.1.2.3      // Updates the value of the static field "sf" to be "value".
297 duncan   1.1.2.3      // Throws an error if "sf" is not static
298 duncan   1.1.2.1      void update(HField sf, Object value) {
299 cananian 1.3.2.1          assert sf.isStatic();
300 duncan   1.1.2.1          HClass cls = sf.getDeclaringClass();
301 duncan   1.1.2.1          if (!isLoaded(cls)) load(cls);
302 duncan   1.1.2.1          put(cls, FieldValueList.update(get(cls), sf, value));
303 duncan   1.1.2.1      }
304 duncan   1.1.2.1  
305 duncan   1.1.2.3      /************************************************************
306 duncan   1.1.2.3       *                                                          *
307 duncan   1.1.2.3       *                      CALL STACK                          *
308 duncan   1.1.2.3       *                                                          *
309 duncan   1.1.2.3       ***********************************************************/
310 duncan   1.1.2.1  
311 duncan   1.1.2.1      final private Stack callStack = new Stack();
312 duncan   1.1.2.1  
313 duncan   1.1.2.1      private StackFrame stack(int i) {
314 duncan   1.1.2.1          return (StackFrame) callStack.elementAt(callStack.size()-i-1);
315 duncan   1.1.2.1      }
316 duncan   1.1.2.1  
317 duncan   1.1.2.1      void pushStack(StackFrame sf) { callStack.push(sf); }
318 duncan   1.1.2.1  
319 duncan   1.1.2.1      void popStack() { callStack.pop(); }
320 duncan   1.1.2.1  
321 duncan   1.1.2.1      void printStackTrace(PrintWriter pw) {
322 duncan   1.1.2.1          printStackTrace(pw, stackTrace());
323 duncan   1.1.2.1      }
324 duncan   1.1.2.1  
325 duncan   1.1.2.1      void printStackTrace(java.io.PrintStream ps) {
326 duncan   1.1.2.1          printStackTrace(new PrintWriter(ps, true));
327 duncan   1.1.2.1      }
328 duncan   1.1.2.1  
329 duncan   1.1.2.1      void printStackTrace() { printStackTrace(System.err); }
330 duncan   1.1.2.1          
331 duncan   1.1.2.1      String[] stackTrace() {
332 duncan   1.1.2.1          String[] st = new String[callStack.size()];
333 duncan   1.1.2.1          for (int i=0; i<st.length; i++)
334 duncan   1.1.2.1              st[i] =
335 duncan   1.1.2.1                  stack(i).getMethod().getDeclaringClass().getName() + "." +
336 duncan   1.1.2.1                  stack(i).getMethod().getName() +
337 duncan   1.1.2.1                  "("+stack(i).getSourceFile()+":"+stack(i).getLineNumber()+")";
338 duncan   1.1.2.1          return st;
339 duncan   1.1.2.1      }
340 duncan   1.1.2.1      static void printStackTrace(PrintWriter pw, String[] st) {
341 duncan   1.1.2.1          for (int i=0; i<st.length; i++)
342 duncan   1.1.2.1              pw.println("-   at " + st[i]);
343 duncan   1.1.2.1      }
344 duncan   1.1.2.3  
345 duncan   1.1.2.3      /************************************************************
346 duncan   1.1.2.3       *                                                          *
347 duncan   1.1.2.3       *                        STRINGS                           *
348 duncan   1.1.2.3       *                                                          *
349 duncan   1.1.2.3       ***********************************************************/
350 duncan   1.1.2.3  
351 duncan   1.1.2.1      final private Hashtable internTable = new Hashtable();
352 duncan   1.1.2.1  
353 duncan   1.1.2.1      final ObjectRef intern(ObjectRef src) {
354 duncan   1.1.2.1          String s = ref2str(src);
355 duncan   1.1.2.1          ObjectRef obj = (ObjectRef) internTable.get(s);
356 duncan   1.1.2.1          if (obj==null) { internTable.put(s, src); obj = src; }
357 duncan   1.1.2.1          return obj;
358 duncan   1.1.2.1      }
359 duncan   1.1.2.1  
360 duncan   1.1.2.1      final String ref2str(ObjectRef str) {
361 duncan   1.1.2.1          HField HFvalue = HCstring.getField("value");
362 duncan   1.1.2.1          HField HFoffset= HCstring.getField("offset");
363 duncan   1.1.2.1          HField HFcount = HCstring.getField("count");
364 duncan   1.1.2.3          
365 duncan   1.1.2.1          ArrayRef value = (ArrayRef)str.get(HFvalue);
366 duncan   1.1.2.1          int offset = ((Integer)str.get(HFoffset)).intValue();
367 duncan   1.1.2.1          int count = ((Integer)str.get(HFcount)).intValue();
368 duncan   1.1.2.1  
369 duncan   1.1.2.1          char[] ca = new char[count];
370 duncan   1.1.2.1          for (int i=0; i<ca.length; i++)
371 duncan   1.1.2.1              ca[i] = ((Character)value.get(i+offset)).charValue();
372 duncan   1.1.2.1          return new String(ca);
373 duncan   1.1.2.1      }
374 duncan   1.1.2.1  
375 duncan   1.1.2.1      final ObjectRef makeString(String s)
376 duncan   1.1.2.1          throws InterpretedThrowable {
377 duncan   1.1.2.1          
378 duncan   1.1.2.3          ObjectRef obj = new ObjectRef(this, HCstring);
379 duncan   1.1.2.3          ArrayRef ca=new ArrayRef(this, HCcharA, new int[]{s.length()});
380 duncan   1.1.2.3          for (int i=0; i<s.length(); i++)
381 duncan   1.1.2.3              ca.update(i, new Character(s.charAt(i)));
382 duncan   1.1.2.3          HMethod hm = HCstring.getConstructor(new HClass[] { HCcharA });
383 duncan   1.1.2.3          Method.invoke(this, hm, new Object[] { obj, ca });
384 duncan   1.1.2.1  
385 duncan   1.1.2.3          return obj;
386 duncan   1.1.2.1      }
387 duncan   1.1.2.1  
388 duncan   1.1.2.1      final ObjectRef makeStringIntern(String s) 
389 duncan   1.1.2.1          throws InterpretedThrowable {
390 duncan   1.1.2.1          ObjectRef obj = (ObjectRef) internTable.get(s);
391 duncan   1.1.2.1          if (obj!=null) return obj;
392 duncan   1.1.2.1          obj = makeString(s);
393 duncan   1.1.2.1          internTable.put(s, obj);
394 duncan   1.1.2.1          return obj;
395 duncan   1.1.2.1      }
396 duncan   1.1.2.1  
397 duncan   1.1.2.1      final ObjectRef makeThrowable(HClass HCex) 
398 duncan   1.1.2.1          throws InterpretedThrowable {
399 duncan   1.1.2.1          ObjectRef obj = new ObjectRef(this, HCex);
400 duncan   1.1.2.1          Method.invoke(this, HCex.getConstructor(new HClass[0]),
401 duncan   1.1.2.1                        new Object[] { obj } );
402 duncan   1.1.2.1          return obj;
403 duncan   1.1.2.1      }
404 duncan   1.1.2.1  
405 duncan   1.1.2.1      final ObjectRef makeThrowable(HClass HCex, String msg)
406 duncan   1.1.2.1          throws InterpretedThrowable {
407 duncan   1.1.2.1          ObjectRef obj = new ObjectRef(this, HCex);
408 duncan   1.1.2.1          Method.invoke(this, HCex.getConstructor(new HClass[] { HCstring }),
409 duncan   1.1.2.1                        new Object[] { obj, makeString(msg) } );
410 duncan   1.1.2.1          return obj;
411 duncan   1.1.2.1      }
412 duncan   1.1.2.3  
413 duncan   1.1.2.3      /************************************************************
414 duncan   1.1.2.3       *                                                          *
415 duncan   1.1.2.3       *                    NATIVE METHODS                        *
416 duncan   1.1.2.3       *                                                          *
417 duncan   1.1.2.3       ***********************************************************/
418 duncan   1.1.2.3  
419 duncan   1.1.2.1      private final Hashtable nativeRegistry = new Hashtable();
420 duncan   1.1.2.1      private final Hashtable nativeClosure = new Hashtable();
421 duncan   1.1.2.1      final void register(NativeMethod nm) {
422 duncan   1.1.2.1          nativeRegistry.put(nm.getMethod(), nm);
423 duncan   1.1.2.1      }
424 duncan   1.1.2.1      final NativeMethod findNative(HMethod hm) {
425 duncan   1.1.2.1          if (hm.getDeclaringClass().isArray() && hm.getName().equals("clone"))
426 duncan   1.1.2.1              hm = HCobject.getMethod("clone", new HClass[0]);
427 duncan   1.1.2.1          return (NativeMethod) nativeRegistry.get(hm);
428 duncan   1.1.2.1      }
429 duncan   1.1.2.1  
430 duncan   1.1.2.1      final Object getNativeClosure(HClass hc) {
431 duncan   1.1.2.1          return nativeClosure.get(hc);
432 duncan   1.1.2.1      }
433 duncan   1.1.2.1  
434 duncan   1.1.2.1      final void putNativeClosure(HClass hc, Object cl) {
435 duncan   1.1.2.1          nativeClosure.put(hc, cl);
436 duncan   1.1.2.1      }
437 duncan   1.1.2.3  
438 duncan   1.1.2.3      /************************************************************
439 duncan   1.1.2.3       *                                                          *
440 duncan   1.1.2.3       *                   PROFILING SUPPORT                      *
441 duncan   1.1.2.3       *                                                          *
442 duncan   1.1.2.3       ***********************************************************/
443 duncan   1.1.2.3  
444 cananian 1.3.2.2      public final PrintWriter prof;
445 duncan   1.1.2.1      private long count; // instruction count.
446 duncan   1.1.2.1      final synchronized void incrementInstructionCount() { 
447 duncan   1.1.2.1          count++; 
448 duncan   1.1.2.1      }
449 duncan   1.1.2.1      final synchronized long getInstructionCount() { 
450 duncan   1.1.2.1          return count; 
451 duncan   1.1.2.1      }
452 duncan   1.1.2.1      // profile time spent in a method.
453 duncan   1.1.2.1      final synchronized void profile(HMethod method, long start, long end) {
454 duncan   1.1.2.1          if (prof==null) return;
455 duncan   1.1.2.1          else prof.println("M "+
456 duncan   1.1.2.1                            method.getDeclaringClass().getName()+" "+
457 duncan   1.1.2.1                            method.getName()+" "+method.getDescriptor()+" "+
458 duncan   1.1.2.1                            start+" "+end);
459 duncan   1.1.2.1      }
460 duncan   1.1.2.1      // profile lifetime of an object instance
461 duncan   1.1.2.1      final synchronized void profile(HClass cls, long start, long end) {
462 duncan   1.1.2.1          if (prof==null) return;
463 duncan   1.1.2.1          else prof.println("N "+cls.getDescriptor()+" "+start+" "+end);
464 duncan   1.1.2.1      }
465 duncan   1.1.2.1  
466 duncan   1.1.2.1      private void map(HClass hclass, long offset, HField field) {
467 duncan   1.1.2.1          classInfo.put
468 duncan   1.1.2.1              (new Tuple(new Object[] { hclass, new Long(offset) }), field);
469 duncan   1.1.2.1      }
470 duncan   1.1.2.1      
471 duncan   1.1.2.1      private void map(Label label, HClass hclass) {
472 duncan   1.1.2.1          classInfo.put(label, hclass);
473 duncan   1.1.2.1      }
474 duncan   1.1.2.1  
475 duncan   1.1.2.1      private void map(Label label, HField field) {
476 duncan   1.1.2.1          classInfo.put(label, field);
477 duncan   1.1.2.1      }
478 duncan   1.1.2.1  
479 duncan   1.1.2.1      private void map(Label label, HMethod method) {
480 duncan   1.1.2.1          classInfo.put(label, method);
481 duncan   1.1.2.1      }
482 duncan   1.1.2.1      
483 duncan   1.1.2.1      private void map(ClazPointer ptr, Object object) {
484 duncan   1.1.2.1          classInfo.put(ptr, object);
485 duncan   1.1.2.1      }
486 duncan   1.1.2.3      
487 duncan   1.1.2.3      
488 duncan   1.1.2.1  }
489 duncan   1.1.2.1  
490 duncan   1.1.2.1  
491 cananian 1.2