Exemple #1
0
 /** Write a single method with the byte code associated with it. */
 private void writeMethod(Method method, int method_number) throws IOException {
   // Get raw signature
   String signature = method.getSignature();
   // Get array of strings containing the argument types
   String[] args = Utility.methodSignatureArgumentTypes(signature, false);
   // Get return type string
   String type = Utility.methodSignatureReturnType(signature, false);
   // Get method name
   String name = method.getName();
   String html_name = Class2HTML.toHTML(name);
   // Get method's access flags
   String access = Utility.accessToString(method.getAccessFlags());
   access = Utility.replace(access, " ", " ");
   // Get the method's attributes, the Code Attribute in particular
   Attribute[] attributes = method.getAttributes();
   file.print(
       "<P><B><FONT COLOR=\"#FF0000\">"
           + access
           + "</FONT>&nbsp;"
           + "<A NAME=method"
           + method_number
           + ">"
           + Class2HTML.referenceType(type)
           + "</A>&nbsp<A HREF=\""
           + class_name
           + "_methods.html#method"
           + method_number
           + "\" TARGET=Methods>"
           + html_name
           + "</A>(");
   for (int i = 0; i < args.length; i++) {
     file.print(Class2HTML.referenceType(args[i]));
     if (i < args.length - 1) {
       file.print(",&nbsp;");
     }
   }
   file.println(")</B></P>");
   Code c = null;
   byte[] code = null;
   if (attributes.length > 0) {
     file.print("<H4>Attributes</H4><UL>\n");
     for (int i = 0; i < attributes.length; i++) {
       byte tag = attributes[i].getTag();
       if (tag != ATTR_UNKNOWN) {
         file.print(
             "<LI><A HREF=\""
                 + class_name
                 + "_attributes.html#method"
                 + method_number
                 + "@"
                 + i
                 + "\" TARGET=Attributes>"
                 + ATTRIBUTE_NAMES[tag]
                 + "</A></LI>\n");
       } else {
         file.print("<LI>" + attributes[i] + "</LI>");
       }
       if (tag == ATTR_CODE) {
         c = (Code) attributes[i];
         Attribute[] attributes2 = c.getAttributes();
         code = c.getCode();
         file.print("<UL>");
         for (int j = 0; j < attributes2.length; j++) {
           tag = attributes2[j].getTag();
           file.print(
               "<LI><A HREF=\""
                   + class_name
                   + "_attributes.html#"
                   + "method"
                   + method_number
                   + "@"
                   + i
                   + "@"
                   + j
                   + "\" TARGET=Attributes>"
                   + ATTRIBUTE_NAMES[tag]
                   + "</A></LI>\n");
         }
         file.print("</UL>");
       }
     }
     file.println("</UL>");
   }
   if (code != null) { // No code, an abstract method, e.g.
     // System.out.println(name + "\n" + Utility.codeToString(code, constant_pool, 0, -1));
     // Print the byte code
     ByteSequence stream = new ByteSequence(code);
     stream.mark(stream.available());
     findGotos(stream, method, c);
     stream.reset();
     file.println(
         "<TABLE BORDER=0><TR><TH ALIGN=LEFT>Byte<BR>offset</TH>"
             + "<TH ALIGN=LEFT>Instruction</TH><TH ALIGN=LEFT>Argument</TH>");
     for (int i = 0; stream.available() > 0; i++) {
       int offset = stream.getIndex();
       String str = codeToHTML(stream, method_number);
       String anchor = "";
       /* Set an anchor mark if this line is targetted by a goto, jsr, etc.
        * Defining an anchor for every line is very inefficient!
        */
       if (goto_set.get(offset)) {
         anchor = "<A NAME=code" + method_number + "@" + offset + "></A>";
       }
       String anchor2;
       if (stream.getIndex() == code.length) {
         anchor2 = "<A NAME=code" + method_number + "@" + code.length + ">" + offset + "</A>";
       } else {
         anchor2 = "" + offset;
       }
       file.println("<TR VALIGN=TOP><TD>" + anchor2 + "</TD><TD>" + anchor + str + "</TR>");
     }
     // Mark last line, may be targetted from Attributes window
     file.println("<TR><TD> </A></TD></TR>");
     file.println("</TABLE>");
   }
 }
Exemple #2
0
 /**
  * Find all target addresses in code, so that they can be marked with &lt;A NAME = ...&gt;. Target
  * addresses are kept in an BitSet object.
  */
 private final void findGotos(ByteSequence bytes, Method method, Code code) throws IOException {
   int index;
   goto_set = new BitSet(bytes.available());
   int opcode;
   /* First get Code attribute from method and the exceptions handled
    * (try .. catch) in this method. We only need the line number here.
    */
   if (code != null) {
     CodeException[] ce = code.getExceptionTable();
     int len = ce.length;
     for (int i = 0; i < len; i++) {
       goto_set.set(ce[i].getStartPC());
       goto_set.set(ce[i].getEndPC());
       goto_set.set(ce[i].getHandlerPC());
     }
     // Look for local variables and their range
     Attribute[] attributes = code.getAttributes();
     for (int i = 0; i < attributes.length; i++) {
       if (attributes[i].getTag() == ATTR_LOCAL_VARIABLE_TABLE) {
         LocalVariable[] vars = ((LocalVariableTable) attributes[i]).getLocalVariableTable();
         for (int j = 0; j < vars.length; j++) {
           int start = vars[j].getStartPC();
           int end = (int) (start + vars[j].getLength());
           goto_set.set(start);
           goto_set.set(end);
         }
         break;
       }
     }
   }
   // Get target addresses from GOTO, JSR, TABLESWITCH, etc.
   for (int i = 0; bytes.available() > 0; i++) {
     opcode = bytes.readUnsignedByte();
     // System.out.println(OPCODE_NAMES[opcode]);
     switch (opcode) {
       case TABLESWITCH:
       case LOOKUPSWITCH:
         // bytes.readByte(); // Skip already read byte
         int remainder = bytes.getIndex() % 4;
         int no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder;
         int default_offset, offset;
         for (int j = 0; j < no_pad_bytes; j++) {
           bytes.readByte();
         }
         // Both cases have a field default_offset in common
         default_offset = bytes.readInt();
         if (opcode == TABLESWITCH) {
           int low = bytes.readInt();
           int high = bytes.readInt();
           offset = bytes.getIndex() - 12 - no_pad_bytes - 1;
           default_offset += offset;
           goto_set.set(default_offset);
           for (int j = 0; j < (high - low + 1); j++) {
             index = offset + bytes.readInt();
             goto_set.set(index);
           }
         } else { // LOOKUPSWITCH
           int npairs = bytes.readInt();
           offset = bytes.getIndex() - 8 - no_pad_bytes - 1;
           default_offset += offset;
           goto_set.set(default_offset);
           for (int j = 0; j < npairs; j++) {
             int match = bytes.readInt();
             index = offset + bytes.readInt();
             goto_set.set(index);
           }
         }
         break;
       case GOTO:
       case IFEQ:
       case IFGE:
       case IFGT:
       case IFLE:
       case IFLT:
       case IFNE:
       case IFNONNULL:
       case IFNULL:
       case IF_ACMPEQ:
       case IF_ACMPNE:
       case IF_ICMPEQ:
       case IF_ICMPGE:
       case IF_ICMPGT:
       case IF_ICMPLE:
       case IF_ICMPLT:
       case IF_ICMPNE:
       case JSR:
         // bytes.readByte(); // Skip already read byte
         index = bytes.getIndex() + bytes.readShort() - 1;
         goto_set.set(index);
         break;
       case GOTO_W:
       case JSR_W:
         // bytes.readByte(); // Skip already read byte
         index = bytes.getIndex() + bytes.readInt() - 1;
         goto_set.set(index);
         break;
       default:
         bytes.unreadByte();
         codeToHTML(bytes, 0); // Ignore output
     }
   }
 }