001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 */ 018package org.apache.bcel.generic; 019 020import java.io.DataOutputStream; 021import java.io.IOException; 022 023import org.apache.bcel.ExceptionConst; 024import org.apache.bcel.classfile.ConstantPool; 025import org.apache.bcel.util.ByteSequence; 026 027/** 028 * MULTIANEWARRAY - Create new mutidimensional array of references 029 * <PRE>Stack: ..., count1, [count2, ...] -> ..., arrayref</PRE> 030 * 031 * @version $Id: MULTIANEWARRAY.java 1812166 2017-10-13 23:48:11Z ggregory $ 032 */ 033public class MULTIANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, 034 ExceptionThrower { 035 036 private short dimensions; 037 038 039 /** 040 * Empty constructor needed for Instruction.readInstruction. 041 * Not to be used otherwise. 042 */ 043 MULTIANEWARRAY() { 044 } 045 046 047 public MULTIANEWARRAY(final int index, final short dimensions) { 048 super(org.apache.bcel.Const.MULTIANEWARRAY, index); 049 if (dimensions < 1) { 050 throw new ClassGenException("Invalid dimensions value: " + dimensions); 051 } 052 this.dimensions = dimensions; 053 super.setLength(4); 054 } 055 056 057 /** 058 * Dump instruction as byte code to stream out. 059 * @param out Output stream 060 */ 061 @Override 062 public void dump( final DataOutputStream out ) throws IOException { 063 out.writeByte(super.getOpcode()); 064 out.writeShort(super.getIndex()); 065 out.writeByte(dimensions); 066 } 067 068 069 /** 070 * Read needed data (i.e., no. dimension) from file. 071 */ 072 @Override 073 protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { 074 super.initFromFile(bytes, wide); 075 dimensions = bytes.readByte(); 076 super.setLength(4); 077 } 078 079 080 /** 081 * @return number of dimensions to be created 082 */ 083 public final short getDimensions() { 084 return dimensions; 085 } 086 087 088 /** 089 * @return mnemonic for instruction 090 */ 091 @Override 092 public String toString( final boolean verbose ) { 093 return super.toString(verbose) + " " + super.getIndex() + " " + dimensions; 094 } 095 096 097 /** 098 * @return mnemonic for instruction with symbolic references resolved 099 */ 100 @Override 101 public String toString( final ConstantPool cp ) { 102 return super.toString(cp) + " " + dimensions; 103 } 104 105 106 /** 107 * Also works for instructions whose stack effect depends on the 108 * constant pool entry they reference. 109 * @return Number of words consumed from stack by this instruction 110 */ 111 @Override 112 public int consumeStack( final ConstantPoolGen cpg ) { 113 return dimensions; 114 } 115 116 117 @Override 118 public Class<?>[] getExceptions() { 119 return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 120 ExceptionConst.ILLEGAL_ACCESS_ERROR, 121 ExceptionConst.NEGATIVE_ARRAY_SIZE_EXCEPTION); 122 } 123 124 125 @Override 126 public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { 127 Type t = getType(cpg); 128 if (t instanceof ArrayType) { 129 t = ((ArrayType) t).getBasicType(); 130 } 131 return (t instanceof ObjectType) ? (ObjectType) t : null; 132 } 133 134 135 /** 136 * Call corresponding visitor method(s). The order is: 137 * Call visitor methods of implemented interfaces first, then 138 * call methods according to the class hierarchy in descending order, 139 * i.e., the most specific visitXXX() call comes last. 140 * 141 * @param v Visitor object 142 */ 143 @Override 144 public void accept( final Visitor v ) { 145 v.visitLoadClass(this); 146 v.visitAllocationInstruction(this); 147 v.visitExceptionThrower(this); 148 v.visitTypedInstruction(this); 149 v.visitCPInstruction(this); 150 v.visitMULTIANEWARRAY(this); 151 } 152}