Skip to content

pfmiles/bytecode-lego

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 

Repository files navigation

bytecode-lego

A fluent interface API in Java language which is used to write jvm assembly directly.
It's simple, after you are already familiar with jvm byte code...
Your hello world example would be:

ClsBuilder b = new ClsBuilder(Opcodes.V1_6, Opcodes.ACC_PUBLIC, "test/TestGenCls", null, "java/lang/Object", null, ClassWriter.COMPUTE_FRAMES);

MethodBuilder c = b.newMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null, 0, 0);
c.aload_0();
c.invokespecial("java/lang/Object", "<init>", "()V");
c.return_();

MethodBuilder main = b.newMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null, 0, 0);
main.getstatic("java/lang/System", "out", "Ljava/io/PrintStream;");
main.ldc("Hello World!");
main.invokevirtual("java/io/PrintStream", "println", "(Ljava/lang/String;)V");
main.return_();

byte[] bytes = b.toByteArray();
Class<?> cls = ClassLoadingUtil.loadClsInstantly("test.TestGenCls", bytes);
Method m = cls.getMethod("main", String[].class);
m.invoke(null, new Object[] { new String[0] });
assertTrue(true);// this program should print out 'Hello world!'

You can save the generated bytes to a file and examine it using javap:

$ javap -c TestGenCls -verbose

public class test.TestGenCls extends java.lang.Object
  minor version: 0
  major version: 50
  Constant pool:
const #1 = Asciz    test/TestGenCls;
const #2 = class    #1; //  test/TestGenCls
const #3 = Asciz    java/lang/Object;
const #4 = class    #3; //  java/lang/Object
const #5 = Asciz    <init>;
const #6 = Asciz    ()V;
const #7 = NameAndType  #5:#6;//  "<init>":()V
const #8 = Method   #4.#7;  //  java/lang/Object."<init>":()V
const #9 = Asciz    main;
const #10 = Asciz   ([Ljava/lang/String;)V;
const #11 = Asciz   java/lang/System;
const #12 = class   #11;    //  java/lang/System
const #13 = Asciz   out;
const #14 = Asciz   Ljava/io/PrintStream;;
const #15 = NameAndType #13:#14;//  out:Ljava/io/PrintStream;
const #16 = Field   #12.#15;    //  java/lang/System.out:Ljava/io/PrintStream;
const #17 = Asciz   Hello World!;
const #18 = String  #17;    //  Hello World!
const #19 = Asciz   java/io/PrintStream;
const #20 = class   #19;    //  java/io/PrintStream
const #21 = Asciz   println;
const #22 = Asciz   (Ljava/lang/String;)V;
const #23 = NameAndType #21:#22;//  println:(Ljava/lang/String;)V
const #24 = Method  #20.#23;    //  java/io/PrintStream.println:(Ljava/lang/String;)V
const #25 = Asciz   Code;

{
public test.TestGenCls();
  Code:
   Stack=1, Locals=1, Args_size=1
   0:   aload_0
   1:   invokespecial   #8; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   Stack=2, Locals=1, Args_size=1
   0:   getstatic   #16; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   ldc #18; //String Hello World!
   5:   invokevirtual   #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:   return

}

Ok, that's almost all, may be this is an interesting way to write bytecode directly, have fun!
Oh, after all, it's based on ASM 4, btw...

About

A fluent interface API in Java language which is used to write jvm assembly directly.

Resources

Stars

10 stars

Watchers

2 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages