⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codehtml.java

📁 Java Bytecode Editor 是一个 JAVA 的字节码反汇编和修改器。它可以很方便的修改已经编译成 Class 文件的 JAVA 文件。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package org.apache.bcel.util;

/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *    "Apache BCEL" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache BCEL", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import org.apache.bcel.classfile.*;
import java.io.*;
import java.util.BitSet;

/**
 * Convert code into HTML file.
 *
 * @version $Id: CodeHTML.java,v 1.3 2006/09/04 15:43:18 andos Exp $
 * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
 * 
 */
final class CodeHTML implements org.apache.bcel.Constants {
  private String 	class_name;     // name of current class
  //private Method[]	methods;	// Methods to print
  private PrintWriter	file;		// file to write to
  private BitSet    	goto_set;
  private ConstantPool  constant_pool;
  private ConstantHTML  constant_html;
  private static boolean wide=false;

  CodeHTML(String dir, String class_name,
	   Method[] methods, ConstantPool constant_pool,
	   ConstantHTML constant_html) throws IOException
  {
    this.class_name   	= class_name;
    //this.methods	= methods;
    this.constant_pool	= constant_pool;
    this.constant_html = constant_html;
    
    file = new PrintWriter(new FileOutputStream(dir + class_name + "_code.html"));
    file.println("<HTML><BODY BGCOLOR=\"#C0C0C0\">");
    
    for(int i=0; i < methods.length; i++)
      writeMethod(methods[i], i);
	     
    file.println("</BODY></HTML>");
    file.close();
  }
                                         
