📄 codehtml.java
字号:
break; /* Array of references. */ case ANEWARRAY: index = bytes.readShort(); buf.append(constant_html.referenceConstant(index)); break; /* Multidimensional array of references. */ case MULTIANEWARRAY: index = bytes.readShort(); int dimensions = bytes.readByte(); buf.append(constant_html.referenceConstant(index) + ":" + dimensions + "-dimensional"); break; /* Increment local variable. */ case IINC: if(wide) { vindex = bytes.readShort(); constant = bytes.readShort(); wide = false; } else { vindex = bytes.readUnsignedByte(); constant = bytes.readByte(); } buf.append("%" + vindex + " " + constant); break; default: if(NO_OF_OPERANDS[opcode] > 0) { for(int i=0; i < TYPE_OF_OPERANDS[opcode].length; i++) { switch(TYPE_OF_OPERANDS[opcode][i]) { case T_BYTE: buf.append(bytes.readUnsignedByte()); break; case T_SHORT: // Either branch or index buf.append(bytes.readShort()); break; case T_INT: buf.append(bytes.readInt()); break; default: // Never reached System.err.println("Unreachable default case reached!"); System.exit(-1); } buf.append(" "); } } } buf.append("</TD>"); return buf.toString(); } /** * Find all target addresses in code, so that they can be marked * with <A NAME = ...>. 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 } } } /** * 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> " + "<A NAME=method" + method_number + ">" + Class2HTML.referenceType(type) + "</A> <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(", "); } 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) // last loop 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>"); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -