Search code examples
jvmbytecode

Adding a check for null object in JVM bytecode


I'm using ASM to modify the bytecode of any java class to add a null-check for each object.

For example, for this piece of code:

Object a = new Object();
a.doSomething();

I want to modify the bytecode so it looks like this:

Object a = new Object();
assertNotNull(a);
a.doSomething();

or this:

Object a = new Object();
if(a != null){
a.doSomething();}
else return 1 //or throw exception

I'm stuck because I don't know what number go with ALOAD. I think ALOAD always go with ALOAD 1 (or in this format ALOAD n). What can I do to get the number that goes with ALOAD? Here's my work so far (using Junit assertNotNull)

/*
 * Use JUnit assertNotNull to check object/item for null
 */
private void addAssertNullMethod() {
    //need to add ALOAD here, but I don't know the location of the object on the stack.
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/junit/Assert", "assertNull", "(Ljava/lang/Object;)V", false);
    mv.visitEnd();
}

Solution

  • You need DUP bytecode instead.

    ALOAD refers to local variables, but there can be be no local variable slot assigned for a given object. Before calling doSomething(), an object reference is already put on the expression stack (with ALOAD bytecode or some other - it does not matter). So all you need is to copy this object reference (with DUP) and then invoke your assert method.