  /**
   * Disassemble a stream of byte codes and return the
   * string representation.
   *
   * @param  stream data input stream
   * @return String representation of byte code
   */
  private final String codeToHTML(ByteSequence bytes, int method_number)
       throws IOException
  {
    short        opcode = (short)bytes.readUnsignedByte();
    StringBuffer buf;
    String       name, signature;
    int          default_offset=0, low, high;
    int          index, class_index, vindex, constant;
    int[]        jump_table;
    int          no_pad_bytes=0, offset;

    buf = new StringBuffer("<TT>" + OPCODE_NAMES[opcode] + "</TT></TD><TD>");

    /* Special case: Skip (0-3) padding bytes, i.e., the
     * following bytes are 4-byte-aligned
     */
    if((opcode == TABLESWITCH) || (opcode == LOOKUPSWITCH)) {
      int remainder = bytes.getIndex() % 4;
      no_pad_bytes  = (remainder == 0)? 0 : 4 - remainder;

      for(int i=0; i < no_pad_bytes; i++)
	bytes.readByte();

      // Both cases have a field default_offset in common
      default_offset = bytes.readInt();
    }

    switch(opcode) {
    case TABLESWITCH:
      low  = bytes.readInt();
      high = bytes.readInt();

      offset = bytes.getIndex() - 12 - no_pad_bytes - 1;
      default_offset += offset;

      buf.append("<TABLE BORDER=1><TR>");

      // Print switch indices in first row (and default)
      jump_table = new int[high - low + 1];
      for(int i=0; i < jump_table.length; i++) {
	jump_table[i] = offset + bytes.readInt();

	buf.append("<TH>" + (low + i) + "</TH>");
      }
      buf.append("<TH>default</TH></TR>\n<TR>");

      // Print target and default indices in second row
      for(int i=0; i < jump_table.length; i++)
	buf.append("<TD><A HREF=\"#code" + method_number + "@" +
		   jump_table[i] + "\">" + jump_table[i] + "</A></TD>");
      buf.append("<TD><A HREF=\"#code" + method_number + "@" +
		 default_offset + "\">" + default_offset + "</A></TD></TR>\n</TABLE>\n");

      break;

      /* Lookup switch has variable length arguments.
       */
    case LOOKUPSWITCH:
      int npairs = bytes.readInt();
      offset = bytes.getIndex() - 8 - no_pad_bytes - 1;
      jump_table = new int[npairs];
      default_offset += offset;

      buf.append("<TABLE BORDER=1><TR>");

      // Print switch indices in first row (and default)
      for(int i=0; i < npairs; i++) {
	int match = bytes.readInt();

	jump_table[i] = offset + bytes.readInt();
	buf.append("<TH>" + match + "</TH>");
      }
      buf.append("<TH>default</TH></TR>\n<TR>");

      // Print target and default indices in second row
      for(int i=0; i < npairs; i++)
	buf.append("<TD><A HREF=\"#code" + method_number + "@" +
		   jump_table[i] + "\">" + jump_table[i] + "</A></TD>");
      buf.append("<TD><A HREF=\"#code" + method_number + "@" +
		 default_offset + "\">" + default_offset + "</A></TD></TR>\n</TABLE>\n");
      break;

      /* Two address bytes + offset from start of byte stream form the
       * jump target.
       */
    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:
	  
      index = (int)(bytes.getIndex() + bytes.readShort() - 1);
	  
      buf.append("<A HREF=\"#code" + method_number + "@" + index + "\">" + index + "</A>");
      break;
	  
      /* Same for 32-bit wide jumps
       */
    case GOTO_W: case JSR_W:
      int windex = bytes.getIndex() + bytes.readInt() - 1;
      buf.append("<A HREF=\"#code" + method_number + "@" + windex + "\">" +
		 windex + "</A>");
      break;

      /* Index byte references local variable (register)
       */
    case ALOAD:  case ASTORE: case DLOAD:  case DSTORE: case FLOAD:
    case FSTORE: case ILOAD:  case ISTORE: case LLOAD:  case LSTORE:
    case RET: 
      if(wide) {
	vindex = bytes.readShort();
	wide=false; // Clear flag
      }
      else
	vindex = bytes.readUnsignedByte();

      buf.append("%" + vindex);
      break;

      /*
       * Remember wide byte which is used to form a 16-bit address in the
       * following instruction. Relies on that the method is called again with
       * the following opcode.
       */
    case WIDE:
      wide      = true;
      buf.append("(wide)");
      break;

      /* Array of basic type.
       */
    case NEWARRAY:
      buf.append("<FONT COLOR=\"#00FF00\">" + TYPE_NAMES[bytes.readByte()] + "</FONT>");
      break;

      /* Access object/class fields.
       */
    case GETFIELD: case GETSTATIC: case PUTFIELD: case PUTSTATIC:
      index = bytes.readShort();
      ConstantFieldref c1 = (ConstantFieldref)constant_pool.getConstant(index, CONSTANT_Fieldref);

      class_index = c1.getClassIndex();
      name = constant_pool.getConstantString(class_index, CONSTANT_Class);
      name = Utility.compactClassName(name, false);

      index = c1.getNameAndTypeIndex();
      String field_name = constant_pool.constantToString(index, CONSTANT_NameAndType);

      if(name.equals(class_name)) { // Local field
	buf.append("<A HREF=\"" + class_name + "_methods.html#field" + field_name +
		   "\" TARGET=Methods>" + field_name + "</A>\n");
      }
      else
	buf.append(constant_html.referenceConstant(class_index) + "." + field_name);
	  		
      break;
	  
      /* Operands are references to classes in constant pool
       */
    case CHECKCAST: case INSTANCEOF: case NEW:
      index = bytes.readShort();
      buf.append(constant_html.referenceConstant(index));
      break;
   
      /* Operands are references to methods in constant pool
       */
    case INVOKESPECIAL: case INVOKESTATIC: case INVOKEVIRTUAL: case INVOKEINTERFACE:
      int m_index = bytes.readShort();
      String str;

      if(opcode == INVOKEINTERFACE) { // Special treatment needed
	//int nargs    = bytes.readUnsignedByte(); // Redundant
	//int reserved = bytes.readUnsignedByte(); // Reserved

	ConstantInterfaceMethodref c=(ConstantInterfaceMethodref)constant_pool.getConstant(m_index, CONSTANT_InterfaceMethodref);

	class_index = c.getClassIndex();
	str = constant_pool.constantToString(c);
	index = c.getNameAndTypeIndex();
      }
      else {
	ConstantMethodref c = (ConstantMethodref)constant_pool.getConstant(m_index, CONSTANT_Methodref);
	class_index = c.getClassIndex();
			
	str  = constant_pool.constantToString(c);
	index = c.getNameAndTypeIndex();
      }
	  		
      name = Class2HTML.referenceClass(class_index);
      str = Class2HTML.toHTML(constant_pool.constantToString(constant_pool.getConstant(index, CONSTANT_NameAndType)));

      // Get signature, i.e., types
      ConstantNameAndType c2 = (ConstantNameAndType)constant_pool.
	getConstant(index, CONSTANT_NameAndType);
      signature = constant_pool.constantToString(c2.getSignatureIndex(),
						 CONSTANT_Utf8);
      String[] args = Utility.methodSignatureArgumentTypes(signature, false);
      String   type = Utility.methodSignatureReturnType(signature, false);

      buf.append(name + ".<A HREF=\"" + class_name + "_cp.html#cp" + m_index + 
		 "\" TARGET=ConstantPool>" + str + "</A>" + "(");

      // List arguments
      for(int i=0; i < args.length; i++) {
	buf.append(Class2HTML.referenceType(args[i]));
	  
	if(i < args.length - 1)
	  buf.append(", ");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -