首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用来自localVar的newLocal的奇怪的LocalVariableSorter索引

使用来自localVar的newLocal的奇怪的LocalVariableSorter索引
EN

Stack Overflow用户
提问于 2018-05-02 17:28:47
回答 1查看 386关注 0票数 3

我正在通过newLocalLocalVariableSorter添加新的本地用户。我要添加局部变量的方法是一个具有长参数的实例方法。我要增加两个局部变量,一个长的,一个对象。在示例代码中没有其他本地vars。

因此,我希望看到以下时隙/索引:

代码语言:javascript
复制
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检查结果时,它将向我展示:

代码语言:javascript
复制
LSTORE 5
ASTORE 8

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

但是,生成的代码可以工作。我只想了解一下这里发生了什么魔法以及原因。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-03 08:46:35

LocalVariableSorter类有一个设计,这使得它很容易使用错误。

当调用由MethodVisitor API定义的方法时,局部变量将经历类文档中提到的重命名。

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

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

这种行为与类文档的第一句所述完全吻合:

LocalVariablesSorter

一个按外观顺序重命名局部变量的MethodVisitor。

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50140365

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档