View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   https://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.bcel.generic;
20  
21  import java.io.DataOutputStream;
22  import java.io.IOException;
23  
24  import org.apache.bcel.ExceptionConst;
25  import org.apache.bcel.classfile.ConstantPool;
26  import org.apache.bcel.util.ByteSequence;
27  
28  /**
29   * MULTIANEWARRAY - Create new mutidimensional array of references
30   *
31   * <PRE>
32   * Stack: ..., count1, [count2, ...] -&gt; ..., arrayref
33   * </PRE>
34   */
35  public class MULTIANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, ExceptionThrower {
36  
37      private short dimensions;
38  
39      /**
40       * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise.
41       */
42      MULTIANEWARRAY() {
43      }
44  
45      public MULTIANEWARRAY(final int index, final short dimensions) {
46          super(org.apache.bcel.Const.MULTIANEWARRAY, index);
47          if (dimensions < 1) {
48              throw new ClassGenException("Invalid dimensions value: " + dimensions);
49          }
50          this.dimensions = dimensions;
51          super.setLength(4);
52      }
53  
54      /**
55       * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call
56       * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last.
57       *
58       * @param v Visitor object
59       */
60      @Override
61      public void accept(final Visitor v) {
62          v.visitLoadClass(this);
63          v.visitAllocationInstruction(this);
64          v.visitExceptionThrower(this);
65          v.visitTypedInstruction(this);
66          v.visitCPInstruction(this);
67          v.visitMULTIANEWARRAY(this);
68      }
69  
70      /**
71       * Also works for instructions whose stack effect depends on the constant pool entry they reference.
72       *
73       * @return Number of words consumed from stack by this instruction
74       */
75      @Override
76      public int consumeStack(final ConstantPoolGen cpg) {
77          return dimensions;
78      }
79  
80      /**
81       * Dump instruction as byte code to stream out.
82       *
83       * @param out Output stream
84       */
85      @Override
86      public void dump(final DataOutputStream out) throws IOException {
87          out.writeByte(super.getOpcode());
88          out.writeShort(super.getIndex());
89          out.writeByte(dimensions);
90      }
91  
92      /**
93       * @return number of dimensions to be created
94       */
95      public final short getDimensions() {
96          return dimensions;
97      }
98  
99      @Override
100     public Class<?>[] getExceptions() {
101         return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, ExceptionConst.ILLEGAL_ACCESS_ERROR,
102             ExceptionConst.NEGATIVE_ARRAY_SIZE_EXCEPTION);
103     }
104 
105     @Override
106     public ObjectType getLoadClassType(final ConstantPoolGen cpg) {
107         Type t = getType(cpg);
108         if (t instanceof ArrayType) {
109             t = ((ArrayType) t).getBasicType();
110         }
111         return t instanceof ObjectType ? (ObjectType) t : null;
112     }
113 
114     /**
115      * Reads needed data (i.e., no. dimension) from file.
116      */
117     @Override
118     protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException {
119         super.initFromFile(bytes, wide);
120         dimensions = bytes.readByte();
121         super.setLength(4);
122     }
123 
124     /**
125      * @return mnemonic for instruction
126      */
127     @Override
128     public String toString(final boolean verbose) {
129         return super.toString(verbose) + " " + super.getIndex() + " " + dimensions;
130     }
131 
132     /**
133      * @return mnemonic for instruction with symbolic references resolved
134      */
135     @Override
136     public String toString(final ConstantPool cp) {
137         return super.toString(cp) + " " + dimensions;
138     }
139 }