< prev index next >

src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java

Print this page

 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.lang.classfile.Annotation;
 29 import java.lang.classfile.Attribute;
 30 import java.lang.classfile.Attributes;
 31 import java.lang.classfile.Signature;
 32 import java.lang.classfile.TypeAnnotation;
 33 import java.lang.classfile.attribute.*;
 34 import java.lang.classfile.constantpool.ModuleEntry;

 35 import java.lang.classfile.constantpool.PoolEntry;
 36 import java.lang.classfile.constantpool.Utf8Entry;
 37 import java.lang.reflect.AccessFlag;
 38 import java.lang.reflect.ClassFileFormatVersion;
 39 import java.lang.reflect.Modifier;
 40 import java.nio.charset.StandardCharsets;
 41 import java.util.List;
 42 import java.util.Locale;
 43 
 44 import static java.lang.classfile.ClassFile.ACC_MANDATED;
 45 import static java.lang.classfile.ClassFile.ACC_SYNTHETIC;
 46 import static java.lang.classfile.attribute.StackMapFrameInfo.*;
 47 import static java.lang.classfile.instruction.CharacterRange.*;
 48 



 49 /*
 50  *  A writer for writing Attributes as text.
 51  *
 52  *  <p><b>This is NOT part of any supported API.
 53  *  If you write code that depends on this, you do so at your own risk.
 54  *  This code and its internal interfaces are subject to change or
 55  *  deletion without notice.</b>
 56  */
 57 public class AttributeWriter extends BasicWriter {
 58 
 59     public static AttributeWriter instance(Context context) {
 60         AttributeWriter instance = context.get(AttributeWriter.class);
 61         if (instance == null)
 62             instance = new AttributeWriter(context);
 63         return instance;
 64     }
 65 
 66     protected AttributeWriter(Context context) {
 67         super(context);
 68         context.put(AttributeWriter.class, this);

 69         annotationWriter = AnnotationWriter.instance(context);
 70         codeWriter = CodeWriter.instance(context);
 71         constantWriter = ConstantWriter.instance(context);
 72         options = Options.instance(context);
 73     }
 74 
 75     public void write(List<Attribute<?>> attrs, ClassFileFormatVersion cffv) {
 76         write(attrs, null, cffv);
 77     }
 78 
 79     public void write(List<Attribute<?>> attrs, CodeAttribute lr, ClassFileFormatVersion cffv) {
 80         if (attrs != null) {
 81             for (var attr : attrs) try {
 82                 write(attr, lr, cffv);
 83             } catch (IllegalArgumentException e) {
 84                 report(e);
 85             }
 86         }
 87     }
 88 

201                 var exc = attr.exceptions();
202                 for (int i = 0; i < exc.size(); i++) {
203                     if (i > 0)
204                         print(", ");
205                     print(getJavaName(exc.get(i).asInternalName()));
206                 }
207                 println();
208                 indent(-1);
209             }
210             case InnerClassesAttribute attr -> {
211                 boolean first = true;
212                 for (var info : attr.classes()) {
213                     //access
214                     int access_flags = info.flagsMask();
215                     if (options.checkAccess(access_flags)) {
216                         if (first) {
217                             println("InnerClasses:");
218                             indent(+1);
219                             first = false;
220                         }
221                         for (var flag : maskToAccessFlagsReportUnknown(access_flags, AccessFlag.Location.INNER_CLASS, cffv)) {

222                             if (flag.sourceModifier() && (flag != AccessFlag.ABSTRACT
223                                     || !info.has(AccessFlag.INTERFACE))) {
224                                 print(Modifier.toString(flag.mask()) + " ");
225                             }
226                         }
227                         if (info.innerName().isPresent()) {
228                             print("#" + info.innerName().get().index() + "= ");
229                         }
230                         print("#" + info.innerClass().index());
231                         if (info.outerClass().isPresent()) {
232                             print(" of #" + info.outerClass().get().index());
233                         }
234                         print(";");
235                         tab();
236                         print("// ");
237                         if (info.innerName().isPresent()) {
238                             print(info.innerName().get().stringValue() + "=");
239                         }
240                         constantWriter.write(info.innerClass().index());
241                         if (info.outerClass().isPresent()) {
242                             print(" of ");
243                             constantWriter.write(info.outerClass().get().index());
244                         }
245                         println();






246                     }
247                 }
248                 if (!first)
249                     indent(-1);
250             }
251             case LineNumberTableAttribute attr -> {
252                 println("LineNumberTable:");
253                 indent(+1);
254                 for (var entry: attr.lineNumbers()) {
255                     println("line " + entry.lineNumber() + ": " + entry.startPc());
256                 }
257                 indent(-1);
258             }
259             case LocalVariableTableAttribute attr -> {
260                 println("LocalVariableTable:");
261                 indent(+1);
262                 println("Start  Length  Slot  Name   Signature");
263                 for (var entry : attr.localVariables()) {
264                     println(String.format("%5d %7d %5d %5s   %s",
265                             entry.startPc(), entry.length(), entry.slot(),

517             case RuntimeVisibleTypeAnnotationsAttribute attr ->
518                 printTypeAnnotations("RuntimeVisibleTypeAnnotations:",
519                         attr.annotations(), lr);
520             case RuntimeInvisibleTypeAnnotationsAttribute attr ->
521                 printTypeAnnotations("RuntimeInvisibleTypeAnnotations:",
522                         attr.annotations(), lr);
523             case RuntimeVisibleParameterAnnotationsAttribute attr ->
524                 printParameterAnnotations("RuntimeVisibleParameterAnnotations:",
525                         attr.parameterAnnotations());
526             case RuntimeInvisibleParameterAnnotationsAttribute attr ->
527                 printParameterAnnotations("RuntimeInvisibleParameterAnnotations:",
528                         attr.parameterAnnotations());
529             case PermittedSubclassesAttribute attr -> {
530                 println("PermittedSubclasses:");
531                 indent(+1);
532                 for (var sc : attr.permittedSubclasses()) {
533                     println(constantWriter.stringValue(sc));
534                 }
535                 indent(-1);
536             }








537             case SignatureAttribute attr -> {
538                 print("Signature: #" + attr.signature().index());
539                 tab();
540                 println("// " + attr.signature().stringValue());
541             }
542             case SourceDebugExtensionAttribute attr -> {
543                 println("SourceDebugExtension:");
544                 indent(+1);
545                 for (String s: new String(attr.contents(), StandardCharsets.UTF_8)
546                         .split("[\r\n]+")) {
547                     println(s);
548                 }
549                 indent(-1);
550             }
551             case SourceFileAttribute attr ->
552                 println("SourceFile: \"" + attr.sourceFile().stringValue() + "\"");
553             case SourceIDAttribute attr ->
554                 constantWriter.write(attr.sourceId().index());
555             case StackMapTableAttribute attr -> {
556                 var entries = attr.entries();
557                 println("StackMapTable: number_of_entries = " + entries.size());
558                 indent(+1);
559                 int lastOffset = -1;
560                 for (var frame : entries) {
561                     int frameType = frame.frameType();
562                     if (frameType < 64) {
563                         printHeader(frameType, "/* same */");
564                     } else if (frameType < 128) {
565                         printHeader(frameType, "/* same_locals_1_stack_item */");
566                         indent(+1);
567                         printMap("stack", frame.stack(), lr);
568                         indent(-1);
569                     } else {
570                         int offsetDelta = lr.labelToBci(frame.target()) - lastOffset - 1;
571                         switch (frameType) {



















572                             case 247 -> {
573                                 printHeader(frameType, "/* same_locals_1_stack_item_frame_extended */");
574                                 indent(+1);
575                                 println("offset_delta = " + offsetDelta);
576                                 printMap("stack", frame.stack(), lr);
577                                 indent(-1);
578                             }
579                             case 248, 249, 250 -> {
580                                 printHeader(frameType, "/* chop */");
581                                 indent(+1);
582                                 println("offset_delta = " + offsetDelta);
583                                 indent(-1);
584                             }
585                             case 251 -> {
586                                 printHeader(frameType, "/* same_frame_extended */");
587                                 indent(+1);
588                                 println("offset_delta = " + offsetDelta);
589                                 indent(-1);
590                             }
591                             case 252, 253, 254 -> {
592                                 printHeader(frameType, "/* append */");
593                                 indent(+1);
594                                 println("offset_delta = " + offsetDelta);
595                                 var locals = frame.locals();
596                                 printMap("locals", locals.subList(locals.size()
597                                         - frameType + 251, locals.size()), lr);
598                                 indent(-1);
599                             }
600                             case 255 -> {
601                                 printHeader(frameType, "/* full_frame */");
602                                 indent(+1);
603                                 println("offset_delta = " + offsetDelta);
604                                 printMap("locals", frame.locals(), lr);
605                                 printMap("stack", frame.stack(), lr);
606                                 indent(-1);
607                             }
608                         }
609                     }
610                     lastOffset = lr.labelToBci(frame.target());
611                 }
612                 indent(-1);
613             }
614             case SyntheticAttribute attr ->
615                 println("Synthetic: true");
616             default -> {}
617         }
618     }
619 
620     //ToDo move somewhere to Bytecode API
621     public static final int DO_NOT_RESOLVE_BY_DEFAULT   = 0x0001;

735 
736     static String toHex(int i) {
737         return Integer.toString(i, 16).toUpperCase(Locale.US);
738     }
739 
740     static String toHex(int i, int w) {
741         String s = Integer.toHexString(i).toUpperCase(Locale.US);
742         while (s.length() < w)
743             s = "0" + s;
744         return s;
745     }
746 
747     static String toHex(byte[] ba) {
748         StringBuilder sb = new StringBuilder(ba.length);
749         for (byte b: ba) {
750             sb.append(String.format("%02x", b & 0xff));
751         }
752         return sb.toString();
753     }
754 

755     private final AnnotationWriter annotationWriter;
756     private final CodeWriter codeWriter;
757     private final ConstantWriter constantWriter;
758     private final Options options;
759 }

 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.lang.classfile.Annotation;
 29 import java.lang.classfile.Attribute;
 30 import java.lang.classfile.Attributes;
 31 import java.lang.classfile.Signature;
 32 import java.lang.classfile.TypeAnnotation;
 33 import java.lang.classfile.attribute.*;
 34 import java.lang.classfile.constantpool.ModuleEntry;
 35 import java.lang.classfile.constantpool.NameAndTypeEntry;
 36 import java.lang.classfile.constantpool.PoolEntry;
 37 import java.lang.classfile.constantpool.Utf8Entry;
 38 import java.lang.reflect.AccessFlag;
 39 import java.lang.reflect.ClassFileFormatVersion;
 40 import java.lang.reflect.Modifier;
 41 import java.nio.charset.StandardCharsets;
 42 import java.util.List;
 43 import java.util.Locale;
 44 
 45 import static java.lang.classfile.ClassFile.ACC_MANDATED;
 46 import static java.lang.classfile.ClassFile.ACC_SYNTHETIC;
 47 import static java.lang.classfile.attribute.StackMapFrameInfo.*;
 48 import static java.lang.classfile.instruction.CharacterRange.*;
 49 
 50 import com.sun.tools.javac.util.Assert;
 51 import com.sun.tools.javac.util.StringUtils;
 52 
 53 /*
 54  *  A writer for writing Attributes as text.
 55  *
 56  *  <p><b>This is NOT part of any supported API.
 57  *  If you write code that depends on this, you do so at your own risk.
 58  *  This code and its internal interfaces are subject to change or
 59  *  deletion without notice.</b>
 60  */
 61 public class AttributeWriter extends BasicWriter {
 62 
 63     public static AttributeWriter instance(Context context) {
 64         AttributeWriter instance = context.get(AttributeWriter.class);
 65         if (instance == null)
 66             instance = new AttributeWriter(context);
 67         return instance;
 68     }
 69 
 70     protected AttributeWriter(Context context) {
 71         super(context);
 72         context.put(AttributeWriter.class, this);
 73         classWriter = ClassWriter.instance(context);
 74         annotationWriter = AnnotationWriter.instance(context);
 75         codeWriter = CodeWriter.instance(context);
 76         constantWriter = ConstantWriter.instance(context);
 77         options = Options.instance(context);
 78     }
 79 
 80     public void write(List<Attribute<?>> attrs, ClassFileFormatVersion cffv) {
 81         write(attrs, null, cffv);
 82     }
 83 
 84     public void write(List<Attribute<?>> attrs, CodeAttribute lr, ClassFileFormatVersion cffv) {
 85         if (attrs != null) {
 86             for (var attr : attrs) try {
 87                 write(attr, lr, cffv);
 88             } catch (IllegalArgumentException e) {
 89                 report(e);
 90             }
 91         }
 92     }
 93 

206                 var exc = attr.exceptions();
207                 for (int i = 0; i < exc.size(); i++) {
208                     if (i > 0)
209                         print(", ");
210                     print(getJavaName(exc.get(i).asInternalName()));
211                 }
212                 println();
213                 indent(-1);
214             }
215             case InnerClassesAttribute attr -> {
216                 boolean first = true;
217                 for (var info : attr.classes()) {
218                     //access
219                     int access_flags = info.flagsMask();
220                     if (options.checkAccess(access_flags)) {
221                         if (first) {
222                             println("InnerClasses:");
223                             indent(+1);
224                             first = false;
225                         }
226                         var flagSet = maskToAccessFlagsReportUnknown(access_flags, AccessFlag.Location.INNER_CLASS, cffv);
227                         for (var flag : flagSet) {
228                             if (flag.sourceModifier() && (flag != AccessFlag.ABSTRACT
229                                     || !info.has(AccessFlag.INTERFACE))) {
230                                 print(Modifier.toString(flag.mask()) + " ");
231                             }
232                         }
233                         if (info.innerName().isPresent()) {
234                             print("#" + info.innerName().get().index() + "= ");
235                         }
236                         print("#" + info.innerClass().index());
237                         if (info.outerClass().isPresent()) {
238                             print(" of #" + info.outerClass().get().index());
239                         }
240                         print(";");
241                         tab();
242                         print("// ");
243                         if (info.innerName().isPresent()) {
244                             print(info.innerName().get().stringValue() + "=");
245                         }
246                         constantWriter.write(info.innerClass().index());
247                         if (info.outerClass().isPresent()) {
248                             print(" of ");
249                             constantWriter.write(info.outerClass().get().index());
250                         }
251                         println();
252                         if (options.verbose) {
253                             indent(1);
254                             classWriter.writeList(String.format("flags: (0x%04x) ", access_flags),
255                                     flagSet, "\n");
256                             indent(-1);
257                         }
258                     }
259                 }
260                 if (!first)
261                     indent(-1);
262             }
263             case LineNumberTableAttribute attr -> {
264                 println("LineNumberTable:");
265                 indent(+1);
266                 for (var entry: attr.lineNumbers()) {
267                     println("line " + entry.lineNumber() + ": " + entry.startPc());
268                 }
269                 indent(-1);
270             }
271             case LocalVariableTableAttribute attr -> {
272                 println("LocalVariableTable:");
273                 indent(+1);
274                 println("Start  Length  Slot  Name   Signature");
275                 for (var entry : attr.localVariables()) {
276                     println(String.format("%5d %7d %5d %5s   %s",
277                             entry.startPc(), entry.length(), entry.slot(),

529             case RuntimeVisibleTypeAnnotationsAttribute attr ->
530                 printTypeAnnotations("RuntimeVisibleTypeAnnotations:",
531                         attr.annotations(), lr);
532             case RuntimeInvisibleTypeAnnotationsAttribute attr ->
533                 printTypeAnnotations("RuntimeInvisibleTypeAnnotations:",
534                         attr.annotations(), lr);
535             case RuntimeVisibleParameterAnnotationsAttribute attr ->
536                 printParameterAnnotations("RuntimeVisibleParameterAnnotations:",
537                         attr.parameterAnnotations());
538             case RuntimeInvisibleParameterAnnotationsAttribute attr ->
539                 printParameterAnnotations("RuntimeInvisibleParameterAnnotations:",
540                         attr.parameterAnnotations());
541             case PermittedSubclassesAttribute attr -> {
542                 println("PermittedSubclasses:");
543                 indent(+1);
544                 for (var sc : attr.permittedSubclasses()) {
545                     println(constantWriter.stringValue(sc));
546                 }
547                 indent(-1);
548             }
549             case LoadableDescriptorsAttribute attr -> {
550                 println("LoadableDescriptors:");
551                 indent(+1);
552                 for (var sc : attr.loadableDescriptors()) {
553                     println(constantWriter.stringValue(sc));
554                 }
555                 indent(-1);
556             }
557             case SignatureAttribute attr -> {
558                 print("Signature: #" + attr.signature().index());
559                 tab();
560                 println("// " + attr.signature().stringValue());
561             }
562             case SourceDebugExtensionAttribute attr -> {
563                 println("SourceDebugExtension:");
564                 indent(+1);
565                 for (String s: new String(attr.contents(), StandardCharsets.UTF_8)
566                         .split("[\r\n]+")) {
567                     println(s);
568                 }
569                 indent(-1);
570             }
571             case SourceFileAttribute attr ->
572                 println("SourceFile: \"" + attr.sourceFile().stringValue() + "\"");
573             case SourceIDAttribute attr ->
574                 constantWriter.write(attr.sourceId().index());
575             case StackMapTableAttribute attr -> {
576                 var entries = attr.entries();
577                 println("StackMapTable: number_of_entries = " + entries.size());
578                 indent(+1);
579                 int lastOffset = -1;
580                 for (var frame : entries) {
581                     int frameType = frame.frameType();
582                     if (frameType < 64) {
583                         printHeader(frameType, "/* same */");
584                     } else if (frameType < 128) {
585                         printHeader(frameType, "/* same_locals_1_stack_item */");
586                         indent(+1);
587                         printMap("stack", frame.stack(), lr);
588                         indent(-1);
589                     } else {
590                         int offsetDelta = lr.labelToBci(frame.target()) - lastOffset - 1;
591                         switch (frameType) {
592                             case 246 -> {
593                                 printHeader(frameType, "/* early_larval */");
594                                 indent(+1);
595                                 println("number of unset_fields = " + frame.unsetFields().size());
596                                     indent(+1);
597                                     for (NameAndTypeEntry field : frame.unsetFields()) {
598                                         print("unset_field = #");
599                                         constantWriter.write(field.index());
600                                         println();
601                                     }
602                                     // temporary: print the nested contents of early larval
603                                     indent(+1);
604                                     println("offset_delta = " + offsetDelta);
605                                     printMap("locals", frame.locals(), lr);
606                                     printMap("stack", frame.stack(), lr);
607                                     indent(-1);
608                                     indent(-1);
609                                 indent(-1);
610                             }
611                             case 247 -> {
612                                 printHeader(frameType, "/* same_locals_1_stack_item_entry_extended */");
613                                 indent(+1);
614                                 println("offset_delta = " + offsetDelta);
615                                 printMap("stack", frame.stack(), lr);
616                                 indent(-1);
617                             }
618                             case 248, 249, 250 -> {
619                                 printHeader(frameType, "/* chop */");
620                                 indent(+1);
621                                 println("offset_delta = " + offsetDelta);
622                                 indent(-1);
623                             }
624                             case 251 -> {
625                                 printHeader(frameType, "/* same_entry_extended */");
626                                 indent(+1);
627                                 println("offset_delta = " + offsetDelta);
628                                 indent(-1);
629                             }
630                             case 252, 253, 254 -> {
631                                 printHeader(frameType, "/* append */");
632                                 indent(+1);
633                                 println("offset_delta = " + offsetDelta);
634                                 var locals = frame.locals();
635                                 printMap("locals", locals.subList(locals.size()
636                                         - frameType + 251, locals.size()), lr);
637                                 indent(-1);
638                             }
639                             case 255 -> {
640                                 printHeader(frameType, "/* full_entry */");
641                                 indent(+1);
642                                 println("offset_delta = " + offsetDelta);
643                                 printMap("locals", frame.locals(), lr);
644                                 printMap("stack", frame.stack(), lr);
645                                 indent(-1);
646                             }
647                         }
648                     }
649                     lastOffset = lr.labelToBci(frame.target());
650                 }
651                 indent(-1);
652             }
653             case SyntheticAttribute attr ->
654                 println("Synthetic: true");
655             default -> {}
656         }
657     }
658 
659     //ToDo move somewhere to Bytecode API
660     public static final int DO_NOT_RESOLVE_BY_DEFAULT   = 0x0001;

774 
775     static String toHex(int i) {
776         return Integer.toString(i, 16).toUpperCase(Locale.US);
777     }
778 
779     static String toHex(int i, int w) {
780         String s = Integer.toHexString(i).toUpperCase(Locale.US);
781         while (s.length() < w)
782             s = "0" + s;
783         return s;
784     }
785 
786     static String toHex(byte[] ba) {
787         StringBuilder sb = new StringBuilder(ba.length);
788         for (byte b: ba) {
789             sb.append(String.format("%02x", b & 0xff));
790         }
791         return sb.toString();
792     }
793 
794     private final ClassWriter classWriter;
795     private final AnnotationWriter annotationWriter;
796     private final CodeWriter codeWriter;
797     private final ConstantWriter constantWriter;
798     private final Options options;
799 }
< prev index next >