The Cafebabe Bytecode Generation Library: Examples
IMPORTANT: This page is now outdated. Cafebabe has moved to GitHub and so has the documentation.
See also:
- Cafebabe introduction page
Hello world
The good old:
class HW { public static void main(String [] args) { System.out.println("Hello world!"); } }
…can be generated as follows:
import cafebabe.ByteCodes._ import cafebabe.AbstractByteCodes._ val classFile = new cafebabe.ClassFile("HW", None) classFile.addDefaultConstructor val codeHandler = classFile.addMainMethod.codeHandler codeHandler << GetStatic("java/lang/System", "out", "Ljava/io/PrintStream;") << Ldc("Hello world!") << InvokeVirtual("java/io/PrintStream", "println", "(Ljava/lang/String;)V") << RETURN codeHandler.freeze classFile.writeToFile("./classfiles/HW.class")
Factorial
The following class:
class Factorial { public int fact(int value) { if(value <= 1) { return 1; } else { return value * this.fact(value - 1); } } }
…can be generated this way:
import cafebabe._ import cafebabe.ByteCodes._ import cafebabe.AbstractByteCodes._ val classFile = new ClassFile("Factorial", None) classFile.addDefaultConstructor val codeHandler = classFile.addMethod("I", "fact", "I").codeHandler val labelName = codeHandler.getFreshLabel("else") codeHandler << ILoad(1) << Ldc(1) << If_ICmpGt(labelName) << Ldc(1) << IRETURN << Label(labelName) << ILoad(1) << ALoad(0) << ILoad(1) << Ldc(1) << ISUB << InvokeVirtual("Factorial", "fact", "(I)I") << IMUL << IRETURN codeHandler.freeze classFile.writeToFile("Factorial.class")
The bytecode corresponding to the method is:
0: iload_1 1: iconst_1 2: if_icmpgt 7 5: iconst_1 6: ireturn 7: iload_1 8: aload_0 9: iload_1 10: iconst_1 11: isub 12: invokevirtual #XX; //Method fact:(I)I 15: imul 16: ireturn
Showing that Booleans are Meaningless in Byte Code
object TestGen { import cafebabe._ import AbstractByteCodes._ import ByteCodes._ def main(args : Array[String]) = { val classFile = new cafebabe.ClassFile("HW", None) classFile.addDefaultConstructor val testMethod = classFile.addMethod("Z", "test", "I", "Z").codeHandler testMethod << ILoad(1) << ILoad(2) << Ldc(37) << IADD << IADD << IRETURN testMethod.freeze val codeHandler = classFile.addMainMethod.codeHandler codeHandler << GetStatic("java/lang/System","out","Ljava/io/PrintStream;") << DefaultNew("HW") << Ldc(3) << Ldc(2) << InvokeVirtual("HW", "test", "(IZ)Z") << InvokeVirtual("java/io/PrintStream","println","(I)V") << RETURN codeHandler.freeze classFile.writeToFile("./classfiles/HW.class") } }
generates
class HW extends java.lang.Object{ public HW(); Code: 0: aload_0 1: invokespecial #9; //Method java/lang/Object."<init>":()V 4: return public boolean test(int, boolean); Code: 0: iload_1 1: iload_2 2: bipush 37 4: iadd 5: iadd 6: ireturn public static void main(java.lang.String[]); Code: 0: getstatic #19; //Field java/lang/System.out:Ljava/io/PrintStream; 3: new #3; //class HW 6: dup 7: invokespecial #20; //Method "<init>":()V 10: iconst_3 11: iconst_2 12: invokevirtual #22; //Method test:(IZ)Z 15: invokevirtual #28; //Method java/io/PrintStream.println:(I)V 18: return }