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 +}