Создание «Привет, мир!»класс с библиотекой Java ASM - PullRequest
10 голосов
/ 18 марта 2011

Я начал возиться с ASM API для проекта компилятора, над которым я работаю. Тем не менее, я обнаружил, что документация для новичка во многих местах не совсем ясна, и я подумал, что имею хороший пример генерации класса, который просто печатает «Hello, World!» было бы хорошим примером, чтобы иметь здесь.

В настоящее время я могу сгенерировать класс с помощью main () (используя классы ClassWriter, ClassVisitor и MethodVisitor), но я не могу понять, как генерировать тело main. Может ли кто-нибудь дать мне пример создания файла класса в ASM, который:

  • содержит main ()
  • создает локальную переменную String в main () со значением «Hello, World!»
  • печатает переменную

Ответы [ 2 ]

13 голосов
/ 18 марта 2011

Вы можете скомпилировать класс, используя java, затем получить asm, чтобы распечатать вызовы, которые потребуются для генерации эквивалентного класса,

FAQ

ASMifierClassVisitor

Javadocs в ASMifierClassVisitor содержит код hello world,

import org.objectweb.asm.*;

public class HelloDump implements Opcodes {

  public static byte[] dump() throws Exception {

     ClassWriter cw = new ClassWriter(0);
     FieldVisitor fv;
     MethodVisitor mv;
     AnnotationVisitor av0;

     cw.visit(49,
             ACC_PUBLIC + ACC_SUPER,
             "Hello",
             null,
             "java/lang/Object",
             null);

     cw.visitSource("Hello.java", null);

     {
         mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
         mv.visitVarInsn(ALOAD, 0);
         mv.visitMethodInsn(INVOKESPECIAL,
                 "java/lang/Object",
                 "<init>",
                 "()V");
         mv.visitInsn(RETURN);
         mv.visitMaxs(1, 1);
         mv.visitEnd();
     }
     {
         mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
                 "main",
                 "([Ljava/lang/String;)V",
                 null,
                 null);
         mv.visitFieldInsn(GETSTATIC,
                 "java/lang/System",
                 "out",
                 "Ljava/io/PrintStream;");
         mv.visitLdcInsn("hello");
         mv.visitMethodInsn(INVOKEVIRTUAL,
                 "java/io/PrintStream",
                 "println",
                 "(Ljava/lang/String;)V");
         mv.visitInsn(RETURN);
         mv.visitMaxs(2, 1);
         mv.visitEnd();
     }
     cw.visitEnd();

     return cw.toByteArray();
  }
}
9 голосов
/ 18 марта 2011

Если вы используете Eclipse, есть отличный ASM плагин , который поможет вашему обучению. Он отображает существующий Java-код как фактические вызовы ASM, необходимые для инструментирования указанного кода. Он очень полезен для обучения, поскольку вы можете видеть вызовы ASM, необходимые для реализации конкретного кода Java.

...