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 flagstr = 404 (0 != (entry.flags & ACC_FINAL) ? " final" : "") + 405 (0 != (entry.flags & ACC_SYNTHETIC) ? " synthetic" : ""); 406 println(String.format(format, 407 constantWriter.stringValue(entry.name_index), 408 flagstr)); 409 } 410 indent(-1); 411 return null; 412 } 413 414 public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, Void ignore) { 415 println("RuntimeVisibleAnnotations:"); 416 indent(+1); 417 for (int i = 0; i < attr.annotations.length; i++) { 418 print(i + ": "); 419 annotationWriter.write(attr.annotations[i]); 420 println(); 421 } 422 indent(-1); 423 return null; 424 } 425 426 public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, Void ignore) { 427 println("RuntimeInvisibleAnnotations:"); 428 indent(+1); 429 for (int i = 0; i < attr.annotations.length; i++) { 430 print(i + ": "); 431 annotationWriter.write(attr.annotations[i]); 432 println(); 433 } 434 indent(-1); 435 return null; 436 } 437 438 public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, Void ignore) { 439 println("RuntimeVisibleTypeAnnotations:"); 440 indent(+1); 441 for (int i = 0; i < attr.annotations.length; i++) { 442 print(i + ": "); 443 annotationWriter.write(attr.annotations[i]); 444 println(); 445 } 446 indent(-1); 447 return null; 448 } 449 450 public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, Void ignore) { 451 println("RuntimeInvisibleTypeAnnotations:"); 452 indent(+1); 453 for (int i = 0; i < attr.annotations.length; i++) { 454 print(i + ": "); 455 annotationWriter.write(attr.annotations[i]); 456 println(); 457 } 458 indent(-1); 459 return null; 460 } 461 462 public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) { 463 println("RuntimeVisibleParameterAnnotations:"); 464 indent(+1); 465 for (int param = 0; param < attr.parameter_annotations.length; param++) { 466 println("parameter " + param + ": "); 467 indent(+1); 468 for (int i = 0; i < attr.parameter_annotations[param].length; i++) { 469 print(i + ": "); 470 annotationWriter.write(attr.parameter_annotations[param][i]); 471 println(); 472 } 473 indent(-1); 474 } 475 indent(-1); 476 return null; 477 } 478 479 public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, Void ignore) { 480 println("RuntimeInvisibleParameterAnnotations:"); 481 indent(+1); 482 for (int param = 0; param < attr.parameter_annotations.length; param++) { 483 println(param + ": "); 484 indent(+1); 485 for (int i = 0; i < attr.parameter_annotations[param].length; i++) { 486 print(i + ": "); 487 annotationWriter.write(attr.parameter_annotations[param][i]); 488 println(); 489 } 490 indent(-1); 491 } 492 indent(-1); 493 return null; 494 } 495 496 public Void visitSignature(Signature_attribute attr, Void ignore) { 497 print("Signature: #" + attr.signature_index); 498 tab(); 499 println("// " + getSignature(attr)); 500 return null; 501 } 502 503 String getSignature(Signature_attribute info) { 504 try { 505 return info.getSignature(constant_pool); 506 } catch (ConstantPoolException e) { 507 return report(e); 508 } 509 } 510 511 public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, Void ignore) { 512 println("SourceDebugExtension: " + attr.getValue()); 513 return null; 514 } 515 516 public Void visitSourceFile(SourceFile_attribute attr, Void ignore) { 517 println("SourceFile: \"" + getSourceFile(attr) + "\""); 518 return null; 519 } 520 521 private String getSourceFile(SourceFile_attribute attr) { 522 try { 523 return attr.getSourceFile(constant_pool); 524 } catch (ConstantPoolException e) { 525 return report(e); 526 } 527 } 528 529 public Void visitSourceID(SourceID_attribute attr, Void ignore) { 530 constantWriter.write(attr.sourceID_index); 531 return null; 532 } 533 534 public Void visitStackMap(StackMap_attribute attr, Void ignore) { 535 println("StackMap: number_of_entries = " + attr.number_of_entries); 536 indent(+1); 537 StackMapTableWriter w = new StackMapTableWriter(); 538 for (StackMapTable_attribute.stack_map_frame entry : attr.entries) { 539 w.write(entry); 540 } 541 println(); 542 indent(-1); 543 return null; 544 } 545 546 public Void visitStackMapTable(StackMapTable_attribute attr, Void ignore) { 547 println("StackMapTable: number_of_entries = " + attr.number_of_entries); 548 indent(+1); 549 StackMapTableWriter w = new StackMapTableWriter(); 550 for (StackMapTable_attribute.stack_map_frame entry : attr.entries) { 551 w.write(entry); 552 } 553 println(); 554 indent(-1); 555 return null; 556 } 557 558 class StackMapTableWriter // also handles CLDC StackMap attributes 559 implements StackMapTable_attribute.stack_map_frame.Visitor<Void,Void> { 560 public void write(StackMapTable_attribute.stack_map_frame frame) { 561 frame.accept(this, null); 562 } 563 564 public Void visit_same_frame(StackMapTable_attribute.same_frame frame, Void p) { 565 printHeader(frame); 566 println(" /* same */"); 567 return null; 568 } 569 570 public Void visit_same_locals_1_stack_item_frame(StackMapTable_attribute.same_locals_1_stack_item_frame frame, Void p) { 571 printHeader(frame); 572 println(" /* same_locals_1_stack_item */"); 573 indent(+1); 574 printMap("stack", frame.stack); 575 indent(-1); 576 return null; 577 } 578 579 public Void visit_same_locals_1_stack_item_frame_extended(StackMapTable_attribute.same_locals_1_stack_item_frame_extended frame, Void p) { 580 printHeader(frame); 581 println(" /* same_locals_1_stack_item_frame_extended */"); 582 indent(+1); 583 println("offset_delta = " + frame.offset_delta); 584 printMap("stack", frame.stack); 585 indent(-1); 586 return null; 587 } 588 589 public Void visit_chop_frame(StackMapTable_attribute.chop_frame frame, Void p) { 590 printHeader(frame); 591 println(" /* chop */"); 592 indent(+1); 593 println("offset_delta = " + frame.offset_delta); 594 indent(-1); 595 return null; 596 } 597 598 public Void visit_same_frame_extended(StackMapTable_attribute.same_frame_extended frame, Void p) { 599 printHeader(frame); 600 println(" /* same_frame_extended */"); 601 indent(+1); 602 println("offset_delta = " + frame.offset_delta); 603 indent(-1); 604 return null; 605 } 606 607 public Void visit_append_frame(StackMapTable_attribute.append_frame frame, Void p) { 608 printHeader(frame); 609 println(" /* append */"); 610 println(" offset_delta = " + frame.offset_delta); 611 printMap("locals", frame.locals); 612 return null; 613 } 614 615 public Void visit_full_frame(StackMapTable_attribute.full_frame frame, Void p) { 616 printHeader(frame); 617 if (frame instanceof StackMap_attribute.stack_map_frame) { 618 indent(+1); 619 println(" offset = " + frame.offset_delta); 620 } else { 621 println(" /* full_frame */"); 622 indent(+1); 623 println("offset_delta = " + frame.offset_delta); 624 } 625 printMap("locals", frame.locals); 626 printMap("stack", frame.stack); 627 indent(-1); 628 return null; 629 } 630 631 void printHeader(StackMapTable_attribute.stack_map_frame frame) { 632 print(" frame_type = " + frame.frame_type); 633 } 634 635 void printMap(String name, StackMapTable_attribute.verification_type_info[] map) { 636 print(name + " = ["); 637 for (int i = 0; i < map.length; i++) { 638 StackMapTable_attribute.verification_type_info info = map[i]; 639 int tag = info.tag; 640 switch (tag) { 641 case StackMapTable_attribute.verification_type_info.ITEM_Object: 642 print(" "); 643 constantWriter.write(((StackMapTable_attribute.Object_variable_info) info).cpool_index); 644 break; 645 case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized: 646 print(" " + mapTypeName(tag)); 647 print(" " + ((StackMapTable_attribute.Uninitialized_variable_info) info).offset); 648 break; 649 default: 650 print(" " + mapTypeName(tag)); 651 } 652 print(i == (map.length - 1) ? " " : ","); 653 } 654 println("]"); 655 } 656 657 String mapTypeName(int tag) { 658 switch (tag) { 659 case StackMapTable_attribute.verification_type_info.ITEM_Top: 660 return "top"; 661 662 case StackMapTable_attribute.verification_type_info.ITEM_Integer: 663 return "int"; 664 665 case StackMapTable_attribute.verification_type_info.ITEM_Float: 666 return "float"; 667 668 case StackMapTable_attribute.verification_type_info.ITEM_Long: 669 return "long"; 670 671 case StackMapTable_attribute.verification_type_info.ITEM_Double: 672 return "double"; 673 674 case StackMapTable_attribute.verification_type_info.ITEM_Null: 675 return "null"; 676 677 case StackMapTable_attribute.verification_type_info.ITEM_UninitializedThis: 678 return "this"; 679 680 case StackMapTable_attribute.verification_type_info.ITEM_Object: 681 return "CP"; 682 683 case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized: 684 return "uninitialized"; 685 686 default: 687 report("unrecognized verification_type_info tag: " + tag); 688 return "[tag:" + tag + "]"; 689 } 690 } 691 } 692 693 public Void visitSynthetic(Synthetic_attribute attr, Void ignore) { 694 println("Synthetic: true"); 695 return null; 696 } 697 698 static String getJavaName(String name) { 699 return name.replace('/', '.'); 700 } 701 702 String toHex(byte b, int w) { 703 if (options.compat) // BUG 6622260: javap prints negative bytes incorrectly in hex 704 return toHex((int) b, w); 705 else 706 return toHex(b & 0xff, w); 707 } 708 709 static String toHex(int i) { 710 return Integer.toString(i, 16).toUpperCase(); 711 } 712 713 static String toHex(int i, int w) { 714 String s = Integer.toHexString(i).toUpperCase(); 715 while (s.length() < w) 716 s = "0" + s; 717 return s.toUpperCase(); 718 } 719 720 private AnnotationWriter annotationWriter; 721 private CodeWriter codeWriter; 722 private ConstantWriter constantWriter; 723 private Options options; 724 725 private ConstantPool constant_pool; 726 private Object owner; 727 }