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

Wed, 23 Sep 2009 19:15:04 -0700

author
jjg
date
Wed, 23 Sep 2009 19:15:04 -0700
changeset 416
c287d51c57da
parent 355
961dc3acdb06
child 437
a509a22f9845
permissions
-rw-r--r--

6572945: javah should be written as an annotation processor, not a doclet
Reviewed-by: darcy

     1 /*
     2  * Copyright 2007-2008 Sun Microsystems, Inc.  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.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any 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 API supported by Sun Microsystems.  If
    44  *  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         instr.accept(instructionPrinter, null);
   122         println();
   123     }
   124     // where
   125     Instruction.KindVisitor<Void,Void> instructionPrinter =
   126             new Instruction.KindVisitor<Void,Void>() {
   128         public Void visitNoOperands(Instruction instr, Void p) {
   129             return null;
   130         }
   132         public Void visitArrayType(Instruction instr, TypeKind kind, Void p) {
   133             print(" " + kind.name);
   134             return null;
   135         }
   137         public Void visitBranch(Instruction instr, int offset, Void p) {
   138             print((instr.getPC() + offset));
   139             return null;
   140         }
   142         public Void visitConstantPoolRef(Instruction instr, int index, Void p) {
   143             print("#" + index);
   144             tab();
   145             print("// ");
   146             printConstant(index);
   147             return null;
   148         }
   150         public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Void p) {
   151             print("#" + index + ",  " + value);
   152             tab();
   153             print("// ");
   154             printConstant(index);
   155             return null;
   156         }
   158         public Void visitLocal(Instruction instr, int index, Void p) {
   159             print(index);
   160             return null;
   161         }
   163         public Void visitLocalAndValue(Instruction instr, int index, int value, Void p) {
   164             print(index + ", " + value);
   165             return null;
   166         }
   168         public Void visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets) {
   169             int pc = instr.getPC();
   170             print("{ // " + npairs);
   171             indent(+1);
   172             for (int i = 0; i < npairs; i++) {
   173                 print("\n" + matches[i] + ": " + (pc + offsets[i]));
   174             }
   175             print("\ndefault: " + (pc + default_) + " }");
   176             indent(-1);
   177             return null;
   178         }
   180         public Void visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets) {
   181             int pc = instr.getPC();
   182             print("{ //" + low + " to " + high);
   183             indent(+1);
   184             for (int i = 0; i < offsets.length; i++) {
   185                 print("\n" + (low + i) + ": " + (pc + offsets[i]));
   186             }
   187             print("\ndefault: " + (pc + default_) + " }");
   188             indent(-1);
   189             return null;
   190         }
   192         public Void visitValue(Instruction instr, int value, Void p) {
   193             print(value);
   194             return null;
   195         }
   197         public Void visitUnknown(Instruction instr, Void p) {
   198             return null;
   199         }
   200     };
   203     public void writeExceptionTable(Code_attribute attr) {
   204         if (attr.exception_table_langth > 0) {
   205             println("Exception table:");
   206             indent(+1);
   207             println(" from    to  target type");
   208             for (int i = 0; i < attr.exception_table.length; i++) {
   209                 Code_attribute.Exception_data handler = attr.exception_table[i];
   210                 print(String.format(" %5d %5d %5d",
   211                         handler.start_pc, handler.end_pc, handler.handler_pc));
   212                 print("   ");
   213                 int catch_type = handler.catch_type;
   214                 if (catch_type == 0) {
   215                     println("any");
   216                 } else {
   217                     print("Class ");
   218                     println(constantWriter.stringValue(catch_type));
   219                 }
   220             }
   221             indent(-1);
   222         }
   224     }
   226     private void printConstant(int index) {
   227         constantWriter.write(index);
   228     }
   230     private List<InstructionDetailWriter> getDetailWriters(Code_attribute attr) {
   231         List<InstructionDetailWriter> detailWriters =
   232                 new ArrayList<InstructionDetailWriter>();
   233         if (options.details.contains(InstructionDetailWriter.Kind.SOURCE)) {
   234             sourceWriter.reset(classWriter.getClassFile(), attr);
   235             detailWriters.add(sourceWriter);
   236         }
   238         if (options.details.contains(InstructionDetailWriter.Kind.LOCAL_VARS)) {
   239             localVariableTableWriter.reset(attr);
   240             detailWriters.add(localVariableTableWriter);
   241         }
   243         if (options.details.contains(InstructionDetailWriter.Kind.LOCAL_VAR_TYPES)) {
   244             localVariableTypeTableWriter.reset(attr);
   245             detailWriters.add(localVariableTypeTableWriter);
   246         }
   248         if (options.details.contains(InstructionDetailWriter.Kind.STACKMAPS)) {
   249             stackMapWriter.reset(attr);
   250             stackMapWriter.writeInitialDetails();
   251             detailWriters.add(stackMapWriter);
   252         }
   254         if (options.details.contains(InstructionDetailWriter.Kind.TRY_BLOCKS)) {
   255             tryBlockWriter.reset(attr);
   256             detailWriters.add(tryBlockWriter);
   257         }
   259         if (options.details.contains(InstructionDetailWriter.Kind.TYPE_ANNOS)) {
   260             typeAnnotationWriter.reset(attr);
   261             detailWriters.add(typeAnnotationWriter);
   262         }
   264         return detailWriters;
   265     }
   267     private AttributeWriter attrWriter;
   268     private ClassWriter classWriter;
   269     private ConstantWriter constantWriter;
   270     private LocalVariableTableWriter localVariableTableWriter;
   271     private LocalVariableTypeTableWriter localVariableTypeTableWriter;
   272     private TypeAnnotationWriter typeAnnotationWriter;
   273     private SourceWriter sourceWriter;
   274     private StackMapWriter stackMapWriter;
   275     private TryBlockWriter tryBlockWriter;
   276     private Options options;
   277 }

mercurial