javap/src/main/java/sun/tools/javap/JavapPrinter.java
author Jaroslav Tulach <jtulach@netbeans.org>
Fri, 09 Nov 2012 21:33:22 +0100
branchjavap
changeset 144 b06660b614db
child 145 525b0a571518
permissions -rw-r--r--
javap as of revision jdk6-4ab5d66aaf2b
jtulach@144
     1
/*
jtulach@144
     2
 * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
jtulach@144
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jtulach@144
     4
 *
jtulach@144
     5
 * This code is free software; you can redistribute it and/or modify it
jtulach@144
     6
 * under the terms of the GNU General Public License version 2 only, as
jtulach@144
     7
 * published by the Free Software Foundation.  Oracle designates this
jtulach@144
     8
 * particular file as subject to the "Classpath" exception as provided
jtulach@144
     9
 * by Oracle in the LICENSE file that accompanied this code.
jtulach@144
    10
 *
jtulach@144
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
jtulach@144
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jtulach@144
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
jtulach@144
    14
 * version 2 for more details (a copy is included in the LICENSE file that
jtulach@144
    15
 * accompanied this code).
jtulach@144
    16
 *
jtulach@144
    17
 * You should have received a copy of the GNU General Public License version
jtulach@144
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
jtulach@144
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jtulach@144
    20
 *
jtulach@144
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jtulach@144
    22
 * or visit www.oracle.com if you need additional information or have any
jtulach@144
    23
 * questions.
jtulach@144
    24
 */
jtulach@144
    25
jtulach@144
    26
jtulach@144
    27
package sun.tools.javap;
jtulach@144
    28
jtulach@144
    29
import java.util.*;
jtulach@144
    30
import java.io.*;
jtulach@144
    31
jtulach@144
    32
import static sun.tools.javap.RuntimeConstants.*;
jtulach@144
    33
jtulach@144
    34
/**
jtulach@144
    35
 * Program to print information about class files
jtulach@144
    36
 *
jtulach@144
    37
 * @author  Sucheta Dambalkar
jtulach@144
    38
 */
jtulach@144
    39
