LARA

The Cafebabe Bytecode Generation Library: Examples

IMPORTANT: This page is now outdated. Cafebabe has moved to GitHub and so has the documentation.

See also:

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

}