2

我对 Java 字节码还很陌生。我正在使用 BCEL 生成字节码,但是当我尝试使用生成的代码时收到一条错误消息。(事后看来,ObjectWeb ASM 似乎比 BCEL 更先进、更常用。)

这是错误消息:

Exception in thread "main" java.lang.VerifyError: 
(class: cb/io/FileDescriptor, method: set 
 signature: (I)J) 
Stack size too large

这是方法:

// Method descriptor #4 (I)J
// Stack: 0, Locals: 1
private static long set(int arg1);
  0  lconst_0
  1  lreturn
    Local variable table:
      [pc: 0, pc: 2] local: arg1 index: 0 type: int

据我了解,局部变量表是正确的,因为它与输入参数匹配。我没有添加“this”变量,因为该方法是静态的。

如果我没记错的话, lconst_0 将一个长值 0 加载到堆栈上,然后 lreturn 使用该值并返回它。

我究竟做错了什么?这里有足够的信息可以告诉吗?

谢谢!

4

1 回答 1

7

您必须声明用于每个 Java 方法的最大堆栈大小。例如 ASM 可以自动计算值,这为您省去了很多麻烦。最大堆栈大小是您在该方法中使用的插槽的绝对最大数量(一次,不累积)。进行分支时,计算可能会变得非常棘手。

你在long这里加载一个值,longs 消耗 2 个栈槽(实际上每个 64 位值(指针除外)消耗 2 个栈槽),所以你必须在这里设置最大栈大小为 2。

只是告诉您,您的Stack size too large方法消耗更多的堆栈槽,如方法描述符中指定的那样。

于 2013-03-07T12:09:37.020 回答