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.classfile; 019 020import java.io.DataInput; 021import java.io.DataOutputStream; 022import java.io.IOException; 023 024import org.apache.bcel.Const; 025 026/** 027 * This class represents the type of a local variable or item on stack 028 * used in the StackMap entries. 029 * 030 * @version $Id: StackMapType.java 1749603 2016-06-21 20:50:19Z ggregory $ 031 * @see StackMapEntry 032 * @see StackMap 033 * @see Const 034 */ 035public final class StackMapType implements Cloneable { 036 037 private byte type; 038 private int index = -1; // Index to CONSTANT_Class or offset 039 private ConstantPool constant_pool; 040 041 042 /** 043 * Construct object from file stream. 044 * @param file Input stream 045 * @throws IOException 046 */ 047 StackMapType(final DataInput file, final ConstantPool constant_pool) throws IOException { 048 this(file.readByte(), -1, constant_pool); 049 if (hasIndex()) { 050 this.index = file.readShort(); 051 } 052 this.constant_pool = constant_pool; 053 } 054 055 056 /** 057 * @param type type tag as defined in the Constants interface 058 * @param index index to constant pool, or byte code offset 059 */ 060 public StackMapType(final byte type, final int index, final ConstantPool constant_pool) { 061 if ((type < Const.ITEM_Bogus) || (type > Const.ITEM_NewObject)) { 062 throw new RuntimeException("Illegal type for StackMapType: " + type); 063 } 064 this.type = type; 065 this.index = index; 066 this.constant_pool = constant_pool; 067 } 068 069 070 public void setType( final byte t ) { 071 if ((t < Const.ITEM_Bogus) || (t > Const.ITEM_NewObject)) { 072 throw new RuntimeException("Illegal type for StackMapType: " + t); 073 } 074 type = t; 075 } 076 077 078 public byte getType() { 079 return type; 080 } 081 082 083 public void setIndex( final int t ) { 084 index = t; 085 } 086 087 088 /** @return index to constant pool if type == ITEM_Object, or offset 089 * in byte code, if type == ITEM_NewObject, and -1 otherwise 090 */ 091 public int getIndex() { 092 return index; 093 } 094 095 096 /** 097 * Dump type entries to file. 098 * 099 * @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}