gpt4 book ai didi

java - ASM - 使用来自 LocalVariableSorter 的 newLocal 的奇怪 localVar 索引

转载 作者:行者123 更新时间:2023-12-01 14:21:26 25 4
gpt4 key购买 nike

我正在通过 LocalVariableSorter 中的 newLocal 添加新的本地变量。我要将局部变量添加到的方法是一个带有长参数的实例方法。我要加两个本地人;一长一物。示例代码中没有其他本地变量。

因此,我预计会有以下插槽/索引:

0 - this
1 - the long param
3 - my 1st local added via `newLocal` - using two slots as it is a long
5 - my 2nd local added via `newLocal`

不过,我从 newLocal 得到的返回值是 3 和 7。为什么会有这么大的差距?

让事情变得更奇怪的是,当我使用这些索引添加 xSTORE 指令并使用 javap 检查结果时,它向我显示:

LSTORE 5
ASTORE 8

注意:不仅值与我传递给 xSTORE 指令的值不同,而且它们之间的差距现在是 3,而不是以前的 4。

虽然生成的代码有效。我只是想了解这里发生了什么魔法及其原因。

谢谢

最佳答案

LocalVariableSorter 类有一个设计,很容易用错。

当调用由 MethodVisitor API 定义的方法时,局部变量会经历 class documentation 中提到的重新编号。 .

因此,当与 ClassReader 一起使用时,被访问的旧代码会被转换。由于您不希望注入(inject)的新代码经历这种转换,而是要使用新定义的变量,因此您必须绕过 LocalVariableSorter 并调用底层目标上的方法 MethodVisitor.

当您在 LocalVariableSorter 上调用 visitVarInsn(LSTORE, 3) 时,它会像引用索引 3 的旧指令一样被处理,并且因为您注入(inject)了一个占用索引 34 的新变量,索引 3 处的“旧变量”被重新映射到下一个空闲索引,即5(和 6)。然后,当您定义下一个新变量时,它获得索引 7 并在 LocalVariableSorter 上调用 visitVarInsn(ASTORE, 7) 就像处理与新变量冲突的旧变量,因此它被重新映射到 8

此行为与类文档的第一句完全匹配:

LocalVariablesSorter

A MethodVisitor that renumbers local variables in their order of appearance.

因此,当您必须在 LocalVariableSorter 上调用 newLocal 来创建一个不会重新映射的新变量时,您必须调用 visit... 原始方法,包装 MethodVisitor 以使用它。当您使用子类 GeneratorAdapter 时,您可以使用其新定义的方法(那些不以 visit... 开头的方法)来创建不会被转换的新指令,但对我来说,这会使事情变得更糟,在同一个类上有转换指令和创建未转换指令的方法,并且始终需要记住 visit... 前缀会有所不同。对于某些方法,您仍然需要访问原始方法访问者,如 this answer 中所述。它处理 visitLocalVariable 以创建已创建变量的调试信息。

关于java - ASM - 使用来自 LocalVariableSorter 的 newLocal 的奇怪 localVar 索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50140365/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com