View Javadoc

1   // Arrays.java, created Mon Dec 23 23:01:25 2002 by mcmartin
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
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              // check for dim < 0 here, because if a dim is zero, later dim's
51              // are not checked by multinewarray_helper.
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  }