1 2 /* 3 4 The author of this software is Ian Kaplan 5 Bear Products International 6 www.bearcave.com 7 iank@bearcave.com 8 9 Copyright (c) Ian Kaplan, 1999, 2000 10 11 See copyright file for usage and licensing 12 13 */ 14 15 package jconst; 16 17 import java.io.*; 18 import util.*; 19 20 21 /* 22 * constPool 23 * 24 25 Read the Java JVM constant pool from the class file 26 27 The JVM Specification, Second Edition states: 28 29 The constant pool count (constPoolCnt) is the number of constant 30 pool table entries plus one. A constant pool index is considered 31 valid if it is greater than zero and less than the constant pool 32 count, with the exception for constants of type long and double. 33 34 There should be constPoolCnt-1 constant pool entries. These 35 will be inserted into the constant pool (constPool) at 36 locations 1 ... constPoolCnt-1. 37 38 The first entry of the constant_pool table, constant_pool[0], 39 is reserved for internal use by the Java Virtual Machine 40 implementation. That entry is not present in the class 41 file. The first entry in the class file is constant_pool[1]; 42 43 */ 44 public class constPool extends dataRead implements constPoolTags { 45 private int constPoolCnt; 46 private constBase constPool[] = null; 47 48 public constPool( DataInputStream dStream ) { 49 50 constPoolCnt = readU2( dStream ); 51 52 // The constant pool array is an array of references to 53 // the base class object. References 1..constPoolCnt-1 54 // are valid and are filled in when the constant pool 55 // is read. 56 constPool = new constBase[ constPoolCnt ]; 57 58 readConstPool( dStream ); 59 resolveConstPool(); 60 } // constPool constructor 61 62 63 // 64 // constPoolElem 65 // 66 // Return the constant pool object at index ix. 67 // Note that only constant pool indices greater than 68 // zero are valid. 69 // 70 public constBase constPoolElem( int ix ) 71 { 72 constBase elem = null; 73 74 if (ix > 0 && ix < constPool.length) { 75 elem = constPool[ix]; 76 } 77 return elem; 78 } // constPoolElem 79 80 81 // 82 // allocconstEntry 83 // 84 // Allocate the constant object associated with the tag. 85 // 86 private constBase allocConstEntry( int tag ) { 87 constBase obj = null; 88 89 switch ( tag ) { 90 case CONSTANT_Utf8: 91 obj = new constUtf8(); 92 break; 93 case CONSTANT_Integer: 94 obj = new constInt(); 95 break; 96 case CONSTANT_Float: 97 obj = new constFloat(); 98 break; 99 case CONSTANT_Long: 100 obj = new constLong(); 101 break; 102 case CONSTANT_Double: 103 obj = new constDouble(); 104 break; 105 case CONSTANT_Class: 106 case CONSTANT_String: 107 obj = new constClass_or_String(); 108 break; 109 case CONSTANT_Fieldref: 110 case CONSTANT_Methodref: 111 case CONSTANT_InterfaceMethodref: 112 obj = new constRef(); 113 break; 114 case CONSTANT_NameAndType: 115 obj = new constName_and_Type_info(); 116 break; 117 default: 118 System.out.println("allocConstEntry: bad tag value = " + tag); 119 break; 120 } // switch 121 122 if (obj != null) { 123 obj.tag = tag; 124 } 125 return obj; 126 } // allocConstEntry 127 128 129 // 130 // resolveConstPool 131 // 132 // 133 // A number of the constant pool classes contain indices that 134 // refer to other elements in the constant pool. Convert these 135 // to references, using the set_ref() method. This method is 136 // implemented for all classes, but only does something when it 137 // is appropriate. 138 // 139 // 140 private void resolveConstPool() { 141 for (int i = 1; i < constPoolCnt; i++) { 142 if (constPool[i] != null) 143 constPool[i].set_ref(constPool); 144 } 145 } // resolveConstPool 146 147 148 /** 149 Read the JVM class file constant pool and put 150 it in the internal constant pool. 151 <p> 152 There is a special case in constant pool construction. 153 CONSTANT_Long_info and CONSTANT_Double_info structures 154 take up tow elements in the constant pool table 155 (constPool). See JVM Spec. 4.4.5. As noted in a footnote 156 "In retrospect, making 8-byte constants take two constant 157 pool entries was a poor choice." The extra constant pool 158 entry is unused (and is set to null here). 159 */ 160 private void readConstPool(DataInputStream dStream) { 161 int tag; 162 constBase constObj; 163 164 for (int i = 1; i < constPoolCnt; i++) { 165 tag = readU1( dStream ); 166 if (tag > 0) { 167 constObj = allocConstEntry( tag ); 168 constObj.read( dStream ); 169 constPool[i] = constObj; 170 if (constObj instanceof constLong || 171 constObj instanceof constDouble) { 172 i++; 173 constPool[i] = null; 174 } 175 } 176 else { 177 System.out.println("readConstPool: tag == 0 at constPool index " + i ); 178 } 179 180 } 181 } // readConstPool 182 183 184 // 185 // pr 186 // 187 // Display constant pool count and the contents of the constant pool 188 // 189 public void pr() { 190 System.out.println("constant pool count = " + constPoolCnt + 191 " (size = " + (constPoolCnt-1) + ")"); 192 for (int i = 1; i < constPoolCnt; i++) { 193 System.out.print( i + " "); 194 if (constPool[i] != null) { 195 constPool[i].pr(); 196 System.out.println(); 197 } 198 } 199 } 200 201 } // constPool 202