1 cananian 1.1.2.1  // ObjectRef.java, created Mon Dec 28 00:29:30 1998 by cananian
 2 cananian 1.1.2.8  // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
 3 cananian 1.1.2.8  // Licensed under the terms of the GNU GPL; see COPYING for details.
 4 cananian 1.1.2.1  package harpoon.Interpret.Quads;
 5 cananian 1.1.2.1  
 6 cananian 1.1.2.5  import harpoon.ClassFile.HClass;
 7 cananian 1.1.2.5  import harpoon.ClassFile.HField;
 8 cananian 1.1.2.5  import harpoon.ClassFile.HMethod;
 9 cananian 1.1.2.1  import harpoon.Util.Util;
10 cananian 1.1.2.1  
11 cananian 1.1.2.1  /**
12 cananian 1.1.2.1   * <code>ObjectRef</code> is an object reference in the interpreter.
13 cananian 1.1.2.1   * 
14 cananian 1.1.2.1   * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
15 cananian 1.4       * @version $Id: ObjectRef.java,v 1.4 2002/04/10 03:05:50 cananian Exp $
16 cananian 1.1.2.1   */
17 cananian 1.1.2.9  class ObjectRef extends Ref implements java.io.Serializable {
18 cananian 1.1.2.1      /** Fields in this instance of the object. */
19 cananian 1.1.2.1      FieldValueList fields;
20 cananian 1.1.2.2      /** Native method closure. */
21 cananian 1.1.2.9      Object closure; // must be serializable!
22 cananian 1.1.2.1  
23 cananian 1.1.2.1      /** create a new objectref with default field values.
24 cananian 1.1.2.1       * @exception InterpretedThrowable
25 cananian 1.1.2.1       *            if class initializer throws an exception.  */
26 cananian 1.1.2.1      ObjectRef(StaticState ss, HClass type) {
27 cananian 1.1.2.6          super(ss, type);
28 cananian 1.1.2.6          this.fields = null; this.closure = null;
29 cananian 1.1.2.6          // Initialize our fields.
30 cananian 1.1.2.1          for (HClass sc=type; sc!=null; sc=sc.getSuperclass()) {
31 cananian 1.1.2.1              HField[] fl = sc.getDeclaredFields();
32 cananian 1.1.2.1              for (int i=0; i<fl.length; i++)
33 cananian 1.1.2.1                  if (!fl[i].isStatic())
34 cananian 1.1.2.1                      update(fl[i], defaultValue(fl[i]));
35 cananian 1.1.2.1          }
36 cananian 1.1.2.1          // yay, done.
37 cananian 1.1.2.1      }
38 cananian 1.1.2.3      /** private constructor for use by the clone() method. */
39 cananian 1.1.2.3      private ObjectRef(StaticState ss, HClass type, FieldValueList fields) {
40 cananian 1.1.2.6          super(ss, type);
41 cananian 1.1.2.6          this.fields = fields; this.closure = null;
42 cananian 1.1.2.3          // no field initialization necessary.
43 cananian 1.1.2.3      }
44 cananian 1.1.2.3         
45 cananian 1.1.2.1      Object get(HField f) {
46 cananian 1.1.2.1          return FieldValueList.get(this.fields, f);
47 cananian 1.1.2.1      }
48 cananian 1.1.2.1      void update(HField f, Object value) {
49 cananian 1.1.2.1          this.fields = FieldValueList.update(this.fields, f, value);
50 cananian 1.1.2.1      }
51 cananian 1.1.2.2  
52 cananian 1.1.2.2      Object getClosure() { return closure; }
53 cananian 1.1.2.2      void putClosure(Object cl) { closure = cl; }
54 cananian 1.1.2.1  
55 cananian 1.1.2.3      public Object clone() {
56 cananian 1.3.2.1         assert closure==null : "can't clone objects with closure info.";
57 cananian 1.1.2.3         return new ObjectRef(ss, type, FieldValueList.clone(fields));
58 cananian 1.1.2.3      }
59 cananian 1.1.2.3     
60 cananian 1.1.2.10     /** for profiling. */
61 cananian 1.1.2.11     protected int size() { // approx. object size, in bytes. (not exact!)
62 cananian 1.1.2.10         HField[] hf = type.getFields();
63 cananian 1.1.2.10         int size = 8; // two header words
64 cananian 1.1.2.10         for (int i=0; i<hf.length; i++)
65 cananian 1.1.2.11             if (!hf[i].isStatic()) // skip static fields
66 cananian 1.1.2.11                 size += (hf[i].getType()==HClass.Long ||
67 cananian 1.1.2.11                          hf[i].getType()==HClass.Double) ? 8 : 4;
68 cananian 1.1.2.10         return size;
69 cananian 1.1.2.10     }
70 cananian 1.1.2.10 
71 cananian 1.1.2.7      /** For debugging (invokes the interpreted toString() method) */
72 cananian 1.1.2.7      public String toString() {
73 cananian 1.1.2.7          try {
74 cananian 1.1.2.7              HMethod hm = type.getMethod("toString", new HClass[0]);
75 cananian 1.1.2.7              ObjectRef istr =
76 cananian 1.1.2.7                  (ObjectRef) Method.invoke(ss, hm, new Object[] { this } );
77 cananian 1.1.2.7              return ss.ref2str(istr);
78 cananian 1.1.2.7          } catch (InterpretedThrowable e) {
79 cananian 1.1.2.7              return super.toString(); // nasty ObjectRef@...
80 cananian 1.1.2.7          }
81 cananian 1.1.2.7      }
82 cananian 1.1.2.7  
83 cananian 1.1.2.1      protected void finalize() throws Throwable {
84 cananian 1.1.2.1          // finalize the referenced object by evaluating its finalize method.
85 cananian 1.1.2.1          try {
86 cananian 1.1.2.1              HMethod hm = type.getMethod("finalize", new HClass[0]);
87 cananian 1.1.2.1              Method.invoke(ss, hm, new Object[] { this } );
88 cananian 1.1.2.1          } catch (InterpretedThrowable e) {
89 cananian 1.1.2.1              // ignore.
90 cananian 1.1.2.1          } catch (NoSuchMethodError e) {
91 cananian 1.1.2.1              // no finalize method.
92 cananian 1.1.2.1          }
93 cananian 1.1.2.6          // finalize the ref.
94 cananian 1.1.2.1          super.finalize();
95 cananian 1.1.2.1      }
96 cananian 1.2      }