我正在尝试使用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
的错误优化吗?或者是我以某种方式滥用它?
答案 0 :(得分:0)
LocalVariablesSorter.visitFrame(..)
调用不会添加任何本地,它只会通知ASM记录有关其他帧的信息。您需要通过调用LocalVariablesSorter.newLocal(..)
来添加您的本地人。
虽然一般情况下,如果您认为自己发现了ASM中的错误,最好向ASM issue tracker提交错误报告,并提供允许重现问题的测试代码(例如测试类和完整转换)。 / p>