1 /*** 2 * ASM: a very small and fast Java bytecode manipulation framework 3 * Copyright (c) 2000-2007 INRIA, France Telecom 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 package org.mockito.asm; 31 32 /** 33 * A constant pool item. Constant pool items can be created with the 'newXXX' 34 * methods in the {@link ClassWriter} class. 35 * 36 * @author Eric Bruneton 37 */ 38 final class Item { 39 40 /** 41 * Index of this item in the constant pool. 42 */ 43 int index; 44 45 /** 46 * Type of this constant pool item. A single class is used to represent all 47 * constant pool item types, in order to minimize the bytecode size of this 48 * package. The value of this field is one of {@link ClassWriter#INT}, 49 * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT}, 50 * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8}, 51 * {@link ClassWriter#STR}, {@link ClassWriter#CLASS}, 52 * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD}, 53 * {@link ClassWriter#METH}, {@link ClassWriter#IMETH}. 54 * 55 * Special Item types are used for Items that are stored in the ClassWriter 56 * {@link ClassWriter#typeTable}, instead of the constant pool, in order to 57 * avoid clashes with normal constant pool items in the ClassWriter constant 58 * pool's hash table. These special item types are 59 * {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and 60 * {@link ClassWriter#TYPE_MERGED}. 61 */ 62 int type; 63 64 /** 65 * Value of this item, for an integer item. 66 */ 67 int intVal; 68 69 /** 70 * Value of this item, for a long item. 71 */ 72 long longVal; 73 74 /** 75 * First part of the value of this item, for items that do not hold a 76 * primitive value. 77 */ 78 String strVal1; 79 80 /** 81 * Second part of the value of this item, for items that do not hold a 82 * primitive value. 83 */ 84 String strVal2; 85 86 /** 87 * Third part of the value of this item, for items that do not hold a 88 * primitive value. 89 */ 90 String strVal3; 91 92 /** 93 * The hash code value of this constant pool item. 94 */ 95 int hashCode; 96 97 /** 98 * Link to another constant pool item, used for collision lists in the 99 * constant pool's hash table. 100 */ 101 Item next; 102 103 /** 104 * Constructs an uninitialized {@link Item}. 105 */ 106 Item() { 107 } 108 109 /** 110 * Constructs an uninitialized {@link Item} for constant pool element at 111 * given position. 112 * 113 * @param index index of the item to be constructed. 114 */ 115 Item(final int index) { 116 this.index = index; 117 } 118 119 /** 120 * Constructs a copy of the given item. 121 * 122 * @param index index of the item to be constructed. 123 * @param i the item that must be copied into the item to be constructed. 124 */ 125 Item(final int index, final Item i) { 126 this.index = index; 127 type = i.type; 128 intVal = i.intVal; 129 longVal = i.longVal; 130 strVal1 = i.strVal1; 131 strVal2 = i.strVal2; 132 strVal3 = i.strVal3; 133 hashCode = i.hashCode; 134 } 135 136 /** 137 * Sets this item to an integer item. 138 * 139 * @param intVal the value of this item. 140 */ 141 void set(final int intVal) { 142 this.type = ClassWriter.INT; 143 this.intVal = intVal; 144 this.hashCode = 0x7FFFFFFF & (type + intVal); 145 } 146 147 /** 148 * Sets this item to a long item. 149 * 150 * @param longVal the value of this item. 151 */ 152 void set(final long longVal) { 153 this.type = ClassWriter.LONG; 154 this.longVal = longVal; 155 this.hashCode = 0x7FFFFFFF & (type + (int) longVal); 156 } 157 158 /** 159 * Sets this item to a float item. 160 * 161 * @param floatVal the value of this item. 162 */ 163 void set(final float floatVal) { 164 this.type = ClassWriter.FLOAT; 165 this.intVal = Float.floatToRawIntBits(floatVal); 166 this.hashCode = 0x7FFFFFFF & (type + (int) floatVal); 167 } 168 169 /** 170 * Sets this item to a double item. 171 * 172 * @param doubleVal the value of this item. 173 */ 174 void set(final double doubleVal) { 175 this.type = ClassWriter.DOUBLE; 176 this.longVal = Double.doubleToRawLongBits(doubleVal); 177 this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal); 178 } 179 180 /** 181 * Sets this item to an item that do not hold a primitive value. 182 * 183 * @param type the type of this item. 184 * @param strVal1 first part of the value of this item. 185 * @param strVal2 second part of the value of this item. 186 * @param strVal3 third part of the value of this item. 187 */ 188 void set( 189 final int type, 190 final String strVal1, 191 final String strVal2, 192 final String strVal3) 193 { 194 this.type = type; 195 this.strVal1 = strVal1; 196 this.strVal2 = strVal2; 197 this.strVal3 = strVal3; 198 switch (type) { 199 case ClassWriter.UTF8: 200 case ClassWriter.STR: 201 case ClassWriter.CLASS: 202 case ClassWriter.TYPE_NORMAL: 203 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()); 204 return; 205 case ClassWriter.NAME_TYPE: 206 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() 207 * strVal2.hashCode()); 208 return; 209 // ClassWriter.FIELD: 210 // ClassWriter.METH: 211 // ClassWriter.IMETH: 212 default: 213 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() 214 * strVal2.hashCode() * strVal3.hashCode()); 215 } 216 } 217 218 /** 219 * Indicates if the given item is equal to this one. 220 * 221 * @param i the item to be compared to this one. 222 * @return <tt>true</tt> if the given item if equal to this one, 223 * <tt>false</tt> otherwise. 224 */ 225 boolean isEqualTo(final Item i) { 226 if (i.type == type) { 227 switch (type) { 228 case ClassWriter.INT: 229 case ClassWriter.FLOAT: 230 return i.intVal == intVal; 231 case ClassWriter.TYPE_MERGED: 232 case ClassWriter.LONG: 233 case ClassWriter.DOUBLE: 234 return i.longVal == longVal; 235 case ClassWriter.UTF8: 236 case ClassWriter.STR: 237 case ClassWriter.CLASS: 238 case ClassWriter.TYPE_NORMAL: 239 return i.strVal1.equals(strVal1); 240 case ClassWriter.TYPE_UNINIT: 241 return i.intVal == intVal && i.strVal1.equals(strVal1); 242 case ClassWriter.NAME_TYPE: 243 return i.strVal1.equals(strVal1) 244 && i.strVal2.equals(strVal2); 245 // ClassWriter.FIELD: 246 // ClassWriter.METH: 247 // ClassWriter.IMETH: 248 default: 249 return i.strVal1.equals(strVal1) 250 && i.strVal2.equals(strVal2) 251 && i.strVal3.equals(strVal3); 252 } 253 } 254 return false; 255 } 256 } 257