1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.generic;
18
19 import java.io.DataOutputStream;
20 import java.io.IOException;
21 import org.apache.bcel.ExceptionConstants;
22 import org.apache.bcel.classfile.ConstantPool;
23 import org.apache.bcel.util.ByteSequence;
24
25 /***
26 * MULTIANEWARRAY - Create new mutidimensional array of references
27 * <PRE>Stack: ..., count1, [count2, ...] -> ..., arrayref</PRE>
28 *
29 * @version $Id: MULTIANEWARRAY.java 386056 2006-03-15 11:31:56Z tcurdt $
30 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
31 */
32 public class MULTIANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction,
33 ExceptionThrower {
34
35 private short dimensions;
36
37
38 /***
39 * Empty constructor needed for the Class.newInstance() statement in
40 * Instruction.readInstruction(). Not to be used otherwise.
41 */
42 MULTIANEWARRAY() {
43 }
44
45
46 public MULTIANEWARRAY(int index, short dimensions) {
47 super(org.apache.bcel.Constants.MULTIANEWARRAY, index);
48 if (dimensions < 1) {
49 throw new ClassGenException("Invalid dimensions value: " + dimensions);
50 }
51 this.dimensions = dimensions;
52 length = 4;
53 }
54
55
56 /***
57 * Dump instruction as byte code to stream out.
58 * @param out Output stream
59 */
60 public void dump( DataOutputStream out ) throws IOException {
61 out.writeByte(opcode);
62 out.writeShort(index);
63 out.writeByte(dimensions);
64 }
65
66
67 /***
68 * Read needed data (i.e., no. dimension) from file.
69 */
70 protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
71 super.initFromFile(bytes, wide);
72 dimensions = bytes.readByte();
73 length = 4;
74 }
75
76
77 /***
78 * @return number of dimensions to be created
79 */
80 public final short getDimensions() {
81 return dimensions;
82 }
83
84
85 /***
86 * @return mnemonic for instruction
87 */
88 public String toString( boolean verbose ) {
89 return super.toString(verbose) + " " + index + " " + dimensions;
90 }
91
92
93 /***
94 * @return mnemonic for instruction with symbolic references resolved
95 */
96 public String toString( ConstantPool cp ) {
97 return super.toString(cp) + " " + dimensions;
98 }
99
100
101 /***
102 * Also works for instructions whose stack effect depends on the
103 * constant pool entry they reference.
104 * @return Number of words consumed from stack by this instruction
105 */
106 public int consumeStack( ConstantPoolGen cpg ) {
107 return dimensions;
108 }
109
110
111 public Class[] getExceptions() {
112 Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length];
113 System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0,
114 ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length);
115 cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length + 1] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION;
116 cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR;
117 return cs;
118 }
119
120
121 public ObjectType getLoadClassType( ConstantPoolGen cpg ) {
122 Type t = getType(cpg);
123 if (t instanceof ArrayType) {
124 t = ((ArrayType) t).getBasicType();
125 }
126 return (t instanceof ObjectType) ? (ObjectType) t : null;
127 }
128
129
130 /***
131 * Call corresponding visitor method(s). The order is:
132 * Call visitor methods of implemented interfaces first, then
133 * call methods according to the class hierarchy in descending order,
134 * i.e., the most specific visitXXX() call comes last.
135 *
136 * @param v Visitor object
137 */
138 public void accept( Visitor v ) {
139 v.visitLoadClass(this);
140 v.visitAllocationInstruction(this);
141 v.visitExceptionThrower(this);
142 v.visitTypedInstruction(this);
143 v.visitCPInstruction(this);
144 v.visitMULTIANEWARRAY(this);
145 }
146 }