1 cananian 1.1.2.5 // ObjectRef.java, created Sat Mar 27 17:05:09 1999 by duncan
  2 cananian 1.1.2.4 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.1.2.4 // 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.HClass;
  7 duncan   1.1.2.1 import harpoon.ClassFile.HField;
  8 duncan   1.1.2.1 import harpoon.ClassFile.HMethod;
  9 duncan   1.1.2.1 import harpoon.IR.Tree.NAME;
 10 duncan   1.1.2.1 import harpoon.Util.Util;
 11 duncan   1.1.2.1 
 12 duncan   1.1.2.1 /**
 13 duncan   1.1.2.1  * <code>ObjectRef</code> is an object reference in the interpreter.
 14 duncan   1.1.2.1  * 
 15 duncan   1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 16 cananian 1.4      * @version $Id: ObjectRef.java,v 1.4 2002/04/10 03:06:00 cananian Exp $
 17 duncan   1.1.2.1  */
 18 duncan   1.1.2.1 class ObjectRef extends Ref {
 19 duncan   1.1.2.1 
 20 duncan   1.1.2.1     private Integer      hashCode;
 21 duncan   1.1.2.1     private ClazPointer  classPtr;
 22 duncan   1.1.2.1   
 23 duncan   1.1.2.1     /** Fields in this instance of the object. */
 24 duncan   1.1.2.1     FieldValueList fields;
 25 duncan   1.1.2.1     /** Native method closure. */
 26 duncan   1.1.2.1     Object closure;
 27 duncan   1.1.2.1 
 28 duncan   1.1.2.1     /** create a new objectref with default field values.
 29 duncan   1.1.2.1      * @exception InterpretedThrowable
 30 duncan   1.1.2.1      *            if class initializer throws an exception.  */
 31 duncan   1.1.2.1     ObjectRef(StaticState ss, HClass type) {
 32 duncan   1.1.2.1         this(ss, type, null, null);
 33 duncan   1.1.2.1     }
 34 duncan   1.1.2.1   
 35 duncan   1.1.2.1     /** create a new objectref with default field values.
 36 duncan   1.1.2.1      * @exception InterpretedThrowable
 37 duncan   1.1.2.1      *            if class initializer throws an exception.  */
 38 duncan   1.1.2.1     ObjectRef(StaticState ss, HClass type, 
 39 duncan   1.1.2.1               Integer hashCode, ClazPointer classPtr) {
 40 duncan   1.1.2.1         super(ss, type);
 41 duncan   1.1.2.1         this.fields = null; 
 42 duncan   1.1.2.1         this.closure = null;
 43 duncan   1.1.2.1         this.hashCode = hashCode==null?new Integer(this.hashCode()):hashCode;  
 44 duncan   1.1.2.1         this.classPtr = classPtr==null?
 45 duncan   1.1.2.2             new ClazPointer(ss.map.label(type), ss, 0):
 46 duncan   1.1.2.2             classPtr;
 47 duncan   1.1.2.1 
 48 duncan   1.1.2.1         // Initialize our fields.
 49 duncan   1.1.2.1         for (HClass sc=type; sc!=null; sc=sc.getSuperclass()) {
 50 duncan   1.1.2.1             HField[] fl = sc.getDeclaredFields();
 51 duncan   1.1.2.1             for (int i=0; i<fl.length; i++) {
 52 duncan   1.1.2.1                 if (!fl[i].isStatic()) { update(fl[i], defaultValue(fl[i])); }
 53 duncan   1.1.2.1             }
 54 duncan   1.1.2.1         }
 55 duncan   1.1.2.1         // yay, done.
 56 duncan   1.1.2.1     }
 57 duncan   1.1.2.1 
 58 duncan   1.1.2.1     // private constructor for use by the clone() method. 
 59 duncan   1.1.2.1     private ObjectRef(StaticState ss, HClass type, FieldValueList fields) {
 60 duncan   1.1.2.1         super(ss, type);
 61 duncan   1.1.2.1         this.fields = fields; this.closure = null;
 62 duncan   1.1.2.1         // no field initialization necessary.
 63 duncan   1.1.2.1     }
 64 duncan   1.1.2.1 
 65 duncan   1.1.2.1     /** Clones this <code>ObjectRef</code> */
 66 duncan   1.1.2.1     public Object clone() {
 67 cananian 1.3.2.1         assert closure==null : "can't clone objects with closure info.";
 68 duncan   1.1.2.2         return new ObjectRef(ss, type, FieldValueList.clone(fields));
 69 duncan   1.1.2.1     }
 70 duncan   1.1.2.1    
 71 duncan   1.1.2.1     /** Calls the <code>finalize()</code> method of the specified 
 72 duncan   1.1.2.1      *  <code>ObjectRef</code> */
 73 duncan   1.1.2.1     protected void finalize() throws Throwable {
 74 duncan   1.1.2.1         // finalize the referenced object by evaluating its finalize method.
 75 duncan   1.1.2.1         try {
 76 duncan   1.1.2.1             HMethod hm = type.getMethod("finalize", new HClass[0]);
 77 duncan   1.1.2.1             Method.invoke(ss, hm, new Object[] { this } );
 78 duncan   1.1.2.1         } catch (InterpretedThrowable e) {
 79 duncan   1.1.2.1             // ignore.
 80 duncan   1.1.2.1         } catch (NoSuchMethodError e) {
 81 duncan   1.1.2.1             // no finalize method.
 82 duncan   1.1.2.1         }
 83 duncan   1.1.2.1         // finalize the ref.
 84 duncan   1.1.2.1         super.finalize();
 85 duncan   1.1.2.1     }
 86 duncan   1.1.2.1 
 87 duncan   1.1.2.1     /** Returns the value of the specified field of this <code>ObjectRef</code>
 88 duncan   1.1.2.1      */
 89 duncan   1.1.2.1     Object get(HField f) {
 90 andyb    1.1.2.3         //if (DEBUG) db("Accessing field: " + f + " in " + this);
 91 duncan   1.1.2.1         return FieldValueList.get(this.fields, f);
 92 duncan   1.1.2.1     }
 93 duncan   1.1.2.1  
 94 duncan   1.1.2.1     /** Returns the native method closure of this <code>ObjectRef</code> */
 95 duncan   1.1.2.1     Object getClosure() { return closure; }
 96 duncan   1.1.2.1 
 97 duncan   1.1.2.1     /** Sets the native method closure of this <code>ObjectRef</code> */
 98 duncan   1.1.2.1     void putClosure(Object cl) { closure = cl; }
 99 duncan   1.1.2.1 
100 duncan   1.1.2.1     /** Updates the specified field of this <code>ObjectRef</code> to have
101 duncan   1.1.2.1      *  the specified value */
102 duncan   1.1.2.1     void update(HField f, Object value) {
103 andyb    1.1.2.3         //if (DEBUG) db("Updating field " + f + " in " + this + " to " + value);
104 duncan   1.1.2.1         this.fields = FieldValueList.update(this.fields, f, value);
105 duncan   1.1.2.1     }
106 duncan   1.1.2.1 
107 duncan   1.1.2.1     /** Dereferences the specified <code>FieldPointer</code> and returns
108 duncan   1.1.2.1      *  the value which it points to */
109 duncan   1.1.2.1     static Object get(FieldPointer ptr) {
110 duncan   1.1.2.1         ObjectRef ref = (ObjectRef)ptr.getBase();
111 duncan   1.1.2.1         long offset = ptr.getOffset();
112 duncan   1.1.2.1 
113 duncan   1.1.2.1         // case 1: points to hashcode.  return field as normal. 
114 duncan   1.1.2.1         if (ref.ss.map.hashCodeOffset(ref.type)==offset) {
115 cananian 1.3.2.1             assert ref.hashCode!=null;
116 duncan   1.1.2.1             return ref.hashCode;
117 duncan   1.1.2.1         }
118 duncan   1.1.2.1         // case 2: points to classptr.  Return ClazPointer<label, 0>
119 duncan   1.1.2.6         else if (ref.ss.map.clazzPtrOffset(ref.type)==offset) {
120 cananian 1.3.2.1             assert ref.classPtr != null;
121 duncan   1.1.2.1             return ref.classPtr;
122 duncan   1.1.2.1         }
123 duncan   1.1.2.1         // case 3: points to finalization info.  Can this happen?
124 duncan   1.1.2.1         // case 4: points to normal info.  
125 duncan   1.1.2.1         else {
126 duncan   1.1.2.1             return ref.get(ref.ss.getField(ptr));
127 duncan   1.1.2.1         }
128 duncan   1.1.2.1     }
129 duncan   1.1.2.1 
130 duncan   1.1.2.1     /** Updates the location pointed to by <code>ptr</code> to have
131 duncan   1.1.2.1      *  the specified value. */
132 duncan   1.1.2.1     static void update(FieldPointer ptr, Object value) {
133 duncan   1.1.2.1         ObjectRef ref = (ObjectRef)ptr.getBase();
134 duncan   1.1.2.1         long offset = ptr.getOffset();
135 duncan   1.1.2.1 
136 duncan   1.1.2.1         if (ref.ss.map.hashCodeOffset(ref.type)==offset) {
137 duncan   1.1.2.1             throw new Error("Hashcode field is final!");
138 duncan   1.1.2.1         }
139 duncan   1.1.2.6         else if (ref.ss.map.clazzPtrOffset(ref.type)==offset) {
140 duncan   1.1.2.1             throw new Error("The ClazPointer of an object is final!");
141 duncan   1.1.2.1         }
142 duncan   1.1.2.1         else {
143 duncan   1.1.2.1             ref.update(ref.ss.getField(ptr), value);
144 duncan   1.1.2.1         }       
145 duncan   1.1.2.1     }
146 duncan   1.1.2.2 
147 duncan   1.1.2.2     /** Returns a human-readable representation of this <code>ObjectRef</code>
148 duncan   1.1.2.2      */
149 duncan   1.1.2.2     /*    
150 duncan   1.1.2.2           public String toString() {
151 duncan   1.1.2.2           String fString;
152 duncan   1.1.2.2           if (fields==null) fString=null;
153 duncan   1.1.2.2           else fString = fields.toString();
154 duncan   1.1.2.2         
155 duncan   1.1.2.2           return "ObjectRef < " + type + ", " + fString;
156 duncan   1.1.2.2           
157 duncan   1.1.2.2           }
158 duncan   1.1.2.2     */
159 duncan   1.1.2.1 }
160 duncan   1.1.2.1 
161 duncan   1.1.2.1 
162 duncan   1.1.2.1 
163 cananian 1.2