1
2
3
4 package joeq.Runtime;
5
6 import joeq.Class.PrimordialClassLoader;
7 import joeq.Class.jq_Array;
8 import joeq.Class.jq_Class;
9 import joeq.Class.jq_ClassFileConstants;
10 import joeq.Class.jq_StaticMethod;
11 import joeq.Class.jq_Type;
12 import joeq.Memory.CodeAddress;
13 import joeq.Memory.HeapAddress;
14 import joeq.Memory.StackAddress;
15 import jwutil.util.Assert;
16
17 /***
18 * Arrays
19 *
20 * @author John Whaley <jwhaley@alum.mit.edu>
21 * @version $Id: Arrays.java 1931 2004-09-22 22:17:47Z joewhaley $
22 */
23 public class Arrays implements jq_ClassFileConstants {
24 /***
25 * Allocate a multidimensional array with dim dimensions and array type f.
26 * dim dimensions are read from the stack frame. (NOTE: this method does NOT
27 * reset the stack pointer for the dimensions arguments! The caller must handle it!)
28 * If f is not an array type, throws VerifyError.
29 *
30 * @return allocated array object
31 * @param dim number of dimensions to allocate. f must be an array type of at least this dimensionality.
32 * @param f type of array
33 * @throws VerifyError if t is not a array type of dimensionality at least dim
34 * @throws OutOfMemoryError if there is not enough memory to perform operation
35 * @throws NegativeArraySizeException if a dimension is negative
36 */
37 public static Object multinewarray(char dim, jq_Type f
38 throws OutOfMemoryError, NegativeArraySizeException, VerifyError {
39 if (!f.isArrayType())
40 throw new VerifyError();
41 jq_Array a = (jq_Array)f;
42 a.cls_initialize();
43 if (a.getDimensionality() < dim)
44 throw new VerifyError();
45 int[] n_elem = new int[dim];
46 int offset = StackAddress.size() + CodeAddress.size() + HeapAddress.size() + HeapAddress.size();
47 StackAddress p = (StackAddress) StackAddress.getBasePointer().offset(offset);
48 for (int i=dim-1; i>=0; --i) {
49 n_elem[i] = p.peek4();
50
51
52 if (n_elem[i] < 0)
53 throw new NegativeArraySizeException("dim "+i+": "+n_elem[i]+" < 0");
54 p = (StackAddress) p.offset(HeapAddress.size());
55 }
56 return multinewarray_helper(n_elem, 0, a);
57 }
58
59 /***
60 * Allocates a multidimensional array of type a, with dimensions given in
61 * dims[ind] to dims[dims.length-1]. a must be of dimensionality at least
62 * dims.length-ind.
63 *
64 * @return allocated array object
65 * @param dims array of dimensions
66 * @param ind start index in array dims
67 * @param a array type
68 * @throws NegativeArraySizeException if one of the array sizes in dims is negative
69 * @throws OutOfMemoryError if there is not enough memory to perform operation
70 */
71 public static Object multinewarray_helper(int[] dims, int ind, jq_Array a)
72 throws OutOfMemoryError, NegativeArraySizeException {
73 a.chkState(STATE_CLSINITIALIZED);
74 int length = dims[ind];
75 Object o = a.newInstance(length);
76 Assert._assert(length >= 0);
77 if (ind == dims.length-1)
78 return o;
79 Object[] o2 = (Object[])o;
80 jq_Array a2 = (jq_Array)a.getElementType();
81 a2.cls_initialize();
82 for (int i=0; i<length; ++i) {
83 o2[i] = multinewarray_helper(dims, ind+1, a2);
84 }
85 return o2;
86 }
87
88 public static final jq_StaticMethod _multinewarray;
89
90 static {
91 jq_Class k = (jq_Class)PrimordialClassLoader.loader.getOrCreateBSType("Ljoeq/Runtime/Arrays;");
92 _multinewarray = k.getOrCreateStaticMethod("multinewarray", "(CLjoeq/Class/jq_Type;)Ljava/lang/Object;");
93 }
94 }