View Javadoc

1   /*
2    * @(#) MULTIANEWARRAY.java Jan 8, 2004
3    * 
4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
5    * the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
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 				// last level; now we make 'basicClass' instances
119 				// these can be either simple types or objects
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 }