src/share/classes/com/sun/tools/javap/CodeWriter.java

Tue, 28 Dec 2010 15:54:52 -0800

author
ohair
date
Tue, 28 Dec 2010 15:54:52 -0800
changeset 798
4868a36f6fd8
parent 660
ae3acbf63943
child 815
d17f37522154
permissions
-rw-r--r--

6962318: Update copyright year
Reviewed-by: xdono

     1 /*
     2  * Copyright (c) 2007, 2010, 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  */
    26 package com.sun.tools.javap;
    28 import java.util.ArrayList;
    29 import java.util.List;
    31 import com.sun.tools.classfile.AccessFlags;
    32 import com.sun.tools.classfile.Code_attribute;
    33 import com.sun.tools.classfile.ConstantPool;
    34 import com.sun.tools.classfile.ConstantPoolException;
    35 import com.sun.tools.classfile.DescriptorException;
    36 import com.sun.tools.classfile.Instruction;
    37 import com.sun.tools.classfile.Instruction.TypeKind;
    38 import com.sun.tools.classfile.Method;
    40 /*
    41  *  Write the contents of a Code attribute.
    42  *
    43  *  <p><b>This is NOT part of any supported API.
    44  *  If you write code that depends on this, you do so at your own risk.
    45  *  This code and its internal interfaces are subject to change or
    46  *  deletion without notice.</b>
    47  */
    48 class CodeWriter extends BasicWriter {
    49     static CodeWriter instance(Context context) {
    50         CodeWriter instance = context.get(CodeWriter.class);
    51         if (instance == null)
    52             instance = new CodeWriter(context);
    53         return instance;
    54     }
    56     protected CodeWriter(Context context) {
    57         super(context);
    58         context.put(CodeWriter.class, this);
    59         attrWriter = AttributeWriter.instance(context);
    60         classWriter = ClassWriter.instance(context);
    61         constantWriter = ConstantWriter.instance(context);
    62         sourceWriter = SourceWriter.instance(context);
    63         tryBlockWriter = TryBlockWriter.instance(context);
    64         stackMapWriter = StackMapWriter.instance(context);
    65         localVariableTableWriter = LocalVariableTableWriter.instance(context);
    66         localVariableTypeTableWriter = LocalVariableTypeTableWriter.instance(context);
    67         typeAnnotationWriter = TypeAnnotationWriter.instance(context);
    68         options = Options.instance(context);
    69     }
    71     void write(Code_attribute attr, ConstantPool constant_pool) {
    72         println("Code:");
    73         indent(+1);
    74         writeVerboseHeader(attr, constant_pool);
    75         writeInstrs(attr);
    76         writeExceptionTable(attr);
    77         attrWriter.write(attr, attr.attributes, constant_pool);
    78         indent(-1);
    79     }
    81     public void writeVerboseHeader(Code_attribute attr, ConstantPool constant_pool) {
    82         Method method = classWriter.getMethod();
    83         String argCount;
    84         try {
    85             int n = method.descriptor.getParameterCount(constant_pool);
    86             if (!method.access_flags.is(AccessFlags.ACC_STATIC))
    87                 ++n;  // for 'this'
    88             argCount = Integer.toString(n);
    89         } catch (ConstantPoolException e) {
    90             argCount = report(e);
    91         } catch (DescriptorException e) {
    92             argCount = report(e);
    93         }
    95         println("stack=" + attr.max_stack +
    96                 ", locals=" + attr.max_locals +
    97                 ", args_size=" + argCount);
    99     }
   101     public void writeInstrs(Code_attribute attr) {
   102         List<InstructionDetailWriter> detailWriters = getDetailWriters(attr);
   104         for (Instruction instr: attr.getInstructions()) {
   105             try {
   106                 for (InstructionDetailWriter w: detailWriters)
   107                     w.writeDetails(instr);
   108                 writeInstr(instr);
   109             } catch (ArrayIndexOutOfBoundsException e) {
   110                 println(report("error at or after byte " + instr.getPC()));
   111                 break;
   112             }
   113         }
   115         for (InstructionDetailWriter w: detailWriters)
   116             w.flush();
   117     }
   119     public void writeInstr(Instruction instr) {
   120         print(String.format("%4d: %-13s ", instr.getPC(), instr.getMnemonic()));
   121         // compute the number of indentations for the body of multi-line instructions
   122         // This is 6 (the width of "%4d: "), divided by the width of each indentation level,
   123         // and rounded up to the next integer.
   124         int indentWidth = options.indentWidth;
   125         int indent = (6 + indentWidth - 1) / indentWidth;
   126         instr.accept(instructionPrinter, indent);
   127         println();
   128     }
   129     // where
   130     Instruction.KindVisitor<Void,Integer> instructionPrinter =
   131             new Instruction.KindVisitor<Void,Integer>() {
   133         public Void visitNoOperands(Instruction instr, Integer indent) {
   134             return null;
   135         }
   137         public Void visitArrayType(Instruction instr, TypeKind kind, Integer indent) {
   138             print(" " + kind.name);
   139             return null;
   140         }
   142         public Void visitBranch(Instruction instr, int offset, Integer indent) {
   143             print((instr.getPC() + offset));
   144             return null;
   145         }
   147         public Void visitConstantPoolRef(Instruction instr, int index, Integer indent) {
   148             print("#" + index);
   149             tab();
   150             print("// ");
   151             printConstant(index);
   152             return null;
   153         }
   155         public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Integer indent) {
   156             print("#" + index + ",  " + value);
   157             tab();
   158             print("// ");
   159             printConstant(index);
   160             return null;
   161         }
   163         public Void visitLocal(Instruction instr, int index, Integer indent) {
   164             print(index);
   165             return null;
   166         }
   168         public Void visitLocalAndValue(Instruction instr, int index, int value, Integer indent) {
   169             print(index + ", " + value);
   170             return null;
   171         }
   173         public Void visitLookupSwitch(Instruction instr,
   174                 int default_, int npairs, int[] matches, int[] offsets, Integer indent) {
   175             int pc = instr.getPC();
   176             print("{ // " + npairs);
   177             indent(indent);
   178             for (int i = 0; i < npairs; i++) {
   179                 print(String.format("%n%12d: %d", matches[i], (pc + offsets[i])));
   180             }
   181             print("\n     default: " + (pc + default_) + "\n}");
   182             indent(-indent);
   183             return null;
   184         }
   186         public Void visitTableSwitch(Instruction instr,
   187                 int default_, int low, int high, int[] offsets, Integer indent) {
   188             int pc = instr.getPC();
   189             print("{ // " + low + " to " + high);
   190             indent(indent);
   191             for (int i = 0; i < offsets.length; i++) {
   192                 print(String.format("%n%12d: %d", (low + i), (pc + offsets[i])));
   193             }
   194             print("\n     default: " + (pc + default_) + "\n}");
   195             indent(-indent);
   196             return null;
   197         }
   199         public Void visitValue(Instruction instr, int value, Integer indent) {
   200             print(value);
   201             return null;
   202         }
   204         public Void visitUnknown(Instruction instr, Integer indent) {
   205             return null;
   206         }
   207     };
   210     public void writeExceptionTable(Code_attribute attr) {
   211         if (attr.exception_table_langth > 0) {
   212             println("Exception table:");
   213             indent(+1);
   214             println(" from    to  target type");
   215             for (int i = 0; i < attr.exception_table.length; i++) {
   216                 Code_attribute.Exception_data handler = attr.exception_table[i];
   217                 print(String.format(" %5d %5d %5d",
   218                         handler.start_pc, handler.end_pc, handler.handler_pc));
   219                 print("   ");
   220                 int catch_type = handler.catch_type;
   221                 if (catch_type == 0) {
   222                     println("any");
   223                 } else {
   224                     print("Class ");
   225                     println(constantWriter.stringValue(catch_type));
   226                 }
   227             }
   228             indent(-1);
   229         }
   231     }
   233     private void printConstant(int index) {
   234         constantWriter.write(index);
   235     }
   237     private List<InstructionDetailWriter> getDetailWriters(Code_attribute attr) {
   238         List<InstructionDetailWriter> detailWriters =
   239                 new ArrayList<InstructionDetailWriter>();
   240         if (options.details.contains(InstructionDetailWriter.Kind.SOURCE)) {
   241             sourceWriter.reset(classWriter.getClassFile(), attr);
   242             if (sourceWriter.hasSource())
   243                 detailWriters.add(sourceWriter);
   244             else
   245                 println("(Source code not available)");
   246         }
   248         if (options.details.contains(InstructionDetailWriter.Kind.LOCAL_VARS)) {
   249             localVariableTableWriter.reset(attr);
   250             detailWriters.add(localVariableTableWriter);
   251         }
   253         if (options.details.contains(InstructionDetailWriter.Kind.LOCAL_VAR_TYPES)) {
   254             localVariableTypeTableWriter.reset(attr);
   255             detailWriters.add(localVariableTypeTableWriter);
   256         }
   258         if (options.details.contains(InstructionDetailWriter.Kind.STACKMAPS)) {
   259             stackMapWriter.reset(attr);
   260             stackMapWriter.writeInitialDetails();
   261             detailWriters.add(stackMapWriter);
   262         }
   264         if (options.details.contains(InstructionDetailWriter.Kind.TRY_BLOCKS)) {
   265             tryBlockWriter.reset(attr);
   266             detailWriters.add(tryBlockWriter);
   267         }
   269         if (options.details.contains(InstructionDetailWriter.Kind.TYPE_ANNOS)) {
   270             typeAnnotationWriter.reset(attr);
   271             detailWriters.add(typeAnnotationWriter);
   272         }
   274         return detailWriters;
   275     }
   277     private AttributeWriter attrWriter;
   278     private ClassWriter classWriter;
   279     private ConstantWriter constantWriter;
   280     private LocalVariableTableWriter localVariableTableWriter;
   281     private LocalVariableTypeTableWriter localVariableTypeTableWriter;
   282     private TypeAnnotationWriter typeAnnotationWriter;
   283     private SourceWriter sourceWriter;
   284     private StackMapWriter stackMapWriter;
   285     private TryBlockWriter tryBlockWriter;
   286     private Options options;
   287 }

mercurial