Библиотека, которая позволяет легко печатать инструкции байт-кода *, включая * параметры - PullRequest
4 голосов
/ 03 ноября 2011

Я ищу библиотеку, которая легко позволит мне увидеть заданный байт-код метода. Пример:

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

Я пробовал оба:

  • ASM: На самом деле я мог бы заставить его печатать инструкции и параметры, но у меня возникают трудности, когда я оборачиваюсь вокруг всей его парадигмы посетителей, то есть лучшее, что я сделал, - это красиво напечатал целый класс.
  • BCEL: может заставить его напечатать инструкции, но без параметров.
  • JavaAssist: может заставить его печатать инструкции, но без параметров.

Ответы [ 2 ]

4 голосов
/ 03 ноября 2011

Посмотрите на источник ASM для TraceClassVisitor и TraceMethodVisitor для примера печати деталей байт-кода.

Вот простой тестовый класс:

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
}
1 голос
/ 03 ноября 2011

Из них ASM - единственный, поддерживающий последнюю версию Java. Что касается посетителей, вы можете прочитать этот урок . Он был написан для более старой версии ASM API, но концепции посетителей остаются теми же.

...