java 变量定义 映射_为什么Java编译器生成奇怪的本地变量和堆栈映射帧?如何使用它们可靠地确定变量类型?...

我在ASM框架的帮助下创建

Java字节码检测工具,需要确定并可能更改方法的局部变量类型.很快我遇到了一个简单的情况,其中变量和堆栈映射节点看起来有些奇怪,并且没有给我足够的有关正在使用的变量的信息:

public static void test() {

List l = new ArrayList();

for (Object i : l) {

int a = (int)i;

}

}

给出以下字节码(来自Idea):

public static test()V

L0

LINENUMBER 42 L0

NEW java/util/ArrayList

DUP

INVOKESPECIAL java/util/ArrayList. ()V

ASTORE 0

L1

LINENUMBER 43 L1

ALOAD 0

INVOKEINTERFACE java/util/List.iterator ()Ljava/util/Iterator;

ASTORE 1

L2

FRAME APPEND [java/util/List java/util/Iterator]

ALOAD 1

INVOKEINTERFACE java/util/Iterator.hasNext ()Z

IFEQ L3

ALOAD 1

INVOKEINTERFACE java/util/Iterator.next ()Ljava/lang/Object;

ASTORE 2

L4

LINENUMBER 44 L4

ALOAD 2

CHECKCAST java/lang/Integer

INVOKEVIRTUAL java/lang/Integer.intValue ()I

ISTORE 3

L5

LINENUMBER 45 L5

GOTO L2

L3

LINENUMBER 46 L3

FRAME CHOP 1

RETURN

L6

LOCALVARIABLE i Ljava/lang/Object; L4 L5 2

LOCALVARIABLE l Ljava/util/List; L1 L6 0

MAXSTACK = 2

MAXLOCALS = 4

可以看出,所有4个显式和隐式定义的变量都占用1个时隙,4个时隙被保留,但只有2个被定义,以奇怪的顺序(地址0之前的地址2)和它们之间的“漏洞”.稍后使用ASTORE 1将List迭代器写入此“漏洞”,而不首先声明此变量的类型.只有在此操作后才会出现堆栈映射框,但我不清楚为什么只有2个变量放入其中,因为后来使用了2个以上的变量.稍后,使用ISTORE 3,int再次写入变量槽,没有任何声明.

此时看起来我需要完全忽略变量定义,并通过解释字节码来推断所有类型,运行JVM堆栈的模拟.

尝试了ASM EXPAND_FRAME选项,但它没用,仅将单帧节点的类型更改为F_NEW,其余部分仍然与以前完全相同.

任何人都可以解释为什么我会看到这样一个奇怪的代码,除了编写自己的JVM解释器之外还有其他选择吗?

结论,基于所有答案(如果我错了,请再次纠正我):

变量定义仅用于将源变量名称/类型匹配到在特定代码行访问的特定变量槽,显然是由JVM类验证程序和代码执行期间忽略的.可能缺席或与实际字节码不匹配.

变量槽被视为另一个堆栈,虽然通过32位字索引访问,并且只要您使用匹配类型的加载和存储指令,它总是可以用不同的临时值覆盖其内容.

堆栈帧节点包含从变量帧的开头分配到最后一个变量的变量列表,该变量将在后续代码中加载而不先存储.无论采用何种执行路径到达其标签,预期此分配映射都是相同的.它们还包含类似操作数堆栈的映射.它们的内容可以指定为相对于前一个堆栈帧节点的增量.

仅存在于线性代码序列中的变量将仅出现在堆栈帧节点中,如果存在在较高的插槽地址处分配的具有较长寿命的变量.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值