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   */
18  package org.apache.bcel.classfile;
19  
20  import java.io.DataInput;
21  import java.io.DataOutputStream;
22  import java.io.IOException;
23  
24  import org.apache.bcel.Const;
25  
26  /**
27   * This class represents the type of a local variable or item on stack
28   * used in the StackMap entries.
29   *
30   * @version $Id: StackMapType.html 1018313 2017-09-18 09:03:04Z britter $
31   * @see     StackMapEntry
32   * @see     StackMap
33   * @see     Const
34   */
35  public final class StackMapType implements Cloneable {
36  
37      private byte type;
38      private int index = -1; // Index to CONSTANT_Class or offset
39      private ConstantPool constant_pool;
40  
41  
42      /**
43       * Construct object from file stream.
44       * @param file Input stream
45       * @throws IOException
46       */
47      StackMapType(final DataInput file, final ConstantPool constant_pool) throws IOException {
48          this(file.readByte(), -1, constant_pool);
49          if (hasIndex()) {
50              this.index = file.readShort();
51          }
52          this.constant_pool = constant_pool;
53      }
54  
55  
56      /**
57       * @param type type tag as defined in the Constants interface
58       * @param index index to constant pool, or byte code offset
59       */
60      public StackMapType(final byte type, final int index, final ConstantPool constant_pool) {
61          if ((type < Const.ITEM_Bogus) || (type > Const.ITEM_NewObject)) {
62              throw new RuntimeException("Illegal type for StackMapType: " + type);
63          }
64          this.type = type;
65          this.index = index;
66          this.constant_pool = constant_pool;
67      }
68  
69  
70      public void setType( final byte t ) {
71          if ((t < Const.ITEM_Bogus) || (t > Const.ITEM_NewObject)) {
72              throw new RuntimeException("Illegal type for StackMapType: " + t);
73          }
74          type = t;
75      }
76  
77  
78      public byte getType() {
79          return type;
80      }
81  
82  
83      public void setIndex( final int t ) {
84          index = t;
85      }
86  
87  
88      /** @return index to constant pool if type == ITEM_Object, or offset
89       * in byte code, if type == ITEM_NewObject, and -1 otherwise
90       */
91      public int getIndex() {
92          return index;
93      }
94  
95  
96      /**
97       * Dump type entries to file.
98       *
99       * @param file Output file stream
100      * @throws IOException
101      */
102     public final void dump( final DataOutputStream file ) throws IOException {
103         file.writeByte(type);
104         if (hasIndex()) {
105             file.writeShort(getIndex());
106         }
107     }
108 
109 
110     /** @return true, if type is either ITEM_Object or ITEM_NewObject
111      */
112     public final boolean hasIndex() {
113         return type == Const.ITEM_Object || type == Const.ITEM_NewObject;
114     }
115 
116 
117     private String printIndex() {
118         if (type == Const.ITEM_Object) {
119             if (index < 0) {
120                 return ", class=<unknown>";
121             }
122             return ", class=" + constant_pool.constantToString(index, Const.CONSTANT_Class);
123         } else if (type == Const.ITEM_NewObject) {
124             return ", offset=" + index;
125         } else {
126             return "";
127         }
128     }
129 
130 
131     /**
132      * @return String representation
133      */
134     @Override
135     public final String toString() {
136         return "(type=" + Const.getItemName(type) + printIndex() + ")";
137     }
138 
139 
140     /**
141      * @return deep copy of this object
142      */
143     public StackMapType copy() {
144         try {
145             return (StackMapType) clone();
146         } catch (final CloneNotSupportedException e) {
147             // TODO should this throw?
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( final ConstantPool constant_pool ) {
165         this.constant_pool = constant_pool;
166     }
167 }