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