1 /* 2 * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.javap; 27 28 import java.util.Formatter; 29 30 import com.sun.tools.classfile.AccessFlags; 31 import com.sun.tools.classfile.AnnotationDefault_attribute; 32 import com.sun.tools.classfile.Attribute; 33 import com.sun.tools.classfile.Attributes; 34 import com.sun.tools.classfile.BootstrapMethods_attribute; 35 import com.sun.tools.classfile.CharacterRangeTable_attribute; 36 import com.sun.tools.classfile.Code_attribute; 37 import com.sun.tools.classfile.CompilationID_attribute; 38 import com.sun.tools.classfile.ConstantPool; 39 import com.sun.tools.classfile.ConstantPoolException; 40 import com.sun.tools.classfile.ConstantValue_attribute; 41 import com.sun.tools.classfile.DefaultAttribute; 42 import com.sun.tools.classfile.Deprecated_attribute; 43 import com.sun.tools.classfile.EnclosingMethod_attribute; 44 import com.sun.tools.classfile.Exceptions_attribute; 45 import com.sun.tools.classfile.InnerClasses_attribute; 46 import com.sun.tools.classfile.LineNumberTable_attribute; 47 import com.sun.tools.classfile.LocalVariableTable_attribute; 48 import com.sun.tools.classfile.LocalVariableTypeTable_attribute; 49 import com.sun.tools.classfile.MethodParameters_attribute; 50 import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute; 51 import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute; 52 import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute; 53 import com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute; 54 import com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute; 55 import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute; 56 import com.sun.tools.classfile.Signature_attribute; 57 import com.sun.tools.classfile.SourceDebugExtension_attribute; 58 import com.sun.tools.classfile.SourceFile_attribute; 59 import com.sun.tools.classfile.SourceID_attribute; 60 import com.sun.tools.classfile.StackMapTable_attribute; 61 import com.sun.tools.classfile.StackMap_attribute; 62 import com.sun.tools.classfile.Synthetic_attribute; 63 64 import static com.sun.tools.classfile.AccessFlags.*; 65 66 /* 67 * A writer for writing Attributes as text. 68 * 69 * <p><b>This is NOT part of any supported API. 70 * If you write code that depends on this, you do so at your own risk. 71 * This code and its internal interfaces are subject to change or 72 * deletion without notice.</b> 73 */ 74 public class AttributeWriter extends BasicWriter 75 implements Attribute.Visitor<Void,Void> 76 { 77 public static AttributeWriter instance(Context context) { 78 AttributeWriter instance = context.get(AttributeWriter.class); 79 if (instance == null) 80 instance = new AttributeWriter(context); 81 return instance; 82 } 83 84 protected AttributeWriter(Context context) { 85 super(context); 86 context.put(AttributeWriter.class, this); 87 annotationWriter = AnnotationWriter.instance(context); 88 codeWriter = CodeWriter.instance(context); 89 constantWriter = ConstantWriter.instance(context); 90 options = Options.instance(context); 91 } 92 93 public void write(Object owner, Attribute attr, ConstantPool constant_pool) { 94 if (attr != null) { 95 // null checks 96 owner.getClass(); 97 constant_pool.getClass(); 98 this.constant_pool = constant_pool; 99 this.owner = owner; 100 attr.accept(this, null); 101 } 102 } 103 104 public void write(Object owner, Attributes attrs, ConstantPool constant_pool) { 105 if (attrs != null) { 106 // null checks 107 owner.getClass(); 108 constant_pool.getClass(); 109 this.constant_pool = constant_pool; 110 this.owner = owner; 111 for (Attribute attr: attrs) 112 attr.accept(this, null); 113 } 114 } 115 116 public Void visitDefault(DefaultAttribute attr, Void ignore) { 117 byte[] data = attr.info; 118 int i = 0; 119 int j = 0; 120 print(" "); 121 try { 122 print(attr.getName(constant_pool)); 123 } catch (ConstantPoolException e) { 124 report(e); 125 print("attribute name = #" + attr.attribute_name_index); 126 } 127 print(": "); 128 println("length = 0x" + toHex(attr.info.length)); 129 130 print(" "); 131 132 while (i < data.length) { 133 print(toHex(data[i], 2)); 134 135 j++; 136 if (j == 16) { 137 println(); 138 print(" "); 139 j = 0; 140 } else { 141 print(" "); 142 } 143 i++; 144 } 145 println(); 146 return null; 147 } 148 149 public Void visitAnnotationDefault(AnnotationDefault_attribute attr, Void ignore) { 150 println("AnnotationDefault:"); 151 indent(+1); 152 print("default_value: "); 153 annotationWriter.write(attr.default_value); 154 indent(-1); 155 return null; 156 } 157 158 public Void visitBootstrapMethods(BootstrapMethods_attribute attr, Void p) { 159 println(Attribute.BootstrapMethods + ":"); 160 for (int i = 0; i < attr.bootstrap_method_specifiers.length ; i++) { 161 BootstrapMethods_attribute.BootstrapMethodSpecifier bsm = attr.bootstrap_method_specifiers[i]; 162 indent(+1); 163 print(i + ": #" + bsm.bootstrap_method_ref + " "); 164 println(constantWriter.stringValue(bsm.bootstrap_method_ref)); 165 indent(+1); 166 println("Method arguments:"); 167 indent(+1); 168 for (int j = 0; j < bsm.bootstrap_arguments.length; j++) { 169 print("#" + bsm.bootstrap_arguments[j] + " "); 170 println(constantWriter.stringValue(bsm.bootstrap_arguments[j])); 171 } 172 indent(-3); 173 } 174 return null; 175 } 176 177 public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, Void ignore) { 178 println("CharacterRangeTable:"); 179 indent(+1); 180 for (int i = 0; i < attr.character_range_table.length; i++) { 181 CharacterRangeTable_attribute.Entry e = attr.character_range_table[i]; 182 print(String.format(" %2d, %2d, %6x, %6x, %4x", 183 e.start_pc, e.end_pc, 184 e.character_range_start, e.character_range_end, 185 e.flags)); 186 tab(); 187 print(String.format("// %2d, %2d, %4d:%02d, %4d:%02d", 188 e.start_pc, e.end_pc, 189 (e.character_range_start >> 10), (e.character_range_start & 0x3ff), 190 (e.character_range_end >> 10), (e.character_range_end & 0x3ff))); 191 if ((e.flags & CharacterRangeTable_attribute.CRT_STATEMENT) != 0) 192 print(", statement"); 193 if ((e.flags & CharacterRangeTable_attribute.CRT_BLOCK) != 0) 194 print(", block"); 195 if ((e.flags & CharacterRangeTable_attribute.CRT_ASSIGNMENT) != 0) 196 print(", assignment"); 197 if ((e.flags & CharacterRangeTable_attribute.CRT_FLOW_CONTROLLER) != 0) 198 print(", flow-controller"); 199 if ((e.flags & CharacterRangeTable_attribute.CRT_FLOW_TARGET) != 0) 200 print(", flow-target"); 201 if ((e.flags & CharacterRangeTable_attribute.CRT_INVOKE) != 0) 202 print(", invoke"); 203 if ((e.flags & CharacterRangeTable_attribute.CRT_CREATE) != 0) 204 print(", create"); 205 if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_TRUE) != 0) 206 print(", branch-true"); 207 if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_FALSE) != 0) 208 print(", branch-false"); 209 println(); 210 } 211 indent(-1); 212 return null; 213 } 214 215 public Void visitCode(Code_attribute attr, Void ignore) { 216 codeWriter.write(attr, constant_pool); 217 return null; 218 } 219 220 public Void visitCompilationID(CompilationID_attribute attr, Void ignore) { 221 constantWriter.write(attr.compilationID_index); 222 return null; 223 } 224 225 public Void visitConstantValue(ConstantValue_attribute attr, Void ignore) { 226 if (options.compat) // BUG 6622216 javap names some attributes incorrectly 227 print("Constant value: "); 228 else 229 print("ConstantValue: "); 230 constantWriter.write(attr.constantvalue_index); 231 println(); 232 return null; 233 } 234 235 public Void visitDeprecated(Deprecated_attribute attr, Void ignore) { 236 println("Deprecated: true"); 237 return null; 238 } 239 240 public Void visitEnclosingMethod(EnclosingMethod_attribute attr, Void ignore) { 241 print("EnclosingMethod: #" + attr.class_index + ".#" + attr.method_index); 242 tab(); 243 print("// " + getJavaClassName(attr)); 244 if (attr.method_index != 0) 245 print("." + getMethodName(attr)); 246 println(); 247 return null; 248 } 249 250 private String getJavaClassName(EnclosingMethod_attribute a) { 251 try { 252 return getJavaName(a.getClassName(constant_pool)); 253 } catch (ConstantPoolException e) { 254 return report(e); 255 } 256 } 257 258 private String getMethodName(EnclosingMethod_attribute a) { 259 try { 260 return a.getMethodName(constant_pool); 261 } catch (ConstantPoolException e) { 262 return report(e); 263 } 264 } 265 266 public Void visitExceptions(Exceptions_attribute attr, Void ignore) { 267 println("Exceptions:"); 268 indent(+1); 269 print("throws "); 270 for (int i = 0; i < attr.number_of_exceptions; i++) { 271 if (i > 0) 272 print(", "); 273 print(getJavaException(attr, i)); 274 } 275 println(); 276 indent(-1); 277 return null; 278 } 279 280 private String getJavaException(Exceptions_attribute attr, int index) { 281 try { 282 return getJavaName(attr.getException(index, constant_pool)); 283 } catch (ConstantPoolException e) { 284 return report(e); 285 } 286 } 287 288 public Void visitInnerClasses(InnerClasses_attribute attr, Void ignore) { 289 boolean first = true; 290 if (options.compat) { 291 writeInnerClassHeader(); 292 first = false; 293 } 294 for (int i = 0 ; i < attr.classes.length; i++) { 295 InnerClasses_attribute.Info info = attr.classes[i]; 296 //access 297 AccessFlags access_flags = info.inner_class_access_flags; 298 if (options.compat) { 299 // BUG 6622215: javap ignores certain relevant access flags 300 access_flags = access_flags.ignore(ACC_STATIC | ACC_PROTECTED | ACC_PRIVATE | ACC_INTERFACE | ACC_SYNTHETIC | ACC_ENUM); 301 // BUG 6622232: javap gets whitespace confused 302 print(" "); 303 } 304 if (options.checkAccess(access_flags)) { 305 if (first) { 306 writeInnerClassHeader(); 307 first = false; 308 } 309 print(" "); 310 for (String name: access_flags.getInnerClassModifiers()) 311 print(name + " "); 312 if (info.inner_name_index!=0) { 313 print("#" + info.inner_name_index + "= "); 314 } 315 print("#" + info.inner_class_info_index); 316 if (info.outer_class_info_index != 0) { 317 print(" of #" + info.outer_class_info_index); 318 } 319 print("; //"); 320 if (info.inner_name_index != 0) { 321 print(getInnerName(constant_pool, info) + "="); 322 } 323 constantWriter.write(info.inner_class_info_index); 324 if (info.outer_class_info_index != 0) { 325 print(" of "); 326 constantWriter.write(info.outer_class_info_index); 327 } 328 println(); 329 } 330 } 331 if (!first) 332 indent(-1); 333 return null; 334 } 335 336 String getInnerName(ConstantPool constant_pool, InnerClasses_attribute.Info info) { 337 try { 338 return info.getInnerName(constant_pool); 339 } catch (ConstantPoolException e) { 340 return report(e); 341 } 342 } 343 344 private void writeInnerClassHeader() { 345 if (options.compat) // BUG 6622216: javap names some attributes incorrectly 346 print("InnerClass"); 347 else 348 print("InnerClasses"); 349 println(":"); 350 indent(+1); 351 } 352 353 public Void visitLineNumberTable(LineNumberTable_attribute attr, Void ignore) { 354 println("LineNumberTable:"); 355 indent(+1); 356 for (LineNumberTable_attribute.Entry entry: attr.line_number_table) { 357 println("line " + entry.line_number + ": " + entry.start_pc); 358 } 359 indent(-1); 360 return null; 361 } 362 363 public Void visitLocalVariableTable(LocalVariableTable_attribute attr, Void ignore) { 364 println("LocalVariableTable:"); 365 indent(+1); 366 println("Start Length Slot Name Signature"); 367 for (LocalVariableTable_attribute.Entry entry : attr.local_variable_table) { 368 Formatter formatter = new Formatter(); 369 println(formatter.format("%8d %7d %5d %5s %s", 370 entry.start_pc, entry.length, entry.index, 371 constantWriter.stringValue(entry.name_index), 372 constantWriter.stringValue(entry.descriptor_index))); 373 } 374 indent(-1); 375 return null; 376 } 377 378 public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, Void ignore) { 379 println("LocalVariableTypeTable:"); 380 indent(+1); 381 println("Start Length Slot Name Signature"); 382 for (LocalVariableTypeTable_attribute.Entry entry : attr.local_variable_table) { 383 println(String.format("%5d %7d %5d %5s %s", 384 entry.start_pc, entry.length, entry.index, 385 constantWriter.stringValue(entry.name_index), 386 constantWriter.stringValue(entry.signature_index))); 387 } 388 indent(-1); 389 return null; 390 } 391 392 private static final String format = "%-31s%s"; 393 394 public Void visitMethodParameters(MethodParameters_attribute attr, 395 Void ignore) { 396 397 final String header = String.format(format, "Name", "Flags"); 398 println("MethodParameters:"); 399 indent(+1); 400 println(header); 401 for (MethodParameters_attribute.Entry entry : 402 attr.method_parameter_table) { 403 String namestr = 404 entry.name_index != 0 ? 405 constantWriter.stringValue(entry.name_index) : "<no name>"; 406 String flagstr = 407 (0 != (entry.flags & ACC_FINAL) ? "final " : "") + 408 (0 != (entry.flags & ACC_MANDATED) ? "mandated " : "") + 409 (0 != (entry.flags & ACC_SYNTHETIC) ? " synthetic" : ""); 410 println(String.format(format, namestr, flagstr)); 411 } 412 indent(-1); 413 return null; 414 } 415 416 public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, Void ignore) { 417 println("RuntimeVisibleAnnotations:"); 418 indent(+1); 419 for (int i = 0; i < attr.annotations.length; i++) { 420 print(i + ": "); 421 annotationWriter.write(attr.annotations[i]); 422 println(); 423 } 424 indent(-1); 425 return null; 426 } 427 428 public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, Void ignore) { 429 println("RuntimeInvisibleAnnotations:"); 430 indent(+1); 431 for (int i = 0; i < attr.annotations.length; i++) { 432 print(i + ": "); 433 annotationWriter.write(attr.annotations[i]); 434 println(); 435 } 436 indent(-1); 437 return null; 438 } 439 440 public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, Void ignore) { 441 println("RuntimeVisibleTypeAnnotations:"); 442 indent(+1); 443 for (int i = 0; i < attr.annotations.length; i++) { 444 print(i + ": "); 445 annotationWriter.write(attr.annotations[i]); 446 println(); 447 } 448 indent(-1); 449 return null; 450 } 451 452 public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, Void ignore) { 453 println("RuntimeInvisibleTypeAnnotations:"); 454 indent(+1); 455 for (int i = 0; i < attr.annotations.length; i++) { 456 print(i + ": "); 457 annotationWriter.write(attr.annotations[i]); 458 println(); 459 } 460 indent(-1); 461 return null; 462 } 463 464 public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) { 465 println("RuntimeVisibleParameterAnnotations:"); 466 indent(+1); 467 for (int param = 0; param < attr.parameter_annotations.length; param++) { 468 println("parameter " + param + ": "); 469 indent(+1); 470 for (int i = 0; i < attr.parameter_annotations[param].length; i++) { 471 print(i + ": "); 472 annotationWriter.write(attr.parameter_annotations[param][i]); 473 println(); 474 } 475 indent(-1); 476 } 477 indent(-1); 478 return null; 479 } 480 481 public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, Void ignore) { 482 println("RuntimeInvisibleParameterAnnotations:"); 483 indent(+1); 484 for (int param = 0; param < attr.parameter_annotations.length; param++) { 485 println(param + ": "); 486 indent(+1); 487 for (int i = 0; i < attr.parameter_annotations[param].length; i++) { 488 print(i + ": "); 489 annotationWriter.write(attr.parameter_annotations[param][i]); 490 println(); 491 } 492 indent(-1); 493 } 494 indent(-1); 495 return null; 496 } 497 498 public Void visitSignature(Signature_attribute attr, Void ignore) { 499 print("Signature: #" + attr.signature_index); 500 tab(); 501 println("// " + getSignature(attr)); 502 return null; 503 } 504 505 String getSignature(Signature_attribute info) { 506 try { 507 return info.getSignature(constant_pool); 508 } catch (ConstantPoolException e) { 509 return report(e); 510 } 511 } 512 513 public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, Void ignore) { 514 println("SourceDebugExtension: " + attr.getValue()); 515 return null; 516 } 517 518 public Void visitSourceFile(SourceFile_attribute attr, Void ignore) { 519 println("SourceFile: \"" + getSourceFile(attr) + "\""); 520 return null; 521 } 522 523 private String getSourceFile(SourceFile_attribute attr) { 524 try { 525 return attr.getSourceFile(constant_pool); 526 } catch (ConstantPoolException e) { 527 return report(e); 528 } 529 } 530 531 public Void visitSourceID(SourceID_attribute attr, Void ignore) { 532 constantWriter.write(attr.sourceID_index); 533 return null; 534 } 535 536 public Void visitStackMap(StackMap_attribute attr, Void ignore) { 537 println("StackMap: number_of_entries = " + attr.number_of_entries); 538 indent(+1); 539 StackMapTableWriter w = new StackMapTableWriter(); 540 for (StackMapTable_attribute.stack_map_frame entry : attr.entries) { 541 w.write(entry); 542 } 543 println(); 544 indent(-1); 545 return null; 546 } 547 548 public Void visitStackMapTable(StackMapTable_attribute attr, Void ignore) { 549 println("StackMapTable: number_of_entries = " + attr.number_of_entries); 550 indent(+1); 551 StackMapTableWriter w = new StackMapTableWriter(); 552 for (StackMapTable_attribute.stack_map_frame entry : attr.entries) { 553 w.write(entry); 554 } 555 println(); 556 indent(-1); 557 return null; 558 } 559 560 class StackMapTableWriter // also handles CLDC StackMap attributes 561 implements StackMapTable_attribute.stack_map_frame.Visitor<Void,Void> { 562 public void write(StackMapTable_attribute.stack_map_frame frame) { 563 frame.accept(this, null); 564 } 565 566 public Void visit_same_frame(StackMapTable_attribute.same_frame frame, Void p) { 567 printHeader(frame); 568 println(" /* same */"); 569 return null; 570 } 571 572 public Void visit_same_locals_1_stack_item_frame(StackMapTable_attribute.same_locals_1_stack_item_frame frame, Void p) { 573 printHeader(frame); 574 println(" /* same_locals_1_stack_item */"); 575 indent(+1); 576 printMap("stack", frame.stack); 577 indent(-1); 578 return null; 579 } 580 581 public Void visit_same_locals_1_stack_item_frame_extended(StackMapTable_attribute.same_locals_1_stack_item_frame_extended frame, Void p) { 582 printHeader(frame); 583 println(" /* same_locals_1_stack_item_frame_extended */"); 584 indent(+1); 585 println("offset_delta = " + frame.offset_delta); 586 printMap("stack", frame.stack); 587 indent(-1); 588 return null; 589 } 590 591 public Void visit_chop_frame(StackMapTable_attribute.chop_frame frame, Void p) { 592 printHeader(frame); 593 println(" /* chop */"); 594 indent(+1); 595 println("offset_delta = " + frame.offset_delta); 596 indent(-1); 597 return null; 598 } 599 600 public Void visit_same_frame_extended(StackMapTable_attribute.same_frame_extended frame, Void p) { 601 printHeader(frame); 602 println(" /* same_frame_extended */"); 603 indent(+1); 604 println("offset_delta = " + frame.offset_delta); 605 indent(-1); 606 return null; 607 } 608 609 public Void visit_append_frame(StackMapTable_attribute.append_frame frame, Void p) { 610 printHeader(frame); 611 println(" /* append */"); 612 println(" offset_delta = " + frame.offset_delta); 613 printMap("locals", frame.locals); 614 return null; 615 } 616 617 public Void visit_full_frame(StackMapTable_attribute.full_frame frame, Void p) { 618 printHeader(frame); 619 if (frame instanceof StackMap_attribute.stack_map_frame) { 620 indent(+1); 621 println(" offset = " + frame.offset_delta); 622 } else { 623 println(" /* full_frame */"); 624 indent(+1); 625 println("offset_delta = " + frame.offset_delta); 626 } 627 printMap("locals", frame.locals); 628 printMap("stack", frame.stack); 629 indent(-1); 630 return null; 631 } 632 633 void printHeader(StackMapTable_attribute.stack_map_frame frame) { 634 print(" frame_type = " + frame.frame_type); 635 } 636 637 void printMap(String name, StackMapTable_attribute.verification_type_info[] map) { 638 print(name + " = ["); 639 for (int i = 0; i < map.length; i++) { 640 StackMapTable_attribute.verification_type_info info = map[i]; 641 int tag = info.tag; 642 switch (tag) { 643 case StackMapTable_attribute.verification_type_info.ITEM_Object: 644 print(" "); 645 constantWriter.write(((StackMapTable_attribute.Object_variable_info) info).cpool_index); 646 break; 647 case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized: 648 print(" " + mapTypeName(tag)); 649 print(" " + ((StackMapTable_attribute.Uninitialized_variable_info) info).offset); 650 break; 651 default: 652 print(" " + mapTypeName(tag)); 653 } 654 print(i == (map.length - 1) ? " " : ","); 655 } 656 println("]"); 657 } 658 659 String mapTypeName(int tag) { 660 switch (tag) { 661 case StackMapTable_attribute.verification_type_info.ITEM_Top: 662 return "top"; 663 664 case StackMapTable_attribute.verification_type_info.ITEM_Integer: 665 return "int"; 666 667 case StackMapTable_attribute.verification_type_info.ITEM_Float: 668 return "float"; 669 670 case StackMapTable_attribute.verification_type_info.ITEM_Long: 671 return "long"; 672 673 case StackMapTable_attribute.verification_type_info.ITEM_Double: 674 return "double"; 675 676 case StackMapTable_attribute.verification_type_info.ITEM_Null: 677 return "null"; 678 679 case StackMapTable_attribute.verification_type_info.ITEM_UninitializedThis: 680 return "this"; 681 682 case StackMapTable_attribute.verification_type_info.ITEM_Object: 683 return "CP"; 684 685 case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized: 686 return "uninitialized"; 687 688 default: 689 report("unrecognized verification_type_info tag: " + tag); 690 return "[tag:" + tag + "]"; 691 } 692 } 693 } 694 695 public Void visitSynthetic(Synthetic_attribute attr, Void ignore) { 696 println("Synthetic: true"); 697 return null; 698 } 699 700 static String getJavaName(String name) { 701 return name.replace('/', '.'); 702 } 703 704 String toHex(byte b, int w) { 705 if (options.compat) // BUG 6622260: javap prints negative bytes incorrectly in hex 706 return toHex((int) b, w); 707 else 708 return toHex(b & 0xff, w); 709 } 710 711 static String toHex(int i) { 712 return Integer.toString(i, 16).toUpperCase(); 713 } 714 715 static String toHex(int i, int w) { 716 String s = Integer.toHexString(i).toUpperCase(); 717 while (s.length() < w) 718 s = "0" + s; 719 return s.toUpperCase(); 720 } 721 722 private AnnotationWriter annotationWriter; 723 private CodeWriter codeWriter; 724 private ConstantWriter constantWriter; 725 private Options options; 726 727 private ConstantPool constant_pool; 728 private Object owner; 729 }