是org.objectweb.asm.commons.LocalVariablesSorter错误优化?

时间:2013-01-24 03:59:21

标签: java java-bytecode-asm

我正在尝试使用ASM将方法包装在try / finally块中。具体来说,我正在扩展org.objectweb.asm.commons.AdviceAdapter并遵循“3.2.3在方法退出前插入代码”下所述的"Using ASM framework to implement common bytecode transformation patterns"技术。

我也在使用LocalVariablesSorter(一个超级类AdviceAdapter)在我在finally块中使用的方法开头添加一个局部变量。

我有一个方法,我试图用ASM修改。该方法需要三个args,并且没有自己的本地:

class Example {
    public static int f4(int i, long l, int f) {
        return (int) (i + l + f);
    }
}

由于我的finally块可能是异常处理程序目标,因此我添加一个调用super.visitFrame(F_NEW, ...),传递方法参数。由于这会调用超类,我希望我的newLocal可以通过LocalVariablesSorter添加到此框架中。但是当通过我的ASM管道运行时,Java 7给了我错误java.lang.VerifyError: Bad local variable type in method Example.f4(IJI)I at offset 32

查看source of LocalVariablesSorter,在visitFrame方法中,我看到它有一个布尔changed,如果没有更改,visitFrame会跳过任何新本地人的考虑我可能会被创建。仅当上游字节码对由于使用changed创建新本地时必须重新映射的变量执行某些操作时才会设置此LocalVariablesSorter布尔值(并且{{1}中不会发生此类操作上面的方法)。

通过应用此解决方法:

f4()

我能够通过Java 7的验证程序。此外,使用 Field field = LocalVariablesSorter.class.getDeclaredField("changed"); field.setAccessible(true); field.setBoolean(this, true); ASM实用程序,我在finally块开始之前看到堆栈映射框架的差异:

之前:

TraceClassVisitor

在我的反思黑客之后(我正在添加的新本地是一个int):

FRAME FULL [I J I] [java/lang/Throwable]

我知道我没有分享任何周围的代码,但我的问题更为笼统。 FRAME FULL [I J I I] [java/lang/Throwable] 布尔值是changed的错误优化吗?或者是我以某种方式滥用它?

1 个答案:

答案 0 :(得分:0)

LocalVariablesSorter.visitFrame(..)调用不会添加任何本地,它只会通知ASM记录有关其他帧的信息。您需要通过调用LocalVariablesSorter.newLocal(..)来添加您的本地人。

虽然一般情况下,如果您认为自己发现了ASM中的错误,最好向ASM issue tracker提交错误报告,并提供允许重现问题的测试代码(例如测试类和完整转换)。 / p>