public class JavapPrinter {
jtulach@144
    40
    JavapEnvironment env;
jtulach@144
    41
    ClassData cls;
jtulach@144
    42
    byte[] code;
jtulach@144
    43
    String lP= "";
jtulach@144
    44
    PrintWriter out;
jtulach@144
    45
jtulach@144
    46
    public JavapPrinter(InputStream cname, PrintWriter out, JavapEnvironment env){
jtulach@144
    47
        this.out = out;
jtulach@144
    48
        this.cls =  new ClassData(cname);
jtulach@144
    49
        this.env = env;
jtulach@144
    50
    }
jtulach@144
    51
jtulach@144
    52
    /**
jtulach@144
    53
     *  Entry point to print class file information.
jtulach@144
    54
     */
jtulach@144
    55
    public void print(){
jtulach@144
    56
        printclassHeader();
jtulach@144
    57
        printfields();
jtulach@144
    58
        printMethods();
jtulach@144
    59
        printend();
jtulach@144
    60
    }
jtulach@144
    61
jtulach@144
    62
    /**
jtulach@144
    63
     * Print a description of the class (not members).
jtulach@144
    64
     */
jtulach@144
    65
    public void printclassHeader(){
jtulach@144
    66
        String srcName="";
jtulach@144
    67
        if ((srcName = cls.getSourceName()) != "null") // requires debug info
jtulach@144
    68
            out.println("Compiled from " + javaclassname(srcName));
jtulach@144
    69
jtulach@144
    70
        if(cls.isInterface())   {
jtulach@144
    71
            // The only useful access modifier of an interface is
jtulach@144
    72
            // public; interfaces are always marked as abstract and
jtulach@144
    73
            // cannot be final.
jtulach@144
    74
            out.print((cls.isPublic()?"public ":"") +
jtulach@144
    75
                      "interface "+ javaclassname(cls.getClassName()));
jtulach@144
    76
        }
jtulach@144
    77
        else if(cls.isClass()) {
jtulach@144
    78
            String []accflags =  cls.getAccess();
jtulach@144
    79
            printAccess(accflags);
jtulach@144
    80
            out.print("class "+ javaclassname(cls.getClassName()));
jtulach@144
    81
jtulach@144
    82
            if(cls.getSuperClassName() != null){
jtulach@144
    83
                out.print(" extends " + javaclassname(cls.getSuperClassName()));
jtulach@144
    84
            }
jtulach@144
    85
        }
jtulach@144
    86
jtulach@144
    87
        String []interfacelist =  cls.getSuperInterfaces();
jtulach@144
    88
        if(interfacelist.length > 0){
jtulach@144
    89
            if(cls.isClass()) {
jtulach@144
    90
                out.print(" implements ");
jtulach@144
    91
            }
jtulach@144
    92
            else if(cls.isInterface()){
jtulach@144
    93
                out.print(" extends ");
jtulach@144
    94
            }
jtulach@144
    95
jtulach@144
    96
            for(int j = 0; j < interfacelist.length; j++){
jtulach@144
    97
                out.print(javaclassname(interfacelist[j]));
jtulach@144
    98
jtulach@144
    99
                if((j+1) < interfacelist.length) {
jtulach@144
   100
                    out.print(",");
jtulach@144
   101
                }
jtulach@144
   102
            }
jtulach@144
   103
        }
jtulach@144
   104
jtulach@144
   105
        // Print class attribute information.
jtulach@144
   106
        if((env.showallAttr) || (env.showVerbose)){
jtulach@144
   107
            printClassAttributes();
jtulach@144
   108
        }
jtulach@144
   109
        // Print verbose output.
jtulach@144
   110
        if(env.showVerbose){
jtulach@144
   111
            printverbosecls();
jtulach@144
   112
        }
jtulach@144
   113
        out.println("{");
jtulach@144
   114
    }
jtulach@144
   115
jtulach@144
   116
    /**
jtulach@144
   117
     * Print verbose output.
jtulach@144
   118
     */
jtulach@144
   119
    public void printverbosecls(){
jtulach@144
   120
        out.println("  minor version: "+cls.getMinor_version());
jtulach@144
   121
        out.println("  major version: "+cls.getMajor_version());
jtulach@144
   122
        out.println("  Constant pool:");
jtulach@144
   123
        printcp();
jtulach@144
   124
        env.showallAttr = true;
jtulach@144
   125
    }
jtulach@144
   126
jtulach@144
   127
    /**
jtulach@144
   128
     * Print class attribute information.
jtulach@144
   129
     */
jtulach@144
   130
    public void printClassAttributes(){
jtulach@144
   131
        out.println();
jtulach@144
   132
        AttrData[] clsattrs = cls.getAttributes();
jtulach@144
   133
        for(int i = 0; i < clsattrs.length; i++){
jtulach@144
   134
            String clsattrname = clsattrs[i].getAttrName();
jtulach@144
   135
            if(clsattrname.equals("SourceFile")){
jtulach@144
   136
                out.println("  SourceFile: "+ cls.getSourceName());
jtulach@144
   137
            }else if(clsattrname.equals("InnerClasses")){
jtulach@144
   138
                printInnerClasses();
jtulach@144
   139
            }else {
jtulach@144
   140
                printAttrData(clsattrs[i]);
jtulach@144
   141
            }
jtulach@144
   142
        }
jtulach@144
   143
    }
jtulach@144
   144
jtulach@144
   145
    /**
jtulach@144
   146
     * Print the fields
jtulach@144
   147
     */
jtulach@144
   148
    public void printfields(){
jtulach@144
   149
        FieldData[] fields = cls.getFields();
jtulach@144
   150
        for(int f = 0; f < fields.length; f++){
jtulach@144
   151
            String[] accflags = fields[f].getAccess();
jtulach@144
   152
            if(checkAccess(accflags)){
jtulach@144
   153
                if(!(env. showLineAndLocal || env.showDisassembled || env.showVerbose
jtulach@144
   154
                     ||  env.showInternalSigs || env.showallAttr)){
jtulach@144
   155
                    out.print("    ");
jtulach@144
   156
                }
jtulach@144
   157
                printAccess(accflags);
jtulach@144
   158
                out.println(fields[f].getType()+" " +fields[f].getName()+";");
jtulach@144
   159
                if (env.showInternalSigs) {
jtulach@144
   160
                    out.println("  Signature: " + (fields[f].getInternalSig()));
jtulach@144
   161
                }
jtulach@144
   162
jtulach@144
   163
                // print field attribute information.
jtulach@144
   164
                if (env.showallAttr){
jtulach@144
   165
                    printFieldAttributes(fields[f]);
jtulach@144
   166
jtulach@144
   167
                }
jtulach@144
   168
                if((env.showDisassembled) || (env.showLineAndLocal)){
jtulach@144
   169
                    out.println();
jtulach@144
   170
                }
jtulach@144
   171
            }
jtulach@144
   172
        }
jtulach@144
   173
    }
jtulach@144
   174
jtulach@144
   175
jtulach@144
   176
    /* print field attribute information. */
jtulach@144
   177
    public void printFieldAttributes(FieldData field){
jtulach@144
   178
        Vector fieldattrs = field.getAttributes();
jtulach@144
   179
        for(int j = 0; j < fieldattrs.size(); j++){
jtulach@144
   180
            String fieldattrname = ((AttrData)fieldattrs.elementAt(j)).getAttrName();
jtulach@144
   181
            if(fieldattrname.equals("ConstantValue")){
jtulach@144
   182
                printConstantValue(field);
jtulach@144
   183
            }else if (fieldattrname.equals("Deprecated")){
jtulach@144
   184
                out.println("Deprecated: "+ field.isDeprecated());
jtulach@144
   185
            }else if (fieldattrname.equals("Synthetic")){
jtulach@144
   186
                out.println("  Synthetic: "+ field.isSynthetic());
jtulach@144
   187
            }else {
jtulach@144
   188
                printAttrData((AttrData)fieldattrs.elementAt(j));
jtulach@144
   189
            }
jtulach@144
   190
        }
jtulach@144
   191
        out.println();
jtulach@144
   192
    }
jtulach@144
   193
jtulach@144
   194
    /**
jtulach@144
   195
     * Print the methods
jtulach@144
   196
     */
jtulach@144
   197
    public void printMethods(){
jtulach@144
   198
        MethodData[] methods = cls.getMethods();
jtulach@144
   199
        for(int m = 0; m < methods.length; m++){
jtulach@144
   200
            String[] accflags = methods[m].getAccess();
jtulach@144
   201
            if(checkAccess(accflags)){
jtulach@144
   202
                if(!(env. showLineAndLocal || env.showDisassembled || env.showVerbose
jtulach@144
   203
                     ||  env.showInternalSigs || env.showallAttr)){
jtulach@144
   204
                    out.print("    ");
jtulach@144
   205
                }
jtulach@144
   206
                printMethodSignature(methods[m], accflags);
jtulach@144
   207
                printExceptions(methods[m]);
jtulach@144
   208
                out.println(";");
jtulach@144
   209
jtulach@144
   210
                // Print internal signature of method.
jtulach@144
   211
                if (env.showInternalSigs){
jtulach@144
   212
                    out.println("  Signature: " + (methods[m].getInternalSig()));
jtulach@144
   213
                }
jtulach@144
   214
jtulach@144
   215
                //Print disassembled code.
jtulach@144
   216
                if(env.showDisassembled && ! env.showallAttr) {
jtulach@144
   217
                    printcodeSequence(methods[m]);
jtulach@144
   218
                    printExceptionTable(methods[m]);
jtulach@144
   219
                    out.println();
jtulach@144
   220
                }
jtulach@144
   221
jtulach@144
   222
                // Print line and local variable attribute information.
jtulach@144
   223
                if (env.showLineAndLocal) {
jtulach@144
   224
                    printLineNumTable(methods[m]);
jtulach@144
   225
                    printLocVarTable(methods[m]);
jtulach@144
   226
                    out.println();
jtulach@144
   227
                }
jtulach@144
   228
jtulach@144
   229
                // Print  method attribute information.
jtulach@144
   230
                if (env.showallAttr){
jtulach@144
   231
                    printMethodAttributes(methods[m]);
jtulach@144
   232
                }
jtulach@144
   233
            }
jtulach@144
   234
        }
jtulach@144
   235
    }
jtulach@144
   236
jtulach@144
   237
    /**
jtulach@144
   238
     * Print method signature.
jtulach@144
   239
     */
jtulach@144
   240
    public void printMethodSignature(MethodData method, String[] accflags){
jtulach@144
   241
        printAccess(accflags);
jtulach@144
   242
jtulach@144
   243
        if((method.getName()).equals("<init>")){
jtulach@144
   244
            out.print(javaclassname(cls.getClassName()));
jtulach@144
   245
            out.print(method.getParameters());
jtulach@144
   246
        }else if((method.getName()).equals("<clinit>")){
jtulach@144
   247
            out.print("{}");
jtulach@144
   248
        }else{
jtulach@144
   249
            out.print(method.getReturnType()+" ");
jtulach@144
   250
            out.print(method.getName());
jtulach@144
   251
            out.print(method.getParameters());
jtulach@144
   252
        }
jtulach@144
   253
    }
jtulach@144
   254
jtulach@144
   255
    /**
jtulach@144
   256
     * print method attribute information.
jtulach@144
   257
     */
jtulach@144
   258
    public void printMethodAttributes(MethodData method){
jtulach@144
   259
        Vector methodattrs = method.getAttributes();
jtulach@144
   260
        Vector codeattrs =  method.getCodeAttributes();
jtulach@144
   261
        for(int k = 0; k < methodattrs.size(); k++){
jtulach@144
   262
            String methodattrname = ((AttrData)methodattrs.elementAt(k)).getAttrName();
jtulach@144
   263
            if(methodattrname.equals("Code")){
jtulach@144
   264
                printcodeSequence(method);
jtulach@144
   265
                printExceptionTable(method);
jtulach@144
   266
                for(int c = 0; c < codeattrs.size(); c++){
jtulach@144
   267
                    String codeattrname = ((AttrData)codeattrs.elementAt(c)).getAttrName();
jtulach@144
   268
                    if(codeattrname.equals("LineNumberTable")){
jtulach@144
   269
                        printLineNumTable(method);
jtulach@144
   270
                    }else if(codeattrname.equals("LocalVariableTable")){
jtulach@144
   271
                        printLocVarTable(method);
jtulach@144
   272
                    }else if(codeattrname.equals("StackMapTable")) {
jtulach@144
   273
                        // Java SE JSR 202 stack map tables
jtulach@144
   274
                        printStackMapTable(method);
jtulach@144
   275
                    }else if(codeattrname.equals("StackMap")) {
jtulach@144
   276
                        // Java ME CLDC stack maps
jtulach@144
   277
                        printStackMap(method);
jtulach@144
   278
                    } else {
jtulach@144
   279
                        printAttrData((AttrData)codeattrs.elementAt(c));
jtulach@144
   280
                    }
jtulach@144
   281
                }
jtulach@144
   282
            }else if(methodattrname.equals("Exceptions")){
jtulach@144
   283
                out.println("  Exceptions: ");
jtulach@144
   284
                printExceptions(method);
jtulach@144
   285
            }else if (methodattrname.equals("Deprecated")){
jtulach@144
   286
                out.println("  Deprecated: "+ method.isDeprecated());
jtulach@144
   287
            }else if (methodattrname.equals("Synthetic")){
jtulach@144
   288
                out.println("  Synthetic: "+ method.isSynthetic());
jtulach@144
   289
            }else {
jtulach@144
   290
                printAttrData((AttrData)methodattrs.elementAt(k));
jtulach@144
   291
            }
jtulach@144
   292
        }
jtulach@144
   293
        out.println();
jtulach@144
   294
    }
jtulach@144
   295
jtulach@144
   296
    /**
jtulach@144
   297
     * Print exceptions.
jtulach@144
   298
     */
jtulach@144
   299
    public void printExceptions(MethodData method){
jtulach@144
   300
        int []exc_index_table = method.get_exc_index_table();
jtulach@144
   301
        if (exc_index_table != null) {
jtulach@144
   302
            if(!(env. showLineAndLocal || env.showDisassembled || env.showVerbose
jtulach@144
   303
                 ||  env.showInternalSigs || env.showallAttr)){
jtulach@144
   304
                out.print("    ");
jtulach@144
   305
            }
jtulach@144
   306
            out.print("   throws ");
jtulach@144
   307
            int k;
jtulach@144
   308
            int l = exc_index_table.length;
jtulach@144
   309
jtulach@144
   310
            for (k=0; k<l; k++) {
jtulach@144
   311
                out.print(javaclassname(cls.getClassName(exc_index_table[k])));
jtulach@144
   312
                if (k<l-1) out.print(", ");
jtulach@144
   313
            }
jtulach@144
   314
        }
jtulach@144
   315
    }
jtulach@144
   316
jtulach@144
   317
    /**
jtulach@144
   318
     * Print code sequence.
jtulach@144
   319
     */
jtulach@144
   320
    public void  printcodeSequence(MethodData method){
jtulach@144
   321
        code = method.getCode();
jtulach@144
   322
        if(code != null){
jtulach@144
   323
            out.println("  Code:");
jtulach@144
   324
            if(env.showVerbose){
jtulach@144
   325
                printVerboseHeader(method);
jtulach@144
   326
            }
jtulach@144
   327
jtulach@144
   328
            for (int pc=0; pc < code.length; ) {
jtulach@144
   329
                out.print("   "+pc+":\t");
jtulach@144
   330
                pc=pc+printInstr(pc);
jtulach@144
   331
                out.println();
jtulach@144
   332
            }
jtulach@144
   333
        }
jtulach@144
   334
    }
jtulach@144
   335
jtulach@144
   336
    /**
jtulach@144
   337
     * Print instructions.
jtulach@144
   338
     */
jtulach@144
   339
    public int printInstr(int pc){
jtulach@144
   340
        int opcode = getUbyte(pc);
jtulach@144
   341
        int opcode2;
jtulach@144
   342
        String mnem;
jtulach@144
   343
        switch (opcode) {
jtulach@144
   344
        case opc_nonpriv:
jtulach@144
   345
        case opc_priv:
jtulach@144
   346
            opcode2 = getUbyte(pc+1);
jtulach@144
   347
            mnem=Tables.opcName((opcode<<8)+opcode2);
jtulach@144
   348
            if (mnem==null)
jtulach@144
   349
                // assume all (even nonexistent) priv and nonpriv instructions
jtulach@144
   350
                // are 2 bytes long
jtulach@144
   351
                mnem=Tables.opcName(opcode)+" "+opcode2;
jtulach@144
   352
            out.print(mnem);
jtulach@144
   353
            return 2;
jtulach@144
   354
        case opc_wide: {
jtulach@144
   355
            opcode2 = getUbyte(pc+1);
jtulach@144
   356
            mnem=Tables.opcName((opcode<<8)+opcode2);
jtulach@144
   357
            if (mnem==null) {
jtulach@144
   358
                // nonexistent opcode - but we have to print something
jtulach@144
   359
                out.print("bytecode "+opcode);
jtulach@144
   360
                return 1;
jtulach@144
   361
            }
jtulach@144
   362
            out.print(mnem+" "+getUShort(pc+2));
jtulach@144
   363
            if (opcode2==opc_iinc) {
jtulach@144
   364
                out.print(", "+getShort(pc+4));
jtulach@144
   365
                return 6;
jtulach@144
   366
            }
jtulach@144
   367
            return 4;
jtulach@144
   368
        }
jtulach@144
   369
        }
jtulach@144
   370
        mnem=Tables.opcName(opcode);
jtulach@144
   371
        if (mnem==null) {
jtulach@144
   372
            // nonexistent opcode - but we have to print something
jtulach@144
   373
            out.print("bytecode "+opcode);
jtulach@144
   374
            return 1;
jtulach@144
   375
        }
jtulach@144
   376
        if (opcode>opc_jsr_w) {
jtulach@144
   377
            // pseudo opcodes should be printed as bytecodes
jtulach@144
   378
            out.print("bytecode "+opcode);
jtulach@144
   379
            return 1;
jtulach@144
   380
        }
jtulach@144
   381
        out.print(Tables.opcName(opcode));
jtulach@144
   382
        switch (opcode) {
jtulach@144
   383
        case opc_aload: case opc_astore:
jtulach@144
   384
        case opc_fload: case opc_fstore:
jtulach@144
   385
        case opc_iload: case opc_istore:
jtulach@144
   386
        case opc_lload: case opc_lstore:
jtulach@144
   387
        case opc_dload: case opc_dstore:
jtulach@144
   388
        case opc_ret:
jtulach@144
   389
            out.print("\t"+getUbyte(pc+1));
jtulach@144
   390
            return  2;
jtulach@144
   391
        case opc_iinc:
jtulach@144
   392
            out.print("\t"+getUbyte(pc+1)+", "+getbyte(pc+2));
jtulach@144
   393
            return  3;
jtulach@144
   394
        case opc_tableswitch:{
jtulach@144
   395
            int tb=align(pc+1);
jtulach@144
   396
            int default_skip = getInt(tb); /* default skip pamount */
jtulach@144
   397
            int low = getInt(tb+4);
jtulach@144
   398
            int high = getInt(tb+8);
jtulach@144
   399
            int count = high - low;
jtulach@144
   400
            out.print("{ //"+low+" to "+high);
jtulach@144
   401
            for (int i = 0; i <= count; i++)
jtulach@144
   402
                out.print( "\n\t\t" + (i+low) + ": "+lP+(pc+getInt(tb+12+4*i))+";");
jtulach@144
   403
            out.print("\n\t\tdefault: "+lP+(default_skip + pc) + " }");
jtulach@144
   404
            return tb-pc+16+count*4;
jtulach@144
   405
        }
jtulach@144
   406
jtulach@144
   407
        case opc_lookupswitch:{
jtulach@144
   408
            int tb=align(pc+1);
jtulach@144
   409
            int default_skip = getInt(tb);
jtulach@144
   410
            int npairs = getInt(tb+4);
jtulach@144
   411
            out.print("{ //"+npairs);
jtulach@144
   412
            for (int i = 1; i <= npairs; i++)
jtulach@144
   413
                out.print("\n\t\t"+getInt(tb+i*8)
jtulach@144
   414
                                 +": "+lP+(pc+getInt(tb+4+i*8))+";"
jtulach@144
   415
                                 );
jtulach@144
   416
            out.print("\n\t\tdefault: "+lP+(default_skip + pc) + " }");
jtulach@144
   417
            return tb-pc+(npairs+1)*8;
jtulach@144
   418
        }
jtulach@144
   419
        case opc_newarray:
jtulach@144
   420
            int type=getUbyte(pc+1);
jtulach@144
   421
            switch (type) {
jtulach@144
   422
            case T_BOOLEAN:out.print(" boolean");break;
jtulach@144
   423
            case T_BYTE:   out.print(" byte");   break;
jtulach@144
   424
            case T_CHAR:   out.print(" char");   break;
jtulach@144
   425
            case T_SHORT:  out.print(" short");  break;
jtulach@144
   426
            case T_INT:    out.print(" int");    break;
jtulach@144
   427
            case T_LONG:   out.print(" long");   break;
jtulach@144
   428
            case T_FLOAT:  out.print(" float");  break;
jtulach@144
   429
            case T_DOUBLE: out.print(" double"); break;
jtulach@144
   430
            case T_CLASS:  out.print(" class"); break;
jtulach@144
   431
            default:       out.print(" BOGUS TYPE:"+type);
jtulach@144
   432
            }
jtulach@144
   433
            return 2;
jtulach@144
   434
jtulach@144
   435
        case opc_anewarray: {
jtulach@144
   436
            int index =  getUShort(pc+1);
jtulach@144
   437
            out.print("\t#"+index+"; //");
jtulach@144
   438
            PrintConstant(index);
jtulach@144
   439
            return 3;
jtulach@144
   440
        }
jtulach@144
   441
jtulach@144
   442
        case opc_sipush:
jtulach@144
   443
            out.print("\t"+getShort(pc+1));
jtulach@144
   444
            return 3;
jtulach@144
   445
jtulach@144
   446
        case opc_bipush:
jtulach@144
   447
            out.print("\t"+getbyte(pc+1));
jtulach@144
   448
            return 2;
jtulach@144
   449
jtulach@144
   450
        case opc_ldc: {
jtulach@144
   451
            int index = getUbyte(pc+1);
jtulach@144
   452
            out.print("\t#"+index+"; //");
jtulach@144
   453
            PrintConstant(index);
jtulach@144
   454
            return 2;
jtulach@144
   455
        }
jtulach@144
   456
jtulach@144
   457
        case opc_ldc_w: case opc_ldc2_w:
jtulach@144
   458
        case opc_instanceof: case opc_checkcast:
jtulach@144
   459
        case opc_new:
jtulach@144
   460
        case opc_putstatic: case opc_getstatic:
jtulach@144
   461
        case opc_putfield: case opc_getfield:
jtulach@144
   462
        case opc_invokevirtual:
jtulach@144
   463
        case opc_invokespecial:
jtulach@144
   464
        case opc_invokestatic: {
jtulach@144
   465
            int index = getUShort(pc+1);
jtulach@144
   466
            out.print("\t#"+index+"; //");
jtulach@144
   467
            PrintConstant(index);
jtulach@144
   468
            return 3;
jtulach@144
   469
        }
jtulach@144
   470
jtulach@144
   471
        case opc_invokeinterface: {
jtulach@144
   472
            int index = getUShort(pc+1), nargs=getUbyte(pc+3);
jtulach@144
   473
            out.print("\t#"+index+",  "+nargs+"; //");
jtulach@144
   474
            PrintConstant(index);
jtulach@144
   475
            return 5;
jtulach@144
   476
        }
jtulach@144
   477
jtulach@144
   478
        case opc_multianewarray: {
jtulach@144
   479
            int index = getUShort(pc+1), dimensions=getUbyte(pc+3);
jtulach@144
   480
            out.print("\t#"+index+",  "+dimensions+"; //");
jtulach@144
   481
            PrintConstant(index);
jtulach@144
   482
            return 4;
jtulach@144
   483
        }
jtulach@144
   484
        case opc_jsr: case opc_goto:
jtulach@144
   485
        case opc_ifeq: case opc_ifge: case opc_ifgt:
jtulach@144
   486
        case opc_ifle: case opc_iflt: case opc_ifne:
jtulach@144
   487
        case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmpge:
jtulach@144
   488
        case opc_if_icmpgt: case opc_if_icmple: case opc_if_icmplt:
jtulach@144
   489
        case opc_if_acmpeq: case opc_if_acmpne:
jtulach@144
   490
        case opc_ifnull: case opc_ifnonnull:
jtulach@144
   491
            out.print("\t"+lP+(pc + getShort(pc+1)) );
jtulach@144
   492
            return 3;
jtulach@144
   493
jtulach@144
   494
        case opc_jsr_w:
jtulach@144
   495
        case opc_goto_w:
jtulach@144
   496
            out.print("\t"+lP+(pc + getInt(pc+1)));
jtulach@144
   497
            return 5;
jtulach@144
   498
jtulach@144
   499
        default:
jtulach@144
   500
            return 1;
jtulach@144
   501
        }
jtulach@144
   502
    }
jtulach@144
   503
    /**
jtulach@144
   504
     * Print code attribute details.
jtulach@144
   505
     */
jtulach@144
   506
    public void printVerboseHeader(MethodData method) {
jtulach@144
   507
        int argCount = method.getArgumentlength();
jtulach@144
   508
        if (!method.isStatic())
jtulach@144
   509
            ++argCount;  // for 'this'
jtulach@144
   510
jtulach@144
   511
        out.println("   Stack=" + method.getMaxStack()
jtulach@144
   512
                           + ", Locals=" + method.getMaxLocals()
jtulach@144
   513
                           + ", Args_size=" + argCount);
jtulach@144
   514
jtulach@144
   515
    }
jtulach@144
   516
jtulach@144
   517
jtulach@144
   518
    /**
jtulach@144
   519
     * Print the exception table for this method code
jtulach@144
   520
     */
jtulach@144
   521
    void printExceptionTable(MethodData method){//throws IOException
jtulach@144
   522
        Vector exception_table = method.getexception_table();
jtulach@144
   523
        if (exception_table.size() > 0) {
jtulach@144
   524
            out.println("  Exception table:");
jtulach@144
   525
            out.println("   from   to  target type");
jtulach@144
   526
            for (int idx = 0; idx < exception_table.size(); ++idx) {
jtulach@144
   527
                TrapData handler = (TrapData)exception_table.elementAt(idx);
jtulach@144
   528
                printFixedWidthInt(handler.start_pc, 6);
jtulach@144
   529
                printFixedWidthInt(handler.end_pc, 6);
jtulach@144
   530
                printFixedWidthInt(handler.handler_pc, 6);
jtulach@144
   531
                out.print("   ");
jtulach@144
   532
                int catch_cpx = handler.catch_cpx;
jtulach@144
   533
                if (catch_cpx == 0) {
jtulach@144
   534
                    out.println("any");
jtulach@144
   535
                }else {
jtulach@144
   536
                    out.print("Class ");
jtulach@144
   537
                    out.println(cls.getClassName(catch_cpx));
jtulach@144
   538
                    out.println("");
jtulach@144
   539
                }
jtulach@144
   540
            }
jtulach@144
   541
        }
jtulach@144
   542
    }
jtulach@144
   543
jtulach@144
   544
    /**
jtulach@144
   545
     * Print LineNumberTable attribute information.
jtulach@144
   546
     */
jtulach@144
   547
    public void printLineNumTable(MethodData method) {
jtulach@144
   548
        int numlines = method.getnumlines();
jtulach@144
   549
        Vector lin_num_tb = method.getlin_num_tb();
jtulach@144
   550
        if( lin_num_tb.size() > 0){
jtulach@144
   551
            out.println("  LineNumberTable: ");
jtulach@144
   552
            for (int i=0; i<numlines; i++) {
jtulach@144
   553
                LineNumData linnumtb_entry=(LineNumData)lin_num_tb.elementAt(i);
jtulach@144
   554
                out.println("   line " + linnumtb_entry.line_number + ": "
jtulach@144
   555
                               + linnumtb_entry.start_pc);
jtulach@144
   556
            }
jtulach@144
   557
        }
jtulach@144
   558
        out.println();
jtulach@144
   559
    }
jtulach@144
   560
jtulach@144
   561
    /**
jtulach@144
   562
     * Print LocalVariableTable attribute information.
jtulach@144
   563
     */
jtulach@144
   564
    public void printLocVarTable(MethodData method){
jtulach@144
   565
        int siz = method.getloc_var_tbsize();
jtulach@144
   566
        if(siz > 0){
jtulach@144
   567
            out.println("  LocalVariableTable: ");
jtulach@144
   568
            out.print("   ");
jtulach@144
   569
            out.println("Start  Length  Slot  Name   Signature");
jtulach@144
   570
        }
jtulach@144
   571
        Vector loc_var_tb = method.getloc_var_tb();
jtulach@144
   572
jtulach@144
   573
        for (int i=0; i<siz; i++) {
jtulach@144
   574
            LocVarData entry=(LocVarData)loc_var_tb.elementAt(i);
jtulach@144
   575
jtulach@144
   576
            out.println("   "+entry.start_pc+"      "+entry.length+"      "+
jtulach@144
   577
                               entry.slot+"    "+cls.StringValue(entry.name_cpx)  +
jtulach@144
   578
                               "       "+cls.StringValue(entry.sig_cpx));
jtulach@144
   579
        }
jtulach@144
   580
        out.println();
jtulach@144
   581
    }
jtulach@144
   582
jtulach@144
   583
    /**
jtulach@144
   584
     * Print StackMap attribute information.
jtulach@144
   585
     */
jtulach@144
   586
    public void printStackMap(MethodData method) {
jtulach@144
   587
        StackMapData[] stack_map_tb = method.getStackMap();
jtulach@144
   588
        int number_of_entries = stack_map_tb.length;
jtulach@144
   589
        if (number_of_entries > 0) {
jtulach@144
   590
            out.println("  StackMap: number_of_entries = " + number_of_entries);
jtulach@144
   591
jtulach@144
   592
            for (StackMapData frame : stack_map_tb) {
jtulach@144
   593
                frame.print(this);
jtulach@144
   594
            }
jtulach@144
   595
        }
jtulach@144
   596
       out.println();
jtulach@144
   597
    }
jtulach@144
   598
jtulach@144
   599
    /**
jtulach@144
   600
     * Print StackMapTable attribute information.
jtulach@144
   601
     */
jtulach@144
   602
    public void printStackMapTable(MethodData method) {
jtulach@144
   603
        StackMapTableData[] stack_map_tb = method.getStackMapTable();
jtulach@144
   604
        int number_of_entries = stack_map_tb.length;
jtulach@144
   605
        if (number_of_entries > 0) {
jtulach@144
   606
            out.println("  StackMapTable: number_of_entries = " + number_of_entries);
jtulach@144
   607
jtulach@144
   608
            for (StackMapTableData frame : stack_map_tb) {
jtulach@144
   609
                frame.print(this);
jtulach@144
   610
            }
jtulach@144
   611
        }
jtulach@144
   612
        out.println();
jtulach@144
   613
    }
jtulach@144
   614
jtulach@144
   615
    void printMap(String name, int[] map) {
jtulach@144
   616
        out.print(name);
jtulach@144
   617
        for (int i=0; i<map.length; i++) {
jtulach@144
   618
            int fulltype = map[i];
jtulach@144
   619
            int type = fulltype & 0xFF;
jtulach@144
   620
            int argument = fulltype >> 8;
jtulach@144
   621
            switch (type) {
jtulach@144
   622
                case ITEM_Object:
jtulach@144
   623
                    out.print(" ");
jtulach@144
   624
                    PrintConstant(argument);
jtulach@144
   625
                    break;
jtulach@144
   626
                case ITEM_NewObject:
jtulach@144
   627
                    out.print(" " + Tables.mapTypeName(type));
jtulach@144
   628
                    out.print(" " + argument);
jtulach@144
   629
                    break;
jtulach@144
   630
                default:
jtulach@144
   631
                    out.print(" " + Tables.mapTypeName(type));
jtulach@144
   632
            }
jtulach@144
   633
            out.print( (i==(map.length-1)? ' ' : ','));
jtulach@144
   634
        }
jtulach@144
   635
        out.println("]");
jtulach@144
   636
    }
jtulach@144
   637
jtulach@144
   638
    /**
jtulach@144
   639
     * Print ConstantValue attribute information.
jtulach@144
   640
     */
jtulach@144
   641
    public void printConstantValue(FieldData field){
jtulach@144
   642
        out.print("  Constant value: ");
jtulach@144
   643
        int cpx = (field.getConstantValueIndex());
jtulach@144
   644
        byte tag=0;
jtulach@144
   645
        try {
jtulach@144
   646
            tag=cls.getTag(cpx);
jtulach@144
   647
jtulach@144
   648
        } catch (IndexOutOfBoundsException e) {
jtulach@144
   649
            out.print("Error:");
jtulach@144
   650
            return;
jtulach@144
   651
        }
jtulach@144
   652
        switch (tag) {
jtulach@144
   653
        case CONSTANT_METHOD:
jtulach@144
   654
        case CONSTANT_INTERFACEMETHOD:
jtulach@144
   655
        case CONSTANT_FIELD: {
jtulach@144
   656
            CPX2 x = (CPX2)(cls.getCpoolEntry(cpx));
jtulach@144
   657
            if (x.cpx1 == cls.getthis_cpx()) {
jtulach@144
   658
                // don't print class part for local references
jtulach@144
   659
                cpx=x.cpx2;
jtulach@144
   660
            }
jtulach@144
   661
        }
jtulach@144
   662
        }
jtulach@144
   663
        out.print(cls.TagString(tag)+" "+ cls.StringValue(cpx));
jtulach@144
   664
    }
jtulach@144
   665
jtulach@144
   666
    /**
jtulach@144
   667
     * Print InnerClass attribute information.
jtulach@144
   668
     */
jtulach@144
   669
    public void printInnerClasses(){//throws ioexception
jtulach@144
   670
jtulach@144
   671
        InnerClassData[] innerClasses = cls.getInnerClasses();
jtulach@144
   672
        if(innerClasses != null){
jtulach@144
   673
            if(innerClasses.length > 0){
jtulach@144
   674
                out.print("  ");
jtulach@144
   675
                out.println("InnerClass: ");
jtulach@144
   676
                for(int i = 0 ; i < innerClasses.length; i++){
jtulach@144
   677
                    out.print("   ");
jtulach@144
   678
                    //access
jtulach@144
   679
                    String[] accflags = innerClasses[i].getAccess();
jtulach@144
   680
                    if(checkAccess(accflags)){
jtulach@144
   681
                        printAccess(accflags);
jtulach@144
   682
                        if (innerClasses[i].inner_name_index!=0) {
jtulach@144
   683
                            out.print("#"+innerClasses[i].inner_name_index+"= ");
jtulach@144
   684
                        }
jtulach@144
   685
                        out.print("#"+innerClasses[i].inner_class_info_index);
jtulach@144
   686
                        if (innerClasses[i].outer_class_info_index!=0) {
jtulach@144
   687
                            out.print(" of #"+innerClasses[i].outer_class_info_index);
jtulach@144
   688
                        }
jtulach@144
   689
                        out.print("; //");
jtulach@144
   690
                        if (innerClasses[i].inner_name_index!=0) {
jtulach@144
   691
                            out.print(cls.getName(innerClasses[i].inner_name_index)+"=");
jtulach@144
   692
                        }
jtulach@144
   693
                        PrintConstant(innerClasses[i].inner_class_info_index);
jtulach@144
   694
                        if (innerClasses[i].outer_class_info_index!=0) {
jtulach@144
   695
                            out.print(" of ");
jtulach@144
   696
                            PrintConstant(innerClasses[i].outer_class_info_index);
jtulach@144
   697
                        }
jtulach@144
   698
                        out.println();
jtulach@144
   699
                    }
jtulach@144
   700
                }
jtulach@144
   701
jtulach@144
   702
            }
jtulach@144
   703
        }
jtulach@144
   704
    }
jtulach@144
   705
jtulach@144
   706
    /**
jtulach@144
   707
     * Print constant pool information.
jtulach@144
   708
     */
jtulach@144
   709
    public void printcp(){
jtulach@144
   710
        int cpx = 1 ;
jtulach@144
   711
jtulach@144
   712
        while (cpx < cls.getCpoolCount()) {
jtulach@144
   713
            out.print("const #"+cpx+" = ");
jtulach@144
   714
            cpx+=PrintlnConstantEntry(cpx);
jtulach@144
   715
        }
jtulach@144
   716
        out.println();
jtulach@144
   717
    }
jtulach@144
   718
jtulach@144
   719
    /**
jtulach@144
   720
     * Print constant pool entry information.
jtulach@144
   721
     */
jtulach@144
   722
    public int PrintlnConstantEntry(int cpx) {
jtulach@144
   723
        int size=1;
jtulach@144
   724
        byte tag=0;
jtulach@144
   725
        try {
jtulach@144
   726
            tag=cls.getTag(cpx);
jtulach@144
   727
        } catch (IndexOutOfBoundsException e) {
jtulach@144
   728
            out.println("  <Incorrect CP index>");
jtulach@144
   729
            return 1;
jtulach@144
   730
        }
jtulach@144
   731
        out.print(cls.StringTag(cpx)+"\t");
jtulach@144
   732
        Object x=cls.getCpoolEntryobj(cpx);
jtulach@144
   733
        if (x==null) {
jtulach@144
   734
            switch (tag) {
jtulach@144
   735
            case CONSTANT_LONG:
jtulach@144
   736
            case CONSTANT_DOUBLE:
jtulach@144
   737
                size=2;
jtulach@144
   738
            }
jtulach@144
   739
            out.println("null;");
jtulach@144
   740
            return size;
jtulach@144
   741
        }
jtulach@144
   742
        String str=cls.StringValue(cpx);
jtulach@144
   743
jtulach@144
   744
        switch (tag) {
jtulach@144
   745
        case CONSTANT_CLASS:
jtulach@144
   746
        case CONSTANT_STRING:
jtulach@144
   747
            out.println("#"+(((CPX)x).cpx)+";\t//  "+str);
jtulach@144
   748
            break;
jtulach@144
   749
        case CONSTANT_FIELD:
jtulach@144
   750
        case CONSTANT_METHOD:
jtulach@144
   751
        case CONSTANT_INTERFACEMETHOD:
jtulach@144
   752
            out.println("#"+((CPX2)x).cpx1+".#"+((CPX2)x).cpx2+";\t//  "+str);
jtulach@144
   753
            break;
jtulach@144
   754
        case CONSTANT_NAMEANDTYPE:
jtulach@144
   755
            out.println("#"+((CPX2)x).cpx1+":#"+((CPX2)x).cpx2+";//  "+str);
jtulach@144
   756
            break;
jtulach@144
   757
        case CONSTANT_LONG:
jtulach@144
   758
        case CONSTANT_DOUBLE:
jtulach@144
   759
            size=2;
jtulach@144
   760
        default:
jtulach@144
   761
            out.println(str+";");
jtulach@144
   762
        }
jtulach@144
   763
        return size;
jtulach@144
   764
    }
jtulach@144
   765
jtulach@144
   766
    /**
jtulach@144
   767
     * Checks access of class, field or method.
jtulach@144
   768
     */
jtulach@144
   769
    public boolean checkAccess(String accflags[]){
jtulach@144
   770
jtulach@144
   771
        boolean ispublic = false;
jtulach@144
   772
        boolean isprotected = false;
jtulach@144
   773
        boolean isprivate = false;
jtulach@144
   774
        boolean ispackage = false;
jtulach@144
   775
jtulach@144
   776
        for(int i= 0; i < accflags.length; i++){
jtulach@144
   777
            if(accflags[i].equals("public")) ispublic = true;
jtulach@144
   778
            else if (accflags[i].equals("protected")) isprotected = true;
jtulach@144
   779
            else if (accflags[i].equals("private")) isprivate = true;
jtulach@144
   780
        }
jtulach@144
   781
jtulach@144
   782
        if(!(ispublic || isprotected || isprivate)) ispackage = true;
jtulach@144
   783
jtulach@144
   784
        if((env.showAccess == env.PUBLIC) && (isprotected || isprivate || ispackage)) return false;
jtulach@144
   785
        else if((env.showAccess == env.PROTECTED) && (isprivate || ispackage)) return false;
jtulach@144
   786
        else if((env.showAccess == env.PACKAGE) && (isprivate)) return false;
jtulach@144
   787
        else return true;
jtulach@144
   788
    }
jtulach@144
   789
jtulach@144
   790
    /**
jtulach@144
   791
     * Prints access of class, field or method.
jtulach@144
   792
     */
jtulach@144
   793
    public void printAccess(String []accflags){
jtulach@144
   794
        for(int j = 0; j < accflags.length; j++){
jtulach@144
   795
            out.print(accflags[j]+" ");
jtulach@144
   796
        }
jtulach@144
   797
    }
jtulach@144
   798
jtulach@144
   799
    /**
jtulach@144
   800
     * Print an integer so that it takes 'length' characters in
jtulach@144
   801
     * the output.  Temporary until formatting code is stable.
jtulach@144
   802
     */
jtulach@144
   803
    public void printFixedWidthInt(long x, int length) {
jtulach@144
   804
        CharArrayWriter baStream = new CharArrayWriter();
jtulach@144
   805
        PrintWriter pStream = new PrintWriter(baStream);
jtulach@144
   806
        pStream.print(x);
jtulach@144
   807
        String str = baStream.toString();
jtulach@144
   808
        for (int cnt = length - str.length(); cnt > 0; --cnt)
jtulach@144
   809
            out.print(' ');
jtulach@144
   810
        out.print(str);
jtulach@144
   811
    }
jtulach@144
   812
jtulach@144
   813
    protected int getbyte (int pc) {
jtulach@144
   814
        return code[pc];
jtulach@144
   815
    }
jtulach@144
   816
jtulach@144
   817
    protected int getUbyte (int pc) {
jtulach@144
   818
        return code[pc]&0xFF;
jtulach@144
   819
    }
jtulach@144
   820
jtulach@144
   821
    int getShort (int pc) {
jtulach@144
   822
        return (code[pc]<<8) | (code[pc+1]&0xFF);
jtulach@144
   823
    }
jtulach@144
   824
jtulach@144
   825
    int getUShort (int pc) {
jtulach@144
   826
        return ((code[pc]<<8) | (code[pc+1]&0xFF))&0xFFFF;
jtulach@144
   827
    }
jtulach@144
   828
jtulach@144
   829
    protected int getInt (int pc) {
jtulach@144
   830
        return (getShort(pc)<<16) | (getShort(pc+2)&0xFFFF);
jtulach@144
   831
    }
jtulach@144
   832
jtulach@144
   833
    /**
jtulach@144
   834
     * Print constant value at that index.
jtulach@144
   835
     */
jtulach@144
   836
    void PrintConstant(int cpx) {
jtulach@144
   837
        if (cpx==0) {
jtulach@144
   838
            out.print("#0");
jtulach@144
   839
            return;
jtulach@144
   840
        }
jtulach@144
   841
        byte tag=0;
jtulach@144
   842
        try {
jtulach@144
   843
            tag=cls.getTag(cpx);
jtulach@144
   844
jtulach@144
   845
        } catch (IndexOutOfBoundsException e) {
jtulach@144
   846
            out.print("#"+cpx);
jtulach@144
   847
            return;
jtulach@144
   848
        }
jtulach@144
   849
        switch (tag) {
jtulach@144
   850
        case CONSTANT_METHOD:
jtulach@144
   851
        case CONSTANT_INTERFACEMETHOD:
jtulach@144
   852
        case CONSTANT_FIELD: {
jtulach@144
   853
            // CPX2 x=(CPX2)(cpool[cpx]);
jtulach@144
   854
            CPX2 x = (CPX2)(cls.getCpoolEntry(cpx));
jtulach@144
   855
            if (x.cpx1 == cls.getthis_cpx()) {
jtulach@144
   856
                // don't print class part for local references
jtulach@144
   857
                cpx=x.cpx2;
jtulach@144
   858
            }
jtulach@144
   859
        }
jtulach@144
   860
        }
jtulach@144
   861
        out.print(cls.TagString(tag)+" "+ cls.StringValue(cpx));
jtulach@144
   862
    }
jtulach@144
   863
jtulach@144
   864
    protected static int  align (int n) {
jtulach@144
   865
        return (n+3) & ~3 ;
jtulach@144
   866
    }
jtulach@144
   867
jtulach@144
   868
    public void printend(){
jtulach@144
   869
        out.println("}");
jtulach@144
   870
        out.println();
jtulach@144
   871
    }
jtulach@144
   872
jtulach@144
   873
    public String javaclassname(String name){
jtulach@144
   874
        return name.replace('/','.');
jtulach@144
   875
    }
jtulach@144
   876
jtulach@144
   877
    /**
jtulach@144
   878
     * Print attribute data in hex.
jtulach@144
   879
     */
jtulach@144
   880
    public void printAttrData(AttrData attr){
jtulach@144
   881
        byte []data = attr.getData();
jtulach@144
   882
        int i = 0;
jtulach@144
   883
        int j = 0;
jtulach@144
   884
        out.print("  "+attr.getAttrName()+": ");
jtulach@144
   885
        out.println("length = " + cls.toHex(attr.datalen));
jtulach@144
   886
jtulach@144
   887
        out.print("   ");
jtulach@144
   888
jtulach@144
   889
jtulach@144
   890
        while (i < data.length){
jtulach@144
   891
            String databytestring = cls.toHex(data[i]);
jtulach@144
   892
            if(databytestring.equals("0x")) out.print("00");
jtulach@144
   893
            else if(databytestring.substring(2).length() == 1){
jtulach@144
   894
                out.print("0"+databytestring.substring(2));
jtulach@144
   895
            } else{
jtulach@144
   896
                out.print(databytestring.substring(2));
jtulach@144
   897
            }
jtulach@144
   898
jtulach@144
   899
             j++;
jtulach@144
   900
            if(j == 16) {
jtulach@144
   901
                out.println();
jtulach@144
   902
                out.print("   ");
jtulach@144
   903
                j = 0;
jtulach@144
   904
            }
jtulach@144
   905
            else out.print(" ");
jtulach@144
   906
            i++;
jtulach@144
   907
        }
jtulach@144
   908
        out.println();
jtulach@144
   909
    }
jtulach@144
   910
}