javap/src/main/java/sun/tools/javap/JavapPrinter.java
branchjavap
changeset 144 b06660b614db
child 145 525b0a571518
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/javap/src/main/java/sun/tools/javap/JavapPrinter.java	Fri Nov 09 21:33:22 2012 +0100
     1.3 @@ -0,0 +1,910 @@
     1.4 +/*
     1.5 + * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.  Oracle designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Oracle in the LICENSE file that accompanied this code.
    1.13 + *
    1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 + * version 2 for more details (a copy is included in the LICENSE file that
    1.18 + * accompanied this code).
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License version
    1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + *
    1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 + * or visit www.oracle.com if you need additional information or have any
    1.26 + * questions.
    1.27 + */
    1.28 +
    1.29 +
    1.30 +package sun.tools.javap;
    1.31 +
    1.32 +import java.util.*;
    1.33 +import java.io.*;
    1.34 +
    1.35 +import static sun.tools.javap.RuntimeConstants.*;
    1.36 +
    1.37 +/**
    1.38 + * Program to print information about class files
    1.39 + *
    1.40 + * @author  Sucheta Dambalkar
    1.41 + */
    1.42 +public class JavapPrinter {
    1.43 +    JavapEnvironment env;
    1.44 +    ClassData cls;
    1.45 +    byte[] code;
    1.46 +    String lP= "";
    1.47 +    PrintWriter out;
    1.48 +
    1.49 +    public JavapPrinter(InputStream cname, PrintWriter out, JavapEnvironment env){
    1.50 +        this.out = out;
    1.51 +        this.cls =  new ClassData(cname);
    1.52 +        this.env = env;
    1.53 +    }
    1.54 +
    1.55 +    /**
    1.56 +     *  Entry point to print class file information.
    1.57 +     */
    1.58 +    public void print(){
    1.59 +        printclassHeader();
    1.60 +        printfields();
    1.61 +        printMethods();
    1.62 +        printend();
    1.63 +    }
    1.64 +
    1.65 +    /**
    1.66 +     * Print a description of the class (not members).
    1.67 +     */
    1.68 +    public void printclassHeader(){
    1.69 +        String srcName="";
    1.70 +        if ((srcName = cls.getSourceName()) != "null") // requires debug info
    1.71 +            out.println("Compiled from " + javaclassname(srcName));
    1.72 +
    1.73 +        if(cls.isInterface())   {
    1.74 +            // The only useful access modifier of an interface is
    1.75 +            // public; interfaces are always marked as abstract and
    1.76 +            // cannot be final.
    1.77 +            out.print((cls.isPublic()?"public ":"") +
    1.78 +                      "interface "+ javaclassname(cls.getClassName()));
    1.79 +        }
    1.80 +        else if(cls.isClass()) {
    1.81 +            String []accflags =  cls.getAccess();
    1.82 +            printAccess(accflags);
    1.83 +            out.print("class "+ javaclassname(cls.getClassName()));
    1.84 +
    1.85 +            if(cls.getSuperClassName() != null){
    1.86 +                out.print(" extends " + javaclassname(cls.getSuperClassName()));
    1.87 +            }
    1.88 +        }
    1.89 +
    1.90 +        String []interfacelist =  cls.getSuperInterfaces();
    1.91 +        if(interfacelist.length > 0){
    1.92 +            if(cls.isClass()) {
    1.93 +                out.print(" implements ");
    1.94 +            }
    1.95 +            else if(cls.isInterface()){
    1.96 +                out.print(" extends ");
    1.97 +            }
    1.98 +
    1.99 +            for(int j = 0; j < interfacelist.length; j++){
   1.100 +                out.print(javaclassname(interfacelist[j]));
   1.101 +
   1.102 +                if((j+1) < interfacelist.length) {
   1.103 +                    out.print(",");
   1.104 +                }
   1.105 +            }
   1.106 +        }
   1.107 +
   1.108 +        // Print class attribute information.
   1.109 +        if((env.showallAttr) || (env.showVerbose)){
   1.110 +            printClassAttributes();
   1.111 +        }
   1.112 +        // Print verbose output.
   1.113 +        if(env.showVerbose){
   1.114 +            printverbosecls();
   1.115 +        }
   1.116 +        out.println("{");
   1.117 +    }
   1.118 +
   1.119 +    /**
   1.120 +     * Print verbose output.
   1.121 +     */
   1.122 +    public void printverbosecls(){
   1.123 +        out.println("  minor version: "+cls.getMinor_version());
   1.124 +        out.println("  major version: "+cls.getMajor_version());
   1.125 +        out.println("  Constant pool:");
   1.126 +        printcp();
   1.127 +        env.showallAttr = true;
   1.128 +    }
   1.129 +
   1.130 +    /**
   1.131 +     * Print class attribute information.
   1.132 +     */
   1.133 +    public void printClassAttributes(){
   1.134 +        out.println();
   1.135 +        AttrData[] clsattrs = cls.getAttributes();
   1.136 +        for(int i = 0; i < clsattrs.length; i++){
   1.137 +            String clsattrname = clsattrs[i].getAttrName();
   1.138 +            if(clsattrname.equals("SourceFile")){
   1.139 +                out.println("  SourceFile: "+ cls.getSourceName());
   1.140 +            }else if(clsattrname.equals("InnerClasses")){
   1.141 +                printInnerClasses();
   1.142 +            }else {
   1.143 +                printAttrData(clsattrs[i]);
   1.144 +            }
   1.145 +        }
   1.146 +    }
   1.147 +
   1.148 +    /**
   1.149 +     * Print the fields
   1.150 +     */
   1.151 +    public void printfields(){
   1.152 +        FieldData[] fields = cls.getFields();
   1.153 +        for(int f = 0; f < fields.length; f++){
   1.154 +            String[] accflags = fields[f].getAccess();
   1.155 +            if(checkAccess(accflags)){
   1.156 +                if(!(env. showLineAndLocal || env.showDisassembled || env.showVerbose
   1.157 +                     ||  env.showInternalSigs || env.showallAttr)){
   1.158 +                    out.print("    ");
   1.159 +                }
   1.160 +                printAccess(accflags);
   1.161 +                out.println(fields[f].getType()+" " +fields[f].getName()+";");
   1.162 +                if (env.showInternalSigs) {
   1.163 +                    out.println("  Signature: " + (fields[f].getInternalSig()));
   1.164 +                }
   1.165 +
   1.166 +                // print field attribute information.
   1.167 +                if (env.showallAttr){
   1.168 +                    printFieldAttributes(fields[f]);
   1.169 +
   1.170 +                }
   1.171 +                if((env.showDisassembled) || (env.showLineAndLocal)){
   1.172 +                    out.println();
   1.173 +                }
   1.174 +            }
   1.175 +        }
   1.176 +    }
   1.177 +
   1.178 +
   1.179 +    /* print field attribute information. */
   1.180 +    public void printFieldAttributes(FieldData field){
   1.181 +        Vector fieldattrs = field.getAttributes();
   1.182 +        for(int j = 0; j < fieldattrs.size(); j++){
   1.183 +            String fieldattrname = ((AttrData)fieldattrs.elementAt(j)).getAttrName();
   1.184 +            if(fieldattrname.equals("ConstantValue")){
   1.185 +                printConstantValue(field);
   1.186 +            }else if (fieldattrname.equals("Deprecated")){
   1.187 +                out.println("Deprecated: "+ field.isDeprecated());
   1.188 +            }else if (fieldattrname.equals("Synthetic")){
   1.189 +                out.println("  Synthetic: "+ field.isSynthetic());
   1.190 +            }else {
   1.191 +                printAttrData((AttrData)fieldattrs.elementAt(j));
   1.192 +            }
   1.193 +        }
   1.194 +        out.println();
   1.195 +    }
   1.196 +
   1.197 +    /**
   1.198 +     * Print the methods
   1.199 +     */
   1.200 +    public void printMethods(){
   1.201 +        MethodData[] methods = cls.getMethods();
   1.202 +        for(int m = 0; m < methods.length; m++){
   1.203 +            String[] accflags = methods[m].getAccess();
   1.204 +            if(checkAccess(accflags)){
   1.205 +                if(!(env. showLineAndLocal || env.showDisassembled || env.showVerbose
   1.206 +                     ||  env.showInternalSigs || env.showallAttr)){
   1.207 +                    out.print("    ");
   1.208 +                }
   1.209 +                printMethodSignature(methods[m], accflags);
   1.210 +                printExceptions(methods[m]);
   1.211 +                out.println(";");
   1.212 +
   1.213 +                // Print internal signature of method.
   1.214 +                if (env.showInternalSigs){
   1.215 +                    out.println("  Signature: " + (methods[m].getInternalSig()));
   1.216 +                }
   1.217 +
   1.218 +                //Print disassembled code.
   1.219 +                if(env.showDisassembled && ! env.showallAttr) {
   1.220 +                    printcodeSequence(methods[m]);
   1.221 +                    printExceptionTable(methods[m]);
   1.222 +                    out.println();
   1.223 +                }
   1.224 +
   1.225 +                // Print line and local variable attribute information.
   1.226 +                if (env.showLineAndLocal) {
   1.227 +                    printLineNumTable(methods[m]);
   1.228 +                    printLocVarTable(methods[m]);
   1.229 +                    out.println();
   1.230 +                }
   1.231 +
   1.232 +                // Print  method attribute information.
   1.233 +                if (env.showallAttr){
   1.234 +                    printMethodAttributes(methods[m]);
   1.235 +                }
   1.236 +            }
   1.237 +        }
   1.238 +    }
   1.239 +
   1.240 +    /**
   1.241 +     * Print method signature.
   1.242 +     */
   1.243 +    public void printMethodSignature(MethodData method, String[] accflags){
   1.244 +        printAccess(accflags);
   1.245 +
   1.246 +        if((method.getName()).equals("<init>")){
   1.247 +            out.print(javaclassname(cls.getClassName()));
   1.248 +            out.print(method.getParameters());
   1.249 +        }else if((method.getName()).equals("<clinit>")){
   1.250 +            out.print("{}");
   1.251 +        }else{
   1.252 +            out.print(method.getReturnType()+" ");
   1.253 +            out.print(method.getName());
   1.254 +            out.print(method.getParameters());
   1.255 +        }
   1.256 +    }
   1.257 +
   1.258 +    /**
   1.259 +     * print method attribute information.
   1.260 +     */
   1.261 +    public void printMethodAttributes(MethodData method){
   1.262 +        Vector methodattrs = method.getAttributes();
   1.263 +        Vector codeattrs =  method.getCodeAttributes();
   1.264 +        for(int k = 0; k < methodattrs.size(); k++){
   1.265 +            String methodattrname = ((AttrData)methodattrs.elementAt(k)).getAttrName();
   1.266 +            if(methodattrname.equals("Code")){
   1.267 +                printcodeSequence(method);
   1.268 +                printExceptionTable(method);
   1.269 +                for(int c = 0; c < codeattrs.size(); c++){
   1.270 +                    String codeattrname = ((AttrData)codeattrs.elementAt(c)).getAttrName();
   1.271 +                    if(codeattrname.equals("LineNumberTable")){
   1.272 +                        printLineNumTable(method);
   1.273 +                    }else if(codeattrname.equals("LocalVariableTable")){
   1.274 +                        printLocVarTable(method);
   1.275 +                    }else if(codeattrname.equals("StackMapTable")) {
   1.276 +                        // Java SE JSR 202 stack map tables
   1.277 +                        printStackMapTable(method);
   1.278 +                    }else if(codeattrname.equals("StackMap")) {
   1.279 +                        // Java ME CLDC stack maps
   1.280 +                        printStackMap(method);
   1.281 +                    } else {
   1.282 +                        printAttrData((AttrData)codeattrs.elementAt(c));
   1.283 +                    }
   1.284 +                }
   1.285 +            }else if(methodattrname.equals("Exceptions")){
   1.286 +                out.println("  Exceptions: ");
   1.287 +                printExceptions(method);
   1.288 +            }else if (methodattrname.equals("Deprecated")){
   1.289 +                out.println("  Deprecated: "+ method.isDeprecated());
   1.290 +            }else if (methodattrname.equals("Synthetic")){
   1.291 +                out.println("  Synthetic: "+ method.isSynthetic());
   1.292 +            }else {
   1.293 +                printAttrData((AttrData)methodattrs.elementAt(k));
   1.294 +            }
   1.295 +        }
   1.296 +        out.println();
   1.297 +    }
   1.298 +
   1.299 +    /**
   1.300 +     * Print exceptions.
   1.301 +     */
   1.302 +    public void printExceptions(MethodData method){
   1.303 +        int []exc_index_table = method.get_exc_index_table();
   1.304 +        if (exc_index_table != null) {
   1.305 +            if(!(env. showLineAndLocal || env.showDisassembled || env.showVerbose
   1.306 +                 ||  env.showInternalSigs || env.showallAttr)){
   1.307 +                out.print("    ");
   1.308 +            }
   1.309 +            out.print("   throws ");
   1.310 +            int k;
   1.311 +            int l = exc_index_table.length;
   1.312 +
   1.313 +            for (k=0; k<l; k++) {
   1.314 +                out.print(javaclassname(cls.getClassName(exc_index_table[k])));
   1.315 +                if (k<l-1) out.print(", ");
   1.316 +            }
   1.317 +        }
   1.318 +    }
   1.319 +
   1.320 +    /**
   1.321 +     * Print code sequence.
   1.322 +     */
   1.323 +    public void  printcodeSequence(MethodData method){
   1.324 +        code = method.getCode();
   1.325 +        if(code != null){
   1.326 +            out.println("  Code:");
   1.327 +            if(env.showVerbose){
   1.328 +                printVerboseHeader(method);
   1.329 +            }
   1.330 +
   1.331 +            for (int pc=0; pc < code.length; ) {
   1.332 +                out.print("   "+pc+":\t");
   1.333 +                pc=pc+printInstr(pc);
   1.334 +                out.println();
   1.335 +            }
   1.336 +        }
   1.337 +    }
   1.338 +
   1.339 +    /**
   1.340 +     * Print instructions.
   1.341 +     */
   1.342 +    public int printInstr(int pc){
   1.343 +        int opcode = getUbyte(pc);
   1.344 +        int opcode2;
   1.345 +        String mnem;
   1.346 +        switch (opcode) {
   1.347 +        case opc_nonpriv:
   1.348 +        case opc_priv:
   1.349 +            opcode2 = getUbyte(pc+1);
   1.350 +            mnem=Tables.opcName((opcode<<8)+opcode2);
   1.351 +            if (mnem==null)
   1.352 +                // assume all (even nonexistent) priv and nonpriv instructions
   1.353 +                // are 2 bytes long
   1.354 +                mnem=Tables.opcName(opcode)+" "+opcode2;
   1.355 +            out.print(mnem);
   1.356 +            return 2;
   1.357 +        case opc_wide: {
   1.358 +            opcode2 = getUbyte(pc+1);
   1.359 +            mnem=Tables.opcName((opcode<<8)+opcode2);
   1.360 +            if (mnem==null) {
   1.361 +                // nonexistent opcode - but we have to print something
   1.362 +                out.print("bytecode "+opcode);
   1.363 +                return 1;
   1.364 +            }
   1.365 +            out.print(mnem+" "+getUShort(pc+2));
   1.366 +            if (opcode2==opc_iinc) {
   1.367 +                out.print(", "+getShort(pc+4));
   1.368 +                return 6;
   1.369 +            }
   1.370 +            return 4;
   1.371 +        }
   1.372 +        }
   1.373 +        mnem=Tables.opcName(opcode);
   1.374 +        if (mnem==null) {
   1.375 +            // nonexistent opcode - but we have to print something
   1.376 +            out.print("bytecode "+opcode);
   1.377 +            return 1;
   1.378 +        }
   1.379 +        if (opcode>opc_jsr_w) {
   1.380 +            // pseudo opcodes should be printed as bytecodes
   1.381 +            out.print("bytecode "+opcode);
   1.382 +            return 1;
   1.383 +        }
   1.384 +        out.print(Tables.opcName(opcode));
   1.385 +        switch (opcode) {
   1.386 +        case opc_aload: case opc_astore:
   1.387 +        case opc_fload: case opc_fstore:
   1.388 +        case opc_iload: case opc_istore:
   1.389 +        case opc_lload: case opc_lstore:
   1.390 +        case opc_dload: case opc_dstore:
   1.391 +        case opc_ret:
   1.392 +            out.print("\t"+getUbyte(pc+1));
   1.393 +            return  2;
   1.394 +        case opc_iinc:
   1.395 +            out.print("\t"+getUbyte(pc+1)+", "+getbyte(pc+2));
   1.396 +            return  3;
   1.397 +        case opc_tableswitch:{
   1.398 +            int tb=align(pc+1);
   1.399 +            int default_skip = getInt(tb); /* default skip pamount */
   1.400 +            int low = getInt(tb+4);
   1.401 +            int high = getInt(tb+8);
   1.402 +            int count = high - low;
   1.403 +            out.print("{ //"+low+" to "+high);
   1.404 +            for (int i = 0; i <= count; i++)
   1.405 +                out.print( "\n\t\t" + (i+low) + ": "+lP+(pc+getInt(tb+12+4*i))+";");
   1.406 +            out.print("\n\t\tdefault: "+lP+(default_skip + pc) + " }");
   1.407 +            return tb-pc+16+count*4;
   1.408 +        }
   1.409 +
   1.410 +        case opc_lookupswitch:{
   1.411 +            int tb=align(pc+1);
   1.412 +            int default_skip = getInt(tb);
   1.413 +            int npairs = getInt(tb+4);
   1.414 +            out.print("{ //"+npairs);
   1.415 +            for (int i = 1; i <= npairs; i++)
   1.416 +                out.print("\n\t\t"+getInt(tb+i*8)
   1.417 +                                 +": "+lP+(pc+getInt(tb+4+i*8))+";"
   1.418 +                                 );
   1.419 +            out.print("\n\t\tdefault: "+lP+(default_skip + pc) + " }");
   1.420 +            return tb-pc+(npairs+1)*8;
   1.421 +        }
   1.422 +        case opc_newarray:
   1.423 +            int type=getUbyte(pc+1);
   1.424 +            switch (type) {
   1.425 +            case T_BOOLEAN:out.print(" boolean");break;
   1.426 +            case T_BYTE:   out.print(" byte");   break;
   1.427 +            case T_CHAR:   out.print(" char");   break;
   1.428 +            case T_SHORT:  out.print(" short");  break;
   1.429 +            case T_INT:    out.print(" int");    break;
   1.430 +            case T_LONG:   out.print(" long");   break;
   1.431 +            case T_FLOAT:  out.print(" float");  break;
   1.432 +            case T_DOUBLE: out.print(" double"); break;
   1.433 +            case T_CLASS:  out.print(" class"); break;
   1.434 +            default:       out.print(" BOGUS TYPE:"+type);
   1.435 +            }
   1.436 +            return 2;
   1.437 +
   1.438 +        case opc_anewarray: {
   1.439 +            int index =  getUShort(pc+1);
   1.440 +            out.print("\t#"+index+"; //");
   1.441 +            PrintConstant(index);
   1.442 +            return 3;
   1.443 +        }
   1.444 +
   1.445 +        case opc_sipush:
   1.446 +            out.print("\t"+getShort(pc+1));
   1.447 +            return 3;
   1.448 +
   1.449 +        case opc_bipush:
   1.450 +            out.print("\t"+getbyte(pc+1));
   1.451 +            return 2;
   1.452 +
   1.453 +        case opc_ldc: {
   1.454 +            int index = getUbyte(pc+1);
   1.455 +            out.print("\t#"+index+"; //");
   1.456 +            PrintConstant(index);
   1.457 +            return 2;
   1.458 +        }
   1.459 +
   1.460 +        case opc_ldc_w: case opc_ldc2_w:
   1.461 +        case opc_instanceof: case opc_checkcast:
   1.462 +        case opc_new:
   1.463 +        case opc_putstatic: case opc_getstatic:
   1.464 +        case opc_putfield: case opc_getfield:
   1.465 +        case opc_invokevirtual:
   1.466 +        case opc_invokespecial:
   1.467 +        case opc_invokestatic: {
   1.468 +            int index = getUShort(pc+1);
   1.469 +            out.print("\t#"+index+"; //");
   1.470 +            PrintConstant(index);
   1.471 +            return 3;
   1.472 +        }
   1.473 +
   1.474 +        case opc_invokeinterface: {
   1.475 +            int index = getUShort(pc+1), nargs=getUbyte(pc+3);
   1.476 +            out.print("\t#"+index+",  "+nargs+"; //");
   1.477 +            PrintConstant(index);
   1.478 +            return 5;
   1.479 +        }
   1.480 +
   1.481 +        case opc_multianewarray: {
   1.482 +            int index = getUShort(pc+1), dimensions=getUbyte(pc+3);
   1.483 +            out.print("\t#"+index+",  "+dimensions+"; //");
   1.484 +            PrintConstant(index);
   1.485 +            return 4;
   1.486 +        }
   1.487 +        case opc_jsr: case opc_goto:
   1.488 +        case opc_ifeq: case opc_ifge: case opc_ifgt:
   1.489 +        case opc_ifle: case opc_iflt: case opc_ifne:
   1.490 +        case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmpge:
   1.491 +        case opc_if_icmpgt: case opc_if_icmple: case opc_if_icmplt:
   1.492 +        case opc_if_acmpeq: case opc_if_acmpne:
   1.493 +        case opc_ifnull: case opc_ifnonnull:
   1.494 +            out.print("\t"+lP+(pc + getShort(pc+1)) );
   1.495 +            return 3;
   1.496 +
   1.497 +        case opc_jsr_w:
   1.498 +        case opc_goto_w:
   1.499 +            out.print("\t"+lP+(pc + getInt(pc+1)));
   1.500 +            return 5;
   1.501 +
   1.502 +        default:
   1.503 +            return 1;
   1.504 +        }
   1.505 +    }
   1.506 +    /**
   1.507 +     * Print code attribute details.
   1.508 +     */
   1.509 +    public void printVerboseHeader(MethodData method) {
   1.510 +        int argCount = method.getArgumentlength();
   1.511 +        if (!method.isStatic())
   1.512 +            ++argCount;  // for 'this'
   1.513 +
   1.514 +        out.println("   Stack=" + method.getMaxStack()
   1.515 +                           + ", Locals=" + method.getMaxLocals()
   1.516 +                           + ", Args_size=" + argCount);
   1.517 +
   1.518 +    }
   1.519 +
   1.520 +
   1.521 +    /**
   1.522 +     * Print the exception table for this method code
   1.523 +     */
   1.524 +    void printExceptionTable(MethodData method){//throws IOException
   1.525 +        Vector exception_table = method.getexception_table();
   1.526 +        if (exception_table.size() > 0) {
   1.527 +            out.println("  Exception table:");
   1.528 +            out.println("   from   to  target type");
   1.529 +            for (int idx = 0; idx < exception_table.size(); ++idx) {
   1.530 +                TrapData handler = (TrapData)exception_table.elementAt(idx);
   1.531 +                printFixedWidthInt(handler.start_pc, 6);
   1.532 +                printFixedWidthInt(handler.end_pc, 6);
   1.533 +                printFixedWidthInt(handler.handler_pc, 6);
   1.534 +                out.print("   ");
   1.535 +                int catch_cpx = handler.catch_cpx;
   1.536 +                if (catch_cpx == 0) {
   1.537 +                    out.println("any");
   1.538 +                }else {
   1.539 +                    out.print("Class ");
   1.540 +                    out.println(cls.getClassName(catch_cpx));
   1.541 +                    out.println("");
   1.542 +                }
   1.543 +            }
   1.544 +        }
   1.545 +    }
   1.546 +
   1.547 +    /**
   1.548 +     * Print LineNumberTable attribute information.
   1.549 +     */
   1.550 +    public void printLineNumTable(MethodData method) {
   1.551 +        int numlines = method.getnumlines();
   1.552 +        Vector lin_num_tb = method.getlin_num_tb();
   1.553 +        if( lin_num_tb.size() > 0){
   1.554 +            out.println("  LineNumberTable: ");
   1.555 +            for (int i=0; i<numlines; i++) {
   1.556 +                LineNumData linnumtb_entry=(LineNumData)lin_num_tb.elementAt(i);
   1.557 +                out.println("   line " + linnumtb_entry.line_number + ": "
   1.558 +                               + linnumtb_entry.start_pc);
   1.559 +            }
   1.560 +        }
   1.561 +        out.println();
   1.562 +    }
   1.563 +
   1.564 +    /**
   1.565 +     * Print LocalVariableTable attribute information.
   1.566 +     */
   1.567 +    public void printLocVarTable(MethodData method){
   1.568 +        int siz = method.getloc_var_tbsize();
   1.569 +        if(siz > 0){
   1.570 +            out.println("  LocalVariableTable: ");
   1.571 +            out.print("   ");
   1.572 +            out.println("Start  Length  Slot  Name   Signature");
   1.573 +        }
   1.574 +        Vector loc_var_tb = method.getloc_var_tb();
   1.575 +
   1.576 +        for (int i=0; i<siz; i++) {
   1.577 +            LocVarData entry=(LocVarData)loc_var_tb.elementAt(i);
   1.578 +
   1.579 +            out.println("   "+entry.start_pc+"      "+entry.length+"      "+
   1.580 +                               entry.slot+"    "+cls.StringValue(entry.name_cpx)  +
   1.581 +                               "       "+cls.StringValue(entry.sig_cpx));
   1.582 +        }
   1.583 +        out.println();
   1.584 +    }
   1.585 +
   1.586 +    /**
   1.587 +     * Print StackMap attribute information.
   1.588 +     */
   1.589 +    public void printStackMap(MethodData method) {
   1.590 +        StackMapData[] stack_map_tb = method.getStackMap();
   1.591 +        int number_of_entries = stack_map_tb.length;
   1.592 +        if (number_of_entries > 0) {
   1.593 +            out.println("  StackMap: number_of_entries = " + number_of_entries);
   1.594 +
   1.595 +            for (StackMapData frame : stack_map_tb) {
   1.596 +                frame.print(this);
   1.597 +            }
   1.598 +        }
   1.599 +       out.println();
   1.600 +    }
   1.601 +
   1.602 +    /**
   1.603 +     * Print StackMapTable attribute information.
   1.604 +     */
   1.605 +    public void printStackMapTable(MethodData method) {
   1.606 +        StackMapTableData[] stack_map_tb = method.getStackMapTable();
   1.607 +        int number_of_entries = stack_map_tb.length;
   1.608 +        if (number_of_entries > 0) {
   1.609 +            out.println("  StackMapTable: number_of_entries = " + number_of_entries);
   1.610 +
   1.611 +            for (StackMapTableData frame : stack_map_tb) {
   1.612 +                frame.print(this);
   1.613 +            }
   1.614 +        }
   1.615 +        out.println();
   1.616 +    }
   1.617 +
   1.618 +    void printMap(String name, int[] map) {
   1.619 +        out.print(name);
   1.620 +        for (int i=0; i<map.length; i++) {
   1.621 +            int fulltype = map[i];
   1.622 +            int type = fulltype & 0xFF;
   1.623 +            int argument = fulltype >> 8;
   1.624 +            switch (type) {
   1.625 +                case ITEM_Object:
   1.626 +                    out.print(" ");
   1.627 +                    PrintConstant(argument);
   1.628 +                    break;
   1.629 +                case ITEM_NewObject:
   1.630 +                    out.print(" " + Tables.mapTypeName(type));
   1.631 +                    out.print(" " + argument);
   1.632 +                    break;
   1.633 +                default:
   1.634 +                    out.print(" " + Tables.mapTypeName(type));
   1.635 +            }
   1.636 +            out.print( (i==(map.length-1)? ' ' : ','));
   1.637 +        }
   1.638 +        out.println("]");
   1.639 +    }
   1.640 +
   1.641 +    /**
   1.642 +     * Print ConstantValue attribute information.
   1.643 +     */
   1.644 +    public void printConstantValue(FieldData field){
   1.645 +        out.print("  Constant value: ");
   1.646 +        int cpx = (field.getConstantValueIndex());
   1.647 +        byte tag=0;
   1.648 +        try {
   1.649 +            tag=cls.getTag(cpx);
   1.650 +
   1.651 +        } catch (IndexOutOfBoundsException e) {
   1.652 +            out.print("Error:");
   1.653 +            return;
   1.654 +        }
   1.655 +        switch (tag) {
   1.656 +        case CONSTANT_METHOD:
   1.657 +        case CONSTANT_INTERFACEMETHOD:
   1.658 +        case CONSTANT_FIELD: {
   1.659 +            CPX2 x = (CPX2)(cls.getCpoolEntry(cpx));
   1.660 +            if (x.cpx1 == cls.getthis_cpx()) {
   1.661 +                // don't print class part for local references
   1.662 +                cpx=x.cpx2;
   1.663 +            }
   1.664 +        }
   1.665 +        }
   1.666 +        out.print(cls.TagString(tag)+" "+ cls.StringValue(cpx));
   1.667 +    }
   1.668 +
   1.669 +    /**
   1.670 +     * Print InnerClass attribute information.
   1.671 +     */
   1.672 +    public void printInnerClasses(){//throws ioexception
   1.673 +
   1.674 +        InnerClassData[] innerClasses = cls.getInnerClasses();
   1.675 +        if(innerClasses != null){
   1.676 +            if(innerClasses.length > 0){
   1.677 +                out.print("  ");
   1.678 +                out.println("InnerClass: ");
   1.679 +                for(int i = 0 ; i < innerClasses.length; i++){
   1.680 +                    out.print("   ");
   1.681 +                    //access
   1.682 +                    String[] accflags = innerClasses[i].getAccess();
   1.683 +                    if(checkAccess(accflags)){
   1.684 +                        printAccess(accflags);
   1.685 +                        if (innerClasses[i].inner_name_index!=0) {
   1.686 +                            out.print("#"+innerClasses[i].inner_name_index+"= ");
   1.687 +                        }
   1.688 +                        out.print("#"+innerClasses[i].inner_class_info_index);
   1.689 +                        if (innerClasses[i].outer_class_info_index!=0) {
   1.690 +                            out.print(" of #"+innerClasses[i].outer_class_info_index);
   1.691 +                        }
   1.692 +                        out.print("; //");
   1.693 +                        if (innerClasses[i].inner_name_index!=0) {
   1.694 +                            out.print(cls.getName(innerClasses[i].inner_name_index)+"=");
   1.695 +                        }
   1.696 +                        PrintConstant(innerClasses[i].inner_class_info_index);
   1.697 +                        if (innerClasses[i].outer_class_info_index!=0) {
   1.698 +                            out.print(" of ");
   1.699 +                            PrintConstant(innerClasses[i].outer_class_info_index);
   1.700 +                        }
   1.701 +                        out.println();
   1.702 +                    }
   1.703 +                }
   1.704 +
   1.705 +            }
   1.706 +        }
   1.707 +    }
   1.708 +
   1.709 +    /**
   1.710 +     * Print constant pool information.
   1.711 +     */
   1.712 +    public void printcp(){
   1.713 +        int cpx = 1 ;
   1.714 +
   1.715 +        while (cpx < cls.getCpoolCount()) {
   1.716 +            out.print("const #"+cpx+" = ");
   1.717 +            cpx+=PrintlnConstantEntry(cpx);
   1.718 +        }
   1.719 +        out.println();
   1.720 +    }
   1.721 +
   1.722 +    /**
   1.723 +     * Print constant pool entry information.
   1.724 +     */
   1.725 +    public int PrintlnConstantEntry(int cpx) {
   1.726 +        int size=1;
   1.727 +        byte tag=0;
   1.728 +        try {
   1.729 +            tag=cls.getTag(cpx);
   1.730 +        } catch (IndexOutOfBoundsException e) {
   1.731 +            out.println("  <Incorrect CP index>");
   1.732 +            return 1;
   1.733 +        }
   1.734 +        out.print(cls.StringTag(cpx)+"\t");
   1.735 +        Object x=cls.getCpoolEntryobj(cpx);
   1.736 +        if (x==null) {
   1.737 +            switch (tag) {
   1.738 +            case CONSTANT_LONG:
   1.739 +            case CONSTANT_DOUBLE:
   1.740 +                size=2;
   1.741 +            }
   1.742 +            out.println("null;");
   1.743 +            return size;
   1.744 +        }
   1.745 +        String str=cls.StringValue(cpx);
   1.746 +
   1.747 +        switch (tag) {
   1.748 +        case CONSTANT_CLASS:
   1.749 +        case CONSTANT_STRING:
   1.750 +            out.println("#"+(((CPX)x).cpx)+";\t//  "+str);
   1.751 +            break;
   1.752 +        case CONSTANT_FIELD:
   1.753 +        case CONSTANT_METHOD:
   1.754 +        case CONSTANT_INTERFACEMETHOD:
   1.755 +            out.println("#"+((CPX2)x).cpx1+".#"+((CPX2)x).cpx2+";\t//  "+str);
   1.756 +            break;
   1.757 +        case CONSTANT_NAMEANDTYPE:
   1.758 +            out.println("#"+((CPX2)x).cpx1+":#"+((CPX2)x).cpx2+";//  "+str);
   1.759 +            break;
   1.760 +        case CONSTANT_LONG:
   1.761 +        case CONSTANT_DOUBLE:
   1.762 +            size=2;
   1.763 +        default:
   1.764 +            out.println(str+";");
   1.765 +        }
   1.766 +        return size;
   1.767 +    }
   1.768 +
   1.769 +    /**
   1.770 +     * Checks access of class, field or method.
   1.771 +     */
   1.772 +    public boolean checkAccess(String accflags[]){
   1.773 +
   1.774 +        boolean ispublic = false;
   1.775 +        boolean isprotected = false;
   1.776 +        boolean isprivate = false;
   1.777 +        boolean ispackage = false;
   1.778 +
   1.779 +        for(int i= 0; i < accflags.length; i++){
   1.780 +            if(accflags[i].equals("public")) ispublic = true;
   1.781 +            else if (accflags[i].equals("protected")) isprotected = true;
   1.782 +            else if (accflags[i].equals("private")) isprivate = true;
   1.783 +        }
   1.784 +
   1.785 +        if(!(ispublic || isprotected || isprivate)) ispackage = true;
   1.786 +
   1.787 +        if((env.showAccess == env.PUBLIC) && (isprotected || isprivate || ispackage)) return false;
   1.788 +        else if((env.showAccess == env.PROTECTED) && (isprivate || ispackage)) return false;
   1.789 +        else if((env.showAccess == env.PACKAGE) && (isprivate)) return false;
   1.790 +        else return true;
   1.791 +    }
   1.792 +
   1.793 +    /**
   1.794 +     * Prints access of class, field or method.
   1.795 +     */
   1.796 +    public void printAccess(String []accflags){
   1.797 +        for(int j = 0; j < accflags.length; j++){
   1.798 +            out.print(accflags[j]+" ");
   1.799 +        }
   1.800 +    }
   1.801 +
   1.802 +    /**
   1.803 +     * Print an integer so that it takes 'length' characters in
   1.804 +     * the output.  Temporary until formatting code is stable.
   1.805 +     */
   1.806 +    public void printFixedWidthInt(long x, int length) {
   1.807 +        CharArrayWriter baStream = new CharArrayWriter();
   1.808 +        PrintWriter pStream = new PrintWriter(baStream);
   1.809 +        pStream.print(x);
   1.810 +        String str = baStream.toString();
   1.811 +        for (int cnt = length - str.length(); cnt > 0; --cnt)
   1.812 +            out.print(' ');
   1.813 +        out.print(str);
   1.814 +    }
   1.815 +
   1.816 +    protected int getbyte (int pc) {
   1.817 +        return code[pc];
   1.818 +    }
   1.819 +
   1.820 +    protected int getUbyte (int pc) {
   1.821 +        return code[pc]&0xFF;
   1.822 +    }
   1.823 +
   1.824 +    int getShort (int pc) {
   1.825 +        return (code[pc]<<8) | (code[pc+1]&0xFF);
   1.826 +    }
   1.827 +
   1.828 +    int getUShort (int pc) {
   1.829 +        return ((code[pc]<<8) | (code[pc+1]&0xFF))&0xFFFF;
   1.830 +    }
   1.831 +
   1.832 +    protected int getInt (int pc) {
   1.833 +        return (getShort(pc)<<16) | (getShort(pc+2)&0xFFFF);
   1.834 +    }
   1.835 +
   1.836 +    /**
   1.837 +     * Print constant value at that index.
   1.838 +     */
   1.839 +    void PrintConstant(int cpx) {
   1.840 +        if (cpx==0) {
   1.841 +            out.print("#0");
   1.842 +            return;
   1.843 +        }
   1.844 +        byte tag=0;
   1.845 +        try {
   1.846 +            tag=cls.getTag(cpx);
   1.847 +
   1.848 +        } catch (IndexOutOfBoundsException e) {
   1.849 +            out.print("#"+cpx);
   1.850 +            return;
   1.851 +        }
   1.852 +        switch (tag) {
   1.853 +        case CONSTANT_METHOD:
   1.854 +        case CONSTANT_INTERFACEMETHOD:
   1.855 +        case CONSTANT_FIELD: {
   1.856 +            // CPX2 x=(CPX2)(cpool[cpx]);
   1.857 +            CPX2 x = (CPX2)(cls.getCpoolEntry(cpx));
   1.858 +            if (x.cpx1 == cls.getthis_cpx()) {
   1.859 +                // don't print class part for local references
   1.860 +                cpx=x.cpx2;
   1.861 +            }
   1.862 +        }
   1.863 +        }
   1.864 +        out.print(cls.TagString(tag)+" "+ cls.StringValue(cpx));
   1.865 +    }
   1.866 +
   1.867 +    protected static int  align (int n) {
   1.868 +        return (n+3) & ~3 ;
   1.869 +    }
   1.870 +
   1.871 +    public void printend(){
   1.872 +        out.println("}");
   1.873 +        out.println();
   1.874 +    }
   1.875 +
   1.876 +    public String javaclassname(String name){
   1.877 +        return name.replace('/','.');
   1.878 +    }
   1.879 +
   1.880 +    /**
   1.881 +     * Print attribute data in hex.
   1.882 +     */
   1.883 +    public void printAttrData(AttrData attr){
   1.884 +        byte []data = attr.getData();
   1.885 +        int i = 0;
   1.886 +        int j = 0;
   1.887 +        out.print("  "+attr.getAttrName()+": ");
   1.888 +        out.println("length = " + cls.toHex(attr.datalen));
   1.889 +
   1.890 +        out.print("   ");
   1.891 +
   1.892 +
   1.893 +        while (i < data.length){
   1.894 +            String databytestring = cls.toHex(data[i]);
   1.895 +            if(databytestring.equals("0x")) out.print("00");
   1.896 +            else if(databytestring.substring(2).length() == 1){
   1.897 +                out.print("0"+databytestring.substring(2));
   1.898 +            } else{
   1.899 +                out.print(databytestring.substring(2));
   1.900 +            }
   1.901 +
   1.902 +             j++;
   1.903 +            if(j == 16) {
   1.904 +                out.println();
   1.905 +                out.print("   ");
   1.906 +                j = 0;
   1.907 +            }
   1.908 +            else out.print(" ");
   1.909 +            i++;
   1.910 +        }
   1.911 +        out.println();
   1.912 +    }
   1.913 +}