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