我正在使用Krakatau从Jasmin语法生成字节码。我的Jasmin代码是由中间地址的直接翻译以三地址代码(TAC)的形式创建的。我的问题是我无法确定
看一下TAC,在翻译跳转语句时应该将stack指令放在哪里。

汇编器上的Krakatau文档说:


  StackMapTable属性的内容会自动填写
  基于封闭代码属性中的堆栈指令。如果这
  属性的内容为非空且未指定属性
  明确地,将隐式添加一个。


但这也说:


  Krakatau不会从没有任何堆栈信息的字节码为您计算新的堆栈映射。如果要执行此操作,则应尝试使用ASM。


我对哪种类型的指令以及应该在哪里将它们添加到翻译中感到困惑,因此汇编器知道如何隐式添加属性。任何帮助,将不胜感激。

例如,我用类似于Java的语法编写了这段代码(但不一样,因此我需要使用其他编译器):

java - 用Krakatau自动填充StackMapTable-LMLPHP

我从编译器的前端得到的是左侧的TAC,翻译器在右侧生成Jasmin代码(我删除了页眉和页脚,只保留了字节码本身,缺少了返回指令):

java - 用Krakatau自动填充StackMapTable-LMLPHP

当我尝试运行它时,我得到如下信息:

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.VerifyError: Expecting a stackmap frame at branch target 24
Exception Details:
  Location:
    Main.main([Ljava/lang/String;)V @16: iflt
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0x0000000: 1103 e8bc 073a 050f 4814 000a 4a27 2997
    0x0000010: 9b00 0819 0503 2752 b1

    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
    at java.lang.Class.getMethod0(Class.java:3018)
    at java.lang.Class.getMethod(Class.java:1784)
    at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)


我知道发生这种情况是因为它期望在带有标签L23的行之后出现一个.stack append Double Double Object [D,但是,正如我之前说的,这个示例很简单,并且我不能总是推断出这些指令的位置。如果Krakatau可以对我进行推断,然后在封闭代码属性的开头附加一些指令,那将是很好的。

最佳答案

最简单的方法是完全避免使用堆栈映射。仅当您要使用51.0+版本的功能(即invokedynamic)时才需要堆栈映射。如果您不使用invokedynamic,则可以将类文件版本设置为50或更低,并且根本不需要堆栈映射。实际上,如果您未明确指定版本,则Krakatau会将版本默认为49.0,因此您无需在其中进行任何操作。

如果您使用的是invokedynamic,那么事情会变得更加棘手,因为您必须生成堆栈映射。基本规则是,只要前一条指令以外的任何地方都可访问一条指令,就需要一个堆栈映射条目。 (我认为您也需要输入无效代码,但我没有检查)。

至于实际生成的条目,有几种不同类型的堆栈帧,但是您不必为此担心。最简单的方法是每次只使用一个full框架。这涉及列出局部变量(“寄存器”)插槽和操作数堆栈中每个活动值的当前类型,因此您必须对其进行跟踪。

是的,计算和生成所有类型信息很麻烦,但是您必须为此归咎于Oracle,而不是我。或者,您可以尝试按照文档中的建议使用ASM为您生成堆栈映射。

关于java - 用Krakatau自动填充StackMapTable,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47245539/

10-09 03:14