我正在使用ASM开发Java插装引擎,在这种情况下,计算堆栈的顶部有一个特定的 value,我想在现有的 value 之前插入一个 ref(这是 getstatic 的结果)。也就是说,考虑只有一个 value 的堆栈:value ->
,然后在 getstatic 之后,我希望堆栈变成这样:ref, value ->
.
要执行此行为,我必须插入以下字节码:* gettatic * 和 swap。使用ASM时,我将执行如下操作(考虑MethodVisitor
类型的mv
):
mv.visitFieldInsn(Opcodes.GETSTATIC, ...);
mv.visitInsn(Opcodes.SWAP);
问题是 swap 字节码不支持long
和double
值,所以上面的代码对于单个单词类型是可以的,但是对于long
和double
类型就不能正常工作了。
对于long
和double
类型,是否有简单的解决方案来解决此问题,并且不需要辅助局部值?
7条答案
按热度按时间bd1hkmkf1#
我们有一个双字值VV和参考值R。要从VV...获取到VVR...,您可以将R值添加到堆栈顶部(RVV...),然后使用dup_x2(RVVR...),然后弹出(VVR...)。
snz8szmq2#
这里有一个ASM的实用函数,它注入字节码,用于交换栈顶任何类型的操作数:
gblwokeq3#
最简单的解决方案是使用局部变量来交换堆栈上的项。
nue99wik4#
使用序列dup2x2,pop2。
从堆栈上的XXYY开始,dup2x2给您YYXXYY,pop2留给您YYXX。
twh00eeo5#
调用org.objectweb.asm.commons.GeneratorAdapter.swap(类型,类型),它是这样实现的:
wqsoz72f6#
我今天遇到了同样的问题。我觉得局部变量可以这样绕过:
1.价值-〉
获取静态
1.值-〉参考-〉
重复_X2
1.参考-〉值-〉参考-〉
流行音乐
1.参考-〉值-〉
m0rkklqb7#
我会确保堆栈按照它需要的顺序加载,而不需要交换。在优化代码方面,我建议您尝试生成尽可能接近
javac
生成的代码,因为这是JVM已经调整优化的内容。如果这不可能,您可以将值存储在局部变量中,推送
ref
并重新加载值。