fge*_*fge 9 java jvm bytecode-manipulation java-bytecode-asm
我是格拉巴酒的维护者.此包通过使用ASM生成一个扩展解析器类的类,从Java代码在运行时生成解析器.
我已经从ASM 4迁移到ASM 5,从生成JVM 1.5字节码到生成JVM 1.6字节码,现在我已经成功生成了JVM 1.7字节码而不是......除了我不知道为什么这样做.
基本上,我做了以下事情:
new ClassWriter(ClassWriter.COMPUTE_MAXS)现在是new ClassWriter(ClassWriter.COMPUTE_FRAMES).visit()方法的第一个参数更改Opcodes.V1_6为Opcodes.V1_7.现在,为什么我不明白为什么它有效有两个原因:
我有几个电话给MethodVisitors:
mv.visitMaxs(0, 0); // trigger automatic computing
Run Code Online (Sandbox Code Playgroud)
这是否意味着可以删除这些说明?
起初我只是尝试和添加的COMPUTE_FRAMES参数的ClassWriter构造函数,但它没有在一个点为我的测试中,我宣布一个:
static class TestJoinParser
extends EventBusParser<Object>
{
protected final JoinMatcherBuilder builder
= join('a').using('b');
}
Run Code Online (Sandbox Code Playgroud)
错误是:
java.lang.ClassFormatError: Arguments can't fit into locals
Run Code Online (Sandbox Code Playgroud)
鉴于它是一个实例字段,我想它与在构造函数中初始化的特定参数有关吗?
无论如何,我所有的测试现在都有效,我正在尝试更重的测试......但是我的目标是更进一步,我想至少了解为什么我的修改工作了... .
Cel*_*ggs 10
COMPUTE_FRAMES和COMPUTE_MAXSClassWriter.COMPUTE_MAXS有一个不同的功能ClassWriter.COMPUTE_FRAMES.
在最新版本的JVM中,类包含堆栈映射以及方法代码.此映射描述了方法执行期间关键点(跳转目标)的堆栈布局.在以前的版本中,JVM必须计算此信息,这在计算上是昂贵的.通过要求此信息,JVM可以只验证框架是否有效,这比重新计算所有内容要容易得多.
当然,编译器必须生成这些帧.这也很困难,所以ASM包含ClassWriter.COMPUTE_FRAMES允许这一点 - 然后它会为你计算它们.
现在,ClassWriter.COMPUTE_MAXS执行类似的操作:JVM要求类文件指定每个方法使用的最大堆栈大小和变量数,以便它可以只验证这个而不必自己计算.这对于堆叠帧的类似原因很有用:它的计算成本较低.
所以,实际上,你想要两个!但是,正如您所说,当您尝试添加它时失败了.可能的答案在于文档ClassWriter.COMPUTE_FRAMES(当你对它感到困惑时,你应该首先看看它):它说"computeFrames意味着computeMaxs".因此,您只需指定即可ClassWriter.COMPUTE_FRAMES.
使用MethodVisitors,visitMaxs仍然需要呼叫ARE.此时ASM将重新计算帧和最大值.它只会忽略你给它的论据.所以,不,你不能删除它们.(另请注意,它实际上并不是指令.)
我在上面解释了为什么只使用它就足够了COMPUTE_FRAMES,这是这里的关键部分.我不确定为什么指定两个标志会破坏你的测试.如果您可以提供您在那里所做的确切代码,那么可能会有所帮助.我在ClassWriter/ MethodWritersource 上做了一些资源潜水,并且似乎没有任何理由说明为什么两者都会破坏你的代码.
| 归档时间: |
|
| 查看次数: |
2289 次 |
| 最近记录: |