iconst_0
instead of iconst 0
)goto
locationsimport org.apache.bcel._ import org.apache.bcel.generic._ import org.apache.bcel.Constants._
val cg = new ClassGen("HelloBCEL", "java.lang.Object", // Class, superclass "(no filename)", ACC_PUBLIC | ACC_SUPER, null) val cp = cg.getConstantPool() // cg creates constant pool val il = new InstructionList() val factory = new InstructionFactory(cg)
cg.addEmptyConstructor(ACC_PUBLIC) // if no constructor provided cg.getJavaClass().dump("HelloBCEL.class")
val mg = new MethodGen(ACC_STATIC | ACC_PUBLIC, // access flags Type.VOID, // return type Array(new ArrayType(Type.STRING, 1)), // argument types Array("argv"), // arg names "main", "HelloBCEL", // method, class il, cp)
... // method implementation il.append(InstructionFactory.createReturn(Type.VOID)) mg.setMaxStack() cg.addMethod(mg.getMethod()) il.dispose() // Allow instruction handles to be reused
System.out
(of type java.io.PrintStream
)
il.append(factory.createFieldAccess("java.lang.System", "out", new ObjectType("java.io.PrintStream"), Constants.GETSTATIC))
il.append(factory.createConstant("Hello, World!"))
il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, Array(Type.INT), // return type, param types Constants.INVOKEVIRTUAL))
createConstant
works with Boolean, Int, Double, String
il.append(factory.createConstant(value))
Picks the right opcode for push, deals with constant pool
val fooGen = mg.addLocalVariable("foo", Type.INT, null, null) val fooIndex = fooGen.getIndex() val loc = il.append(InstructionFactory.createStore(Type.INT, fooIndex)) fooGen.setStart(loc)
InstructionFactory.createLoad
to load local variable onto stack
il.append(InstructionFactory.createLoad(Type.STRING, fooIndex))
InstructionFactory.createBinaryOperation
for add, mul, etc.
il.append(InstructionFactory.createBinaryOperation("*", Type.INT))
InstructionFactory.createBranchInstruction
for creating a conditional or unconditional branch. il.append
. null
, then add it later.
val instr = InstructionFactory.createBranchInstruction(Constants.IFNE, null) il.append(instr) ... val loc = il.append(the branch target) instr.setTarget(loc)
Constants.GOTO
for an unconditional branch bcellab
bcel-6.2
and click Okbcel-6.2
and click Okbcellab
project. What children do you have?bcel-6.2
with grandchild bcel-6.2.jar
Main
and copy/paste all the code from slides 4 - 6, in the right order.HelloBCEL.class
file located?java HelloBCEL
. What happens?Bits
with a static method
public static int bits(int n)
and a main
method that prints the result of bits(42)
.
Let's get the printing out of the way first. Modify the previous program so that it calls java.lang.Math.abs(42)
and prints that, rather than "Hello, World!"
. What modifications did you make to your program?
bits
function. (There is no shame in writing the function in Java and peeking at the javap
output. Only your teammate will know :-)) Remember to change java.lang.Math.abs
to Bits.bits
. What is the code that generates bits
?while
loop, so we want to generate code for that. Your task is to change the code that generates the code for bits
so that it no longer makes the recursive call but instead uses the loop
int count = 0; while (n > 0) { count = count + n % 2; n = n / 2; } // Put a GOTO to the top of the loop here return count;
What byte codes do you intend to generate?
The Java virtual machine does not have functions or closures as a native type. If we want to generate code for the JVM, we need to implement them as objects. Consider this code:
int fib(int n) // C-like language with nested functions { int fibhelper(int i, int a, int b) { if (i == n) return b; else return fibhelper(i + 1, b, a + b); } fibhelper(1, 0, 1); }
Here, fibhelper
is an object with a method (which we will call invoke
) and with an instance field for each free variable in its body (in this case, n
). Every fibhelper(x, y, z)
turns into a new FibHelper(n).invoke(x, y, z)
.
fib
method in Java. It needs to construct a fibhelper
object and call its invoke
method.fibhelper
in Java. (It needs one constructor and one invoke
method.)fib
method? (Hint: javap
)fibhelper
class? (Hint: javap
)main
and fib
functions in a program Fib
, printing fib(30)
. Hint: Your program needs to generate two classes.