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 * @see StackMapEntry 031 * @see StackMap 032 * @see Const 033 */ 034public final class StackMapType implements Cloneable { 035 036 private byte type; 037 private int index = -1; // Index to CONSTANT_Class or offset 038 private ConstantPool constant_pool; 039 040 041 /** 042 * Construct object from file stream. 043 * @param file Input stream 044 * @throws IOException 045 */ 046 StackMapType(final DataInput file, final ConstantPool constant_pool) throws IOException { 047 this(file.readByte(), -1, constant_pool); 048 if (hasIndex()) { 049 this.index = file.readShort(); 050 } 051 this.constant_pool = constant_pool; 052 } 053 054 055 /** 056 * @param type type tag as defined in the Constants interface 057 * @param index index to constant pool, or byte code offset 058 */ 059 public StackMapType(final byte type, final int index, final ConstantPool constant_pool) { 060 if ((type < Const.ITEM_Bogus) || (type > Const.ITEM_NewObject)) { 061 throw new RuntimeException("Illegal type for StackMapType: " + type); 062 } 063 this.type = type; 064 this.index = index; 065 this.constant_pool = constant_pool; 066 } 067 068 069 public void setType( final byte t ) { 070 if ((t < Const.ITEM_Bogus) || (t > Const.ITEM_NewObject)) { 071 throw new RuntimeException("Illegal type for StackMapType: " + t); 072 } 073 type = t; 074 } 075 076 077 public byte getType() { 078 return type; 079 } 080 081 082 public void setIndex( final int t ) { 083 index = t; 084 } 085 086 087 /** @return index to constant pool if type == ITEM_Object, or offset 088 * in byte code, if type == ITEM_NewObject, and -1 otherwise 089 */ 090 public int getIndex() { 091 return index; 092 } 093 094 095 /** 096 * Dump type entries to file. 097 * 098 * @param file Output file stream 099 * @throws IOException 100 */ 101 public void dump( final DataOutputStream file ) throws IOException { 102 file.writeByte(type); 103 if (hasIndex()) { 104 file.writeShort(getIndex()); 105 } 106 } 107 108 109 /** @return true, if type is either ITEM_Object or ITEM_NewObject 110 */ 111 public boolean hasIndex() { 112 return type == Const.ITEM_Object || type == Const.ITEM_NewObject; 113 } 114 115 116 private String printIndex() { 117 if (type == Const.ITEM_Object) { 118 if (index < 0) { 119 return ", class=<unknown>"; 120 } 121 return ", class=" + constant_pool.constantToString(index, Const.CONSTANT_Class); 122 } else if (type == Const.ITEM_NewObject) { 123 return ", offset=" + index; 124 } else { 125 return ""; 126 } 127 } 128 129 130 /** 131 * @return String representation 132 */ 133 @Override 134 public String toString() { 135 return "(type=" + Const.getItemName(type) + printIndex() + ")"; 136 } 137 138 139 /** 140 * @return deep copy of this object 141 */ 142 public StackMapType copy() { 143 try { 144 return (StackMapType) clone(); 145 } catch (final CloneNotSupportedException e) { 146 // TODO should this throw? 147 } 148 return null; 149 } 150 151 152 /** 153 * @return Constant pool used by this object. 154 */ 155 public ConstantPool getConstantPool() { 156 return constant_pool; 157 } 158 159 160 /** 161 * @param constant_pool Constant pool to be used for this object. 162 */ 163 public void setConstantPool( final ConstantPool constant_pool ) { 164 this.constant_pool = constant_pool; 165 } 166}