1 24 25 package org.aspectj.compiler.base.bcg.pool; 26 27 import org.aspectj.compiler.base.bcg.ClassfileBuilder; 28 import org.aspectj.compiler.base.bcg.Asserts; 29 30 import java.io.*; 31 import java.util.*; 32 33 import org.aspectj.compiler.base.ast.ArrayType; 34 import org.aspectj.compiler.base.ast.NameType; 35 import org.aspectj.compiler.base.ast.RefType; 36 37 public final class ConstantPool { 38 39 42 private boolean isResolvedFlag = false; 43 public boolean isResolved() { return isResolvedFlag; } 44 45 private ClassfileBuilder cfb; 48 public ConstantPool(ClassfileBuilder cfb) { 49 this.cfb = cfb; 50 } 51 52 private List table = new ArrayList(); 53 { 54 table.add(Placeholder.it); 55 } 56 private Map cache = new Hashtable(); 57 58 public void resolve() { 59 if (isResolved()) { 60 throw new RuntimeException ("already resolved"); 61 } 62 Object [] a = table.toArray(); 63 table.clear(); 64 Arrays.sort(a); 65 table.add(Placeholder.it); 66 for (int i = 0, len = a.length; i < len; i++) { 67 add1((Constant) a[i]); 68 } 69 isResolvedFlag = true; 70 } 71 72 public Constant get(int i) { return (Constant) table.get(i); } 73 74 Constant get(int i, Constant young) { 75 Constant c = (Constant) table.get(i); 76 if (c instanceof Placeholder) { 77 table.set(i, young); 78 young.setIndex(i); 79 return young; 80 } else { 81 return c; 82 } 83 } 84 85 private Constant add(Constant constant) { 86 Constant cachedConstant = (Constant) cache.get(constant); 87 if (cachedConstant != null) { 88 return cachedConstant; 89 } else { 90 add1(constant); 91 return constant; 92 } 93 } 94 95 private void add1(Constant constant) { 96 if (constant instanceof Placeholder) return; 97 Asserts.assertUU2(table.size(), "Too many constants in constant pool"); 98 constant.setIndex(table.size()); 99 cache.put(constant, constant); 100 table.add(constant); 101 if (constant.isBig()) { 102 table.add(Placeholder.it); 103 } 104 } 105 106 107 110 public static void writeIndex(Constant constant, DataOutputStream stream) 111 throws IOException { 112 if (constant == null) { 113 stream.writeShort(0); 114 } else { 115 constant.writeIndex(stream); 116 } 117 } 118 119 public void writeTo(DataOutputStream stream) throws IOException { 120 if (! isResolved()) { 121 throw new RuntimeException ("must resolve constant pool first"); 122 } 123 stream.writeShort((short) table.size()); 124 for (Iterator i = table.iterator(); i.hasNext(); ) { 125 Constant c = (Constant) i.next(); 126 c.writeTo(stream); 127 } 128 } 129 130 133 public void display(int indent, boolean inline) { 134 System.err.print("(pool"); 135 display(table, indent + 2, inline); 136 System.err.print(")"); 137 } 138 139 public static void display(List l, int indent, boolean inline) { 140 for (Iterator i = l.iterator(); i.hasNext(); ) { 141 Constant c = (Constant) i.next(); 142 if (c instanceof Placeholder) continue; 143 between(indent, inline); 144 c.display(indent, inline); 145 } 146 } 147 148 static void between(int indent, boolean inline) { 149 if (inline) { 150 System.err.print(" "); 151 } else { 152 System.err.println(); 153 for (int s=indent; s >= 0; s--) System.err.print(" "); 154 } 155 } 156 157 160 162 public ClassConstant addClass(RefType refType) { 163 if (refType instanceof ArrayType) 164 return addClass((ArrayType)refType); 165 else 166 return addClass((NameType)refType); 167 } 168 169 170 public ClassConstant addClass(ArrayType arrayType) { 171 return addClassNoInnerCheck(arrayType); 172 } 173 174 public ClassConstant addClass(NameType nameType) { 175 if (! nameType.isPackageMember()) { 176 cfb.addInnerClassRef(nameType); 177 } 178 return addClassNoInnerCheck(nameType); 179 } 180 181 public ClassConstant addClassNoInnerCheck(RefType refType) { 182 return (ClassConstant) add(new ClassConstant(addUtf8(refType.getInternalName()))); 183 } 184 185 187 public Utf8Constant addUtf8(String name) { 188 return (Utf8Constant) add(new Utf8Constant(name)); 189 } 190 191 public StringConstant addString(String value) { 192 return (StringConstant) add(new StringConstant(addUtf8(value))); 193 } 194 public IntConstant addInt(int value) { 195 return (IntConstant) add(new IntConstant(value)); 196 } 197 public FloatConstant addFloat(float value) { 198 return (FloatConstant) add(new FloatConstant(value)); 199 } 200 public LongConstant addLong(long value) { 201 return (LongConstant) add(new LongConstant(value)); 202 } 203 public DoubleConstant addDouble(double value) { 204 return (DoubleConstant) add(new DoubleConstant(value)); 205 } 206 207 public MethodrefConstant addMethodRef(NameType nameType, String name, String descriptor) { 208 return (MethodrefConstant) 209 add(new MethodrefConstant(addClass(nameType), 210 addNameAndType(name, descriptor))); 211 } 212 213 public InterfaceMethodrefConstant 214 addInterfaceMethodRef(NameType nameType, String name, String descriptor) { 215 return (InterfaceMethodrefConstant) 216 add(new InterfaceMethodrefConstant(addClass(nameType), 217 addNameAndType(name, descriptor))); 218 } 219 220 public FieldrefConstant addFieldRef(NameType nameType, String name, String descriptor) { 221 return (FieldrefConstant) 222 add(new FieldrefConstant(addClass(nameType), 223 addNameAndType(name, descriptor))); 224 } 225 226 public NameAndTypeConstant addNameAndType(String name, String descriptor) { 227 return (NameAndTypeConstant) 228 add(new NameAndTypeConstant(addUtf8(name), addUtf8(descriptor))); 229 } 230 231 234 public void readFrom(DataInputStream stream) throws IOException { 235 int size = stream.readUnsignedShort(); 236 table.clear(); 237 for (int i = size - 1; i >= 0; i--) table.add(Placeholder.it); 238 for (int i = 1; i < size; i++) { 239 int tag = stream.readUnsignedByte(); 240 Constant c; 241 switch (tag) { 242 case Constant.UTF_TAG: 243 c = get(i, new Utf8Constant()); break; 244 case Constant.INT_TAG: 245 c = get(i, new IntConstant()); break; 246 case Constant.FLOAT_TAG: 247 c = get(i, new FloatConstant()); break; 248 case Constant.LONG_TAG: 249 c = get(i, new LongConstant()); i++; break; 250 case Constant.DOUBLE_TAG: 251 c = get(i, new DoubleConstant()); i++; break; 252 case Constant.CLASS_TAG: 253 c = get(i, new ClassConstant()); break; 254 case Constant.STRING_TAG: 255 c = get(i, new StringConstant()); break; 256 case Constant.FIELD_REF_TAG: 257 c = get(i, new FieldrefConstant()); break; 258 case Constant.METHOD_REF_TAG: 259 c = get(i, new MethodrefConstant()); break; 260 case Constant.INTERFACE_METHOD_REF_TAG: 261 c = get(i, new InterfaceMethodrefConstant()); break; 262 case Constant.NAME_AND_TYPE_TAG: 263 c = get(i, new NameAndTypeConstant()); break; 264 default: 265 throw new RuntimeException ("unknown constant pool tag " + tag); 266 } 267 c.readFrom(stream, this); 268 } 269 for (Iterator i = table.iterator(); i.hasNext(); ) { 270 Object o = i.next(); 271 if (o instanceof Placeholder) continue; 272 cache.put(o, o); 273 } 274 } 275 } 276 | Popular Tags |