View Javadoc

    1   /*
    2    * Copyright  2000-2004 The Apache Software Foundation
    3    *
    4    *  Licensed under the Apache License, Version 2.0 (the "License");
    5    *  you may not use this file except in compliance with the License.
    6    *  You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   *  Unless required by applicable law or agreed to in writing, software
    11   *  distributed under the License is distributed on an "AS IS" BASIS,
    12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   *  See the License for the specific language governing permissions and
    14   *  limitations under the License.
    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, ...] -&gt; ..., 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 }