1 cananian 1.1.2.1 // ArrayRef.java, created Mon Dec 28 03:02:39 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 cananian 1.1.2.1 package harpoon.Interpret.Quads;
 5 cananian 1.1.2.1 
 6 cananian 1.1.2.3 import harpoon.ClassFile.HClass;
 7 cananian 1.1.2.4 import harpoon.ClassFile.HField;
 8 cananian 1.1.2.5 import harpoon.Util.HClassUtil;
 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.4  * <code>ArrayRef</code> is a representation of an array reference for use
13 cananian 1.1.2.4  * by the interpreter.
14 cananian 1.1.2.1  * 
15 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
16 cananian 1.4      * @version $Id: ArrayRef.java,v 1.4 2002/04/10 03:05:50 cananian Exp $
17 cananian 1.1.2.1  */
18 cananian 1.1.2.7 final class ArrayRef extends Ref implements java.io.Serializable {
19 cananian 1.1.2.4     /** Elements of the array (primitives or Refs) */
20 cananian 1.1.2.1     final Object[] elements;
21 cananian 1.1.2.4 
22 cananian 1.1.2.1     ArrayRef(StaticState ss, HClass type, int dims[]) 
23 cananian 1.1.2.1         throws InterpretedThrowable {
24 cananian 1.1.2.1         super(ss, type);
25 cananian 1.3.2.1         assert dims.length >= 1 && dims[0]>=0;
26 cananian 1.1.2.1         this.elements = new Object[dims[0]];
27 cananian 1.1.2.1         if (dims.length==1)
28 cananian 1.1.2.1             for (int i=0; i<this.elements.length; i++)
29 cananian 1.1.2.1                 this.elements[i] = defaultValue(type.getComponentType());
30 cananian 1.1.2.1         else {
31 cananian 1.1.2.1             int ndims[] = new int[dims.length-1];
32 cananian 1.1.2.1             System.arraycopy(dims, 1, ndims, 0, ndims.length);
33 cananian 1.1.2.1             for (int i=0; i<this.elements.length; i++)
34 cananian 1.1.2.1                 this.elements[i] =
35 cananian 1.1.2.1                     new ArrayRef(ss, type.getComponentType(), ndims);
36 cananian 1.1.2.1         }
37 cananian 1.1.2.2     }
38 cananian 1.1.2.2     // private constructor for use by clone() method
39 cananian 1.1.2.2     private ArrayRef(StaticState ss, HClass type, Object[] elements) {
40 cananian 1.1.2.2         super(ss, type);
41 cananian 1.1.2.2         this.elements = elements;
42 cananian 1.3.2.1         assert elements!=null;
43 cananian 1.1.2.2     }
44 cananian 1.1.2.2     public Object clone() { // arrays can always be cloned.
45 cananian 1.1.2.2        return new ArrayRef(ss, type, (Object[]) elements.clone());
46 cananian 1.1.2.1     }
47 cananian 1.1.2.4     /** Arrays have phantom 'length' field. (public final int) */
48 cananian 1.1.2.4     Object get(HField f) {
49 cananian 1.1.2.4         if (f.getName().equals("length")) return new Integer(length());
50 cananian 1.1.2.4         else throw new Error("Field not found: "+f);
51 cananian 1.1.2.4     }
52 cananian 1.1.2.4 
53 cananian 1.1.2.1     int length() { return this.elements.length; }
54 cananian 1.1.2.1     Object get(int i) { return this.elements[i]; }
55 cananian 1.1.2.1     void update(int i, Object value) { this.elements[i] = value; }
56 cananian 1.1.2.8 
57 cananian 1.1.2.8     /** for profiling. */
58 cananian 1.1.2.8     protected int size() { // approx. array size, in bytes.
59 cananian 1.1.2.8         HClass ct = type.getComponentType();
60 cananian 1.1.2.8         int elsize;
61 cananian 1.1.2.8         if (!ct.isPrimitive()) elsize = 4; // for 32-bit archs, at least.
62 cananian 1.1.2.8         else if (ct==HClass.Boolean || ct==HClass.Byte) elsize = 1;
63 cananian 1.1.2.8         else if (ct==HClass.Char || ct==HClass.Short) elsize = 2;
64 cananian 1.1.2.8         else if (ct==HClass.Int || ct==HClass.Float) elsize = 4;
65 cananian 1.1.2.8         else if (ct==HClass.Double || ct==HClass.Long) elsize = 8;
66 cananian 1.1.2.8         else throw new Error("ugh: what kind of primitive type is "+ct+"?");
67 cananian 1.1.2.8         return 8 + elsize*length();
68 cananian 1.1.2.8     }
69 cananian 1.1.2.5 
70 cananian 1.1.2.5     /** For debugging. */
71 cananian 1.1.2.5     public String toString() {
72 cananian 1.1.2.5         StringBuffer sb = new StringBuffer();
73 cananian 1.1.2.5         sb.append('<');
74 cananian 1.1.2.5         sb.append(HClassUtil.baseClass(type));
75 cananian 1.1.2.5         sb.append('['); sb.append(elements.length); sb.append(']');
76 cananian 1.1.2.5         for (int i=1; i<HClassUtil.dims(type); i++)
77 cananian 1.1.2.5             sb.append("[]");
78 cananian 1.1.2.5         sb.append('>');
79 cananian 1.1.2.5         return sb.toString();
80 cananian 1.1.2.5     }
81 cananian 1.2     }