1 30 31 39 40 package jbet; 41 import java.io.*; 42 import java.util.*; 43 44 public final class FieldInfo { 45 46 public static String JbetLogFacility = "field"; 47 48 public int accessFlags; 49 50 public String name; 51 public Type type; 52 53 Vector attrHints; 54 public boolean synthetic, deprecated; 55 public Object value; 56 57 58 public ClassInfo cr; 59 60 61 int nameIndex; 62 int typeIndex; 63 Vector attributes; 64 int valueIndex; 65 66 69 void relocate (Hashtable subs) { 70 type = type.relocate_new(subs); 71 } 72 73 75 FieldInfo() { 76 attrHints = new Vector(); 77 } 78 79 83 public void disassemble (LineWriter out, String prefix) { 84 out.print(prefix + ".field " + Util.flags2str(accessFlags) + " " + name 85 + " " + type ); 86 if (synthetic || deprecated || value != null) { 87 out.print( " { " ); 88 boolean first = true; 89 if (synthetic) { 90 out.print(".synthetic"); 91 first = false; 92 } 93 if (deprecated) { 94 if (!first) out.print("; "); 95 out.print(".deprecated"); 96 first = false; 97 } 98 if (value != null) { 99 if (!first) out.print("; "); 100 first = false; 101 out.print( ".value "); 102 if (type.equals(Type.STRING)) 103 out.print("\"" + Util.quoteString((String ) value) + "\""); 104 else 105 switch(type.vmType()) { 106 case Type.VM_INT: 107 case Type.VM_LONG: 108 out.print( value ); 109 break; 110 default: 111 throw new RuntimeException ("not implemented"); 112 } 113 } 114 out.print(" }"); 115 } 116 out.println(); 117 } 118 119 122 public FieldInfo (Lexer lexer) { 123 this(); 124 lexer.push(Lexer.ST_ASM); 125 if (!lexer.match(Token.TAG).text.equals(".field")) 126 lexer.unexpected(lexer.justread()); 127 accessFlags = lexer.parse_flags(ACC_ALL_FFLAGS); 128 name = lexer.match(Token.TAG).text; 129 type = lexer.parse_type(); 130 if (lexer.peek().type != ';' && lexer.peek().type != Token.EOF) { 131 lexer.match('{'); 132 while (true) { 134 lexer.state = Lexer.ST_ASM; 135 while ( lexer.peek().type == ';' ) lexer.read(); 136 Token tok = lexer.peek(); 137 lexer.state = Lexer.ST_ASM_ARG; 138 if (tok.type == Token.TAG) { 139 if (tok.text.equals(".synthetic")) { 140 lexer.read(); 141 lexer.term(); 142 synthetic = true; 143 continue; 144 } 145 if (tok.text.equals(".deprecated")) { 146 lexer.read(); 147 lexer.term(); 148 deprecated = true; 149 continue; 150 } 151 if (tok.text.equals(".flags")) { 152 lexer.read(); 153 int flags = lexer.parse_flags(ACC_ALL_FFLAGS); 154 lexer.term(); 155 accessFlags = flags; 156 continue; 157 } 158 if (tok.text.equals(".value")) { 159 lexer.read(); 160 if (type.equals(Type.STRING)) { 161 value = lexer.parse_string(); 162 } else 163 switch(type.vmType()) { 164 case Type.VM_INT: 165 value = new Integer ( lexer.parse_int() ); 166 break; 167 case Type.VM_LONG: 168 value = new Long ( lexer.parse_long() ); 169 break; 170 default: 171 throw new RuntimeException ("not implemented"); 172 } 173 lexer.term(); 174 continue; 175 } 176 lexer.unexpected(tok); 177 } 178 if (tok.type == '}') 179 break; 180 lexer.unexpected(tok); 181 } 182 lexer.match('}'); 183 } 184 lexer.pop(); 185 } 186 187 190 public FieldInfo(FieldInfo fi) { 191 accessFlags = fi.accessFlags; 192 name = fi.name; 193 type = fi.type; 194 value = fi.value; 195 synthetic = fi.synthetic; 196 deprecated = fi.deprecated; 197 attrHints = new Vector(); 198 } 199 200 204 public FieldInfo (String n, Type t) { 205 name = n; 206 type = t; 207 accessFlags = 0; 208 attrHints = new Vector(); 209 } 210 211 216 public FieldInfo (String n, Type t, int a) { 217 name = n; 218 type = t; 219 accessFlags = a; 220 attrHints = new Vector(); 221 } 222 223 226 public String recString() { 227 StringBuffer ret = new StringBuffer (); 228 String f = flags2str(accessFlags); 229 if (!f.equals("")) ret.append( f + " " ); 230 231 if (synthetic) 232 ret.append( "synthetic " ); 233 if (deprecated) 234 ret.append( "deprecated " ); 235 236 ret.append(name + " " + type.toString() ); 237 238 if (value != null) 239 if (value instanceof String ) 240 ret.append( " = \"" + value.toString() + "\""); 241 else 242 ret.append( " = " + value.toString() ); 243 244 return ret.toString(); 245 } 246 247 250 AttributeWriter valueWriter() { 251 return new AttributeWriter() { 252 public void write(DataOutputStream dataOut) 253 throws IOException, RuntimeException { 254 dataOut.writeShort( valueIndex ); 255 } 256 public int size() { return 2; } 257 }; 258 } 259 260 public void resolveConstants () { 261 resolveConstants(cr.constantPool); 262 } 263 264 267 void resolveConstants (ConstantPool constantPool) { 268 nameIndex = constantPool.internUtf8 (name); 269 typeIndex = constantPool.internUtf8( type.toString() ); 270 271 272 Vector outAttrs = new Vector(); 273 274 if (synthetic) 275 outAttrs.addElement(new GenericAttribute("Synthetic", constantPool).nodata()); 276 277 if (deprecated) 278 outAttrs.addElement(new GenericAttribute("Deprecated", constantPool).nodata()); 279 280 if (value != null) { 281 GenericAttribute attr = new GenericAttribute("ConstantValue", constantPool); 282 attr.writer = valueWriter(); 283 if (value instanceof Long ) 284 valueIndex = constantPool.internLong( ((Long )value).longValue() ) ; 285 else if (value instanceof Float ) 286 valueIndex = constantPool.internFloat( ((Float )value).floatValue() ) ; 287 else if (value instanceof Double ) 288 valueIndex = constantPool.internDouble( ((Double )value).doubleValue()); 289 else if (value instanceof Integer ) 290 valueIndex = constantPool.internInteger( ((Integer )value).intValue()); 291 else if (value instanceof String ) 292 valueIndex = constantPool.internString( (String ) value ) ; 293 outAttrs.addElement (attr); 294 } 295 296 attributes = new Vector (); 297 GenericAttribute.permute(attrHints, outAttrs, attributes); 298 } 299 300 303 void writeFile(DataOutputStream dataOut) throws IOException { 304 dataOut.writeShort (accessFlags); 305 dataOut.writeShort (nameIndex); 306 dataOut.writeShort (typeIndex); 307 308 dataOut.writeShort (attributes.size()); 309 for (int i = 0; i < attributes.size(); i++) 310 ((GenericAttribute)attributes.elementAt(i)).writeAll(dataOut); 311 } 312 313 317 public FieldInfo (DataInputStream dataIn, ConstantPool constantPool) 318 throws IOException, ClassFileException { 319 320 value = null; 321 322 accessFlags = dataIn.readUnsignedShort(); 323 324 nameIndex = dataIn.readUnsignedShort(); 325 name = constantPool.utf8At(nameIndex); 326 327 typeIndex = dataIn.readUnsignedShort(); 328 String typeString = constantPool.utf8At(typeIndex); 329 type = new Type (typeString); 330 331 int attributesCount = dataIn.readUnsignedShort(); 332 attrHints = new Vector (attributesCount); 333 for (int i = 0; i < attributesCount; i++) { 334 int nameindex = dataIn.readUnsignedShort(); 335 String attrname = constantPool.utf8At(nameindex); 336 int length = dataIn.readInt(); 337 338 GenericAttribute item = new GenericAttribute (attrname, nameindex); 339 340 if (attrname.equals("Synthetic")) { 341 synthetic = true; 342 item.nodata(); 343 } else if (attrname.equals("Deprecated")) { 344 deprecated = true; 345 item.nodata(); 346 } else if (attrname.equals("ConstantValue")) { 347 valueIndex = dataIn.readUnsignedShort(); 348 item.writer = valueWriter(); 349 switch ( constantPool.tagAt(valueIndex) ) { 350 case ConstantPool.CONSTANT_Long: 351 long l = constantPool.longAt(valueIndex); 352 value = new Long (l); break; 353 case ConstantPool.CONSTANT_Float: 354 float f = constantPool.floatAt(valueIndex); 355 value = new Float (f); break; 356 case ConstantPool.CONSTANT_Double: 357 double d = constantPool.doubleAt(valueIndex); 358 value = new Double (d); break; 359 case ConstantPool.CONSTANT_Integer: 360 int I = constantPool.integerAt(valueIndex); 361 value = new Integer (I); break; 362 case ConstantPool.CONSTANT_String: 363 value = constantPool.stringAt(valueIndex); break; 364 default: 365 throw new ClassFileException ("bad index for ConstantValue"); 366 } 367 } else { 368 Jbet.warn.println ("Warning: unrecognised field attribute " + attrname); 369 item.read (length, dataIn); 370 } 371 attrHints.addElement(item); 372 } 373 374 attributes = attrHints; 375 376 } 377 378 381 public boolean isStatic() { 382 return (accessFlags & ACC_STATIC) != 0; 383 } 384 385 388 public static String flags2str (int accessFlags) { 389 return Util.flags2str(accessFlags); 390 } 391 392 public static final int ACC_PUBLIC = Util.ACC_PUBLIC; 393 public static final int ACC_PRIVATE = Util.ACC_PRIVATE; 394 public static final int ACC_PROTECTED = Util.ACC_PROTECTED; 395 public static final int ACC_STATIC = Util.ACC_STATIC; 396 public static final int ACC_FINAL = Util.ACC_FINAL; 397 public static final int ACC_VOLATILE = Util.ACC_VOLATILE; 398 public static final int ACC_TRANSIENT = Util.ACC_TRANSIENT; 399 400 public static final int ACC_ALL_FFLAGS = ACC_PUBLIC | ACC_PRIVATE | 401 ACC_PROTECTED | ACC_STATIC | ACC_FINAL | ACC_VOLATILE | 402 ACC_TRANSIENT; 403 404 408 public boolean equals(Object o) { 409 return this == o; 410 } 411 412 public String qualifiedName() { 413 return cr.thisClass + "." + name; 414 } 415 } 416 | Popular Tags |