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 */
018 package org.apache.bcel.classfile;
019
020 import java.io.DataInput;
021 import java.io.DataOutputStream;
022 import java.io.IOException;
023 import java.io.Serializable;
024
025 import org.apache.bcel.Constants;
026
027 /**
028 * This class represents the type of a local variable or item on stack
029 * used in the StackMap entries.
030 *
031 * @version $Id: StackMapType.java 1152072 2011-07-29 01:54:05Z dbrosius $
032 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
033 * @see StackMapEntry
034 * @see StackMap
035 * @see Constants
036 */
037 public final class StackMapType implements Cloneable, Serializable {
038
039 private static final long serialVersionUID = 1L;
040
041 private byte type;
042 private int index = -1; // Index to CONSTANT_Class or offset
043 private ConstantPool constant_pool;
044
045
046 /**
047 * Construct object from file stream.
048 * @param file Input stream
049 * @throws IOException
050 */
051 StackMapType(DataInput file, ConstantPool constant_pool) throws IOException {
052 this(file.readByte(), -1, constant_pool);
053 if (hasIndex()) {
054 setIndex(file.readShort());
055 }
056 setConstantPool(constant_pool);
057 }
058
059
060 /**
061 * @param type type tag as defined in the Constants interface
062 * @param index index to constant pool, or byte code offset
063 */
064 public StackMapType(byte type, int index, ConstantPool constant_pool) {
065 setType(type);
066 setIndex(index);
067 setConstantPool(constant_pool);
068 }
069
070
071 public void setType( byte t ) {
072 if ((t < Constants.ITEM_Bogus) || (t > Constants.ITEM_NewObject)) {
073 throw new RuntimeException("Illegal type for StackMapType: " + t);
074 }
075 type = t;
076 }
077
078
079 public byte getType() {
080 return type;
081 }
082
083
084 public void setIndex( int t ) {
085 index = t;
086 }
087
088
089 /** @return index to constant pool if type == ITEM_Object, or offset
090 * in byte code, if type == ITEM_NewObject, and -1 otherwise
091 */
092 public int getIndex() {
093 return index;
094 }
095
096
097 /**
098 * Dump type entries to file.
099 *
100 * @param file Output file stream
101 * @throws IOException
102 */
103 public final void dump( DataOutputStream file ) throws IOException {
104 file.writeByte(type);
105 if (hasIndex()) {
106 file.writeShort(getIndex());
107 }
108 }
109
110
111 /** @return true, if type is either ITEM_Object or ITEM_NewObject
112 */
113 public final boolean hasIndex() {
114 return ((type == Constants.ITEM_Object) || (type == Constants.ITEM_NewObject));
115 }
116
117
118 private String printIndex() {
119 if (type == Constants.ITEM_Object) {
120 if (index < 0) {
121 return ", class=<unknown>";
122 }
123 return ", class=" + constant_pool.constantToString(index, Constants.CONSTANT_Class);
124 } else if (type == Constants.ITEM_NewObject) {
125 return ", offset=" + index;
126 } else {
127 return "";
128 }
129 }
130
131
132 /**
133 * @return String representation
134 */
135 @Override
136 public final String toString() {
137 return "(type=" + Constants.ITEM_NAMES[type] + printIndex() + ")";
138 }
139
140
141 /**
142 * @return deep copy of this object
143 */
144 public StackMapType copy() {
145 try {
146 return (StackMapType) clone();
147 } catch (CloneNotSupportedException e) {
148 }
149 return null;
150 }
151
152
153 /**
154 * @return Constant pool used by this object.
155 */
156 public final ConstantPool getConstantPool() {
157 return constant_pool;
158 }
159
160
161 /**
162 * @param constant_pool Constant pool to be used for this object.
163 */
164 public final void setConstantPool( ConstantPool constant_pool ) {
165 this.constant_pool = constant_pool;
166 }
167 }