Генерация «Hello, World!» класс с библиотекой Java ASM

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

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

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

person seadowg    schedule 18.03.2011    source источник


Ответы (2)


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

Часто задаваемые вопросы

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();
  }
}
person sbridges    schedule 18.03.2011

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

person Brent Worden    schedule 18.03.2011
comment
Меня больше беспокоили вызовы ASM API для генерации байт-кода, но я обязательно проверю это в любом случае. - person seadowg; 18.03.2011