在JVM字节码中添加对空对象的检查

时间:2018-04-08 03:47:36

标签: jvm bytecode

我正在使用ASM修改任何java类的字节码,为每个对象添加一个空值检查。

例如,对于这段代码:

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

我想修改字节码,所以它看起来像这样:

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

或者这个:

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

我被困了,因为我不知道ALOAD的号码是多少。我认为ALOAD总是使用ALOAD 1(或者采用这种格式ALOAD n)。我该怎么做才能得到ALOAD的数字?这是我到目前为止的工作(使用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();
}

1 个答案:

答案 0 :(得分:1)

您需要DUP字节码。

ALOAD引用局部变量,但是不能为给定对象分配局部变量槽。在调用doSomething()之前,对象引用已经放在表达式堆栈上(带有ALOAD字节码或其他一些 - 这没关系)。所以你需要的是复制这个对象引用(用DUP),然后调用你的断言方法。