库,允许轻松打印字节码指令*包括*参数



我正在寻找一个库,将容易让我看到一个方法的给定字节码。例子:

ALOAD 0
INVOKEVIRTUAL ns/c.m ()I
IRETURN

我都试过了:

    ASM:我实际上可以让它打印指令和参数,但是我很难理解它的整个访问者范式,也就是说,我所做的最好的是打印整个类。
  • BCEL:可以让它打印指令,但没有参数。
  • JavaAssist:可以让它打印指令,但没有参数

查看TraceClassVisitorTraceMethodVisitor的ASM源代码,以获得打印字节码细节的示例。

下面是一个简单的测试类:
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.util.TraceClassVisitor;
public class Main {
    public static void main(String[] args) throws Exception {
        if (1 > args.length) {
            System.err.println("No arguments.");
            return;
        }
        InputStream is = Main.class.getResourceAsStream(args[0]);
        ClassReader cr = new ClassReader(is);
        cr.accept(new TraceClassVisitor(new PrintWriter(System.out)), 0);
    }
}

当传递Main.class作为参数时,输出:

// class version 50.0 (50)
// access flags 0x21
public class Main {
  // compiled from: Main.java
  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 11 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
    MAXSTACK = 1
    MAXLOCALS = 1
  // access flags 0x9
  public static main([Ljava/lang/String;)V throws java/lang/Exception 
   L0
    LINENUMBER 13 L0
    ICONST_1
    ALOAD 0
    ARRAYLENGTH
    IF_ICMPLE L1
   L2
    LINENUMBER 14 L2
    GETSTATIC java/lang/System.err : Ljava/io/PrintStream;
    LDC "No arguments."
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L3
    LINENUMBER 15 L3
    RETURN
   L1
    LINENUMBER 17 L1
   FRAME SAME
    LDC LMain;.class
    ALOAD 0
    ICONST_0
    AALOAD
    INVOKEVIRTUAL java/lang/Class.getResourceAsStream (Ljava/lang/String;)Ljava/io/InputStream;
    ASTORE 1
   L4
    LINENUMBER 18 L4
    NEW org/objectweb/asm/ClassReader
    DUP
    ALOAD 1
    INVOKESPECIAL org/objectweb/asm/ClassReader.<init> (Ljava/io/InputStream;)V
    ASTORE 2
   L5
    LINENUMBER 19 L5
    ALOAD 2
    NEW org/objectweb/asm/util/TraceClassVisitor
    DUP
    NEW java/io/PrintWriter
    DUP
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    INVOKESPECIAL java/io/PrintWriter.<init> (Ljava/io/OutputStream;)V
    INVOKESPECIAL org/objectweb/asm/util/TraceClassVisitor.<init> (Ljava/io/PrintWriter;)V
    ICONST_0
    INVOKEVIRTUAL org/objectweb/asm/ClassReader.accept (Lorg/objectweb/asm/ClassVisitor;I)V
   L6
    LINENUMBER 28 L6
    RETURN
    MAXSTACK = 6
    MAXLOCALS = 3
}

其中ASM是唯一支持最新Java版本的。关于访问者,您可能需要阅读本教程。它是为ASM API的旧版本编写的,但是访问者的概念仍然相同。

相关内容

  • 没有找到相关文章

最新更新