1
2
3
4
5
6
7
8
9
10 package nl.tudelft.simulation.dsol.interpreter.operations;
11
12 import java.io.DataInput;
13 import java.io.IOException;
14 import java.lang.reflect.Array;
15
16 import nl.tudelft.simulation.dsol.interpreter.InterpreterException;
17 import nl.tudelft.simulation.dsol.interpreter.LocalVariable;
18 import nl.tudelft.simulation.dsol.interpreter.OperandStack;
19 import nl.tudelft.simulation.dsol.interpreter.classfile.Constant;
20 import nl.tudelft.simulation.dsol.interpreter.classfile.ConstantClass;
21 import nl.tudelft.simulation.language.primitives.Primitive;
22 import nl.tudelft.simulation.language.reflection.FieldSignature;
23
24 /***
25 * The MULTINEWARRAY operation as defined in <a
26 * href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc9.html">
27 * http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc9.html
28 * </a>.
29 * <p>
30 * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
31 * University of Technology </a>, the Netherlands. <br>
32 * See for project information <a
33 * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
34 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
35 * License (GPL) </a>, no warranty <br>
36 *
37 * @author <a href="http://www.tbm.tudelft.nl/webstaf/peterja/index.htm">Peter
38 * Jacobs </a><a
39 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
40 * Verbraeck </a>
41 * @version 1.3 Apr 6, 2004
42 * @since 1.4
43 */
44 public class MULTIANEWARRAY extends VoidOperation
45 {
46 /*** OP refers to the operand code */
47 public static final int OP = 197;
48
49 /*** the index to load */
50 private int index = -1;
51
52 /*** the dimensions of the new array */
53 private int dimensions = -1;
54
55 /***
56 * constructs a new MULTIANEWARRAY
57 *
58 * @param dataInput the dataInput
59 * @throws IOException on IOfailure
60 */
61 public MULTIANEWARRAY(final DataInput dataInput) throws IOException
62 {
63 super();
64 this.index = dataInput.readUnsignedShort();
65 this.dimensions = dataInput.readUnsignedByte();
66 }
67
68 /***
69 * @see nl.tudelft.simulation.dsol.interpreter.operations.VoidOperation#execute(
70 * nl.tudelft.simulation.dsol.interpreter.OperandStack,
71 * nl.tudelft.simulation.dsol.interpreter.classfile.Constant[],
72 * nl.tudelft.simulation.dsol.interpreter.LocalVariable[])
73 */
74 public void execute(final OperandStack stack,
75 final Constant[] constantPool, final LocalVariable[] localVariables)
76 {
77 ConstantClass constant = (ConstantClass) constantPool[this.index];
78 Class clazz = null;
79 try
80 {
81 clazz = constant.getValue().getClassValue();
82 } catch (Exception exception)
83 {
84 throw new InterpreterException(exception);
85 }
86 int[] dimensions = new int[this.dimensions];
87 for (int i = dimensions.length - 1; i >= 0; i--)
88 {
89 dimensions[i] = Primitive.toInteger(stack.pop()).intValue();
90 }
91 try
92 {
93 Class componentType = FieldSignature.toClass(clazz.getName()
94 .replaceAll("//[", ""));
95 Object result = newArray(0, dimensions, componentType);
96 stack.push(result);
97 } catch (ClassNotFoundException exception)
98 {
99 throw new InterpreterException(exception);
100 }
101 }
102
103 /***
104 * creates a new Array
105 *
106 * @param depth the depth
107 * @param dimensions the dimensions
108 * @param clazz the clazz
109 * @return Object the array
110 */
111 private Object newArray(final int depth, final int[] dimensions,
112 final Class clazz)
113 {
114 try
115 {
116 if (depth == dimensions.length)
117 {
118
119
120 if (clazz.isPrimitive())
121 {
122 throw new InterpreterException("may not occur");
123 }
124 return clazz.newInstance();
125 }
126 if (depth == dimensions.length - 1)
127 {
128 if (clazz.isPrimitive())
129 {
130 return Array.newInstance(clazz, dimensions[depth]);
131 }
132 }
133 Object arrayref = Array
134 .newInstance(Object.class, dimensions[depth]);
135 for (int i = 0; i < dimensions[depth]; i++)
136 {
137 Array.set(arrayref, i, newArray(depth + 1, dimensions, clazz));
138 }
139 return arrayref;
140 } catch (Exception exception)
141 {
142 throw new InterpreterException(exception);
143 }
144 }
145
146 /***
147 * @see nl.tudelft.simulation.dsol.interpreter.Operation#getByteLength()
148 */
149 public int getByteLength()
150 {
151 return OPCODE_BYTE_LENGTH + 3;
152 }
153
154 /***
155 * @see nl.tudelft.simulation.dsol.interpreter.Operation#getOpcode()
156 */
157 public int getOpcode()
158 {
159 return MULTIANEWARRAY.OP;
160 }
161 }