【问题标题】:How to translate Three Address Code(TAC) to Java Bytecode?如何将三地址码 (TAC) 转换为 Java 字节码?
【发布时间】:2017-11-10 04:18:40
【问题描述】:

我想将一个普通的三地址代码文件转换为 Java 字节码。已经有一些与此主题相关的问题,但要么没有回答properly,要么question 超出了我的要求。

以“龙之书”中可用编译器前端生成的这段代码为例:

L1:L3:  i = i + 1
L5:     t1 = i * 8
        t2 = a [ t1 ]
        if t2 < v goto L3
L4:     j = j - 1

它在字节码中会是什么样子?我需要重建符号表来进行翻译吗?如果有人能像 blackcompe 在 answer 中所做的那样描述它,那将非常有帮助(我知道 JVM 是堆栈机器,而不是寄存器机器)。

【问题讨论】:

    标签: java compiler-construction bytecode


    【解决方案1】:

    以下是我将如何用字节码编写您的代码。但这只是一种方法,而且问题是非常开放的。我假设所有变量都是整数,除了 a.如果它们是不同的类型,那么所需的代码显然看起来会有所不同。

    ; assume i, j, a, and v are in slots 0-3 respectively
    L3: 
    iinc 0 1
    iload_0
    bipush 8
    imul
    ; store t1 in a variable for simplicity - you could simplify the code by eliminating the temporary
    istore 4
    aload_2
    iload 4
    iaload
    istore 5
    iload 5
    iload_3
    if_lt L3
    iinc 1 -1
    

    如前所述,这是一个非常开放的问题。例如,上面的代码显式地将临时变量存储到本地插槽(即“寄存器”)中,以便与代码完全匹配。但是您可以通过重新排列来简化代码以避免临时代码,如下所示

    ; assume i, j, a, and v are in slots 0-3 respectively
    L3: 
    iinc 0 1
    aload_2
    iload_0
    bipush 8
    imul
    iaload
    iload_3
    if_lt L3
    iinc 1 -1
    

    【讨论】:

    • 感谢您的回答!我发现它并不像我最初想象的那么简单。你认为有什么已经实现的吗(考虑到“龙书”现在已经很老了)?我还看到你是 Krakatau 的创造者。你认为你的工具能以任何方式帮助我创建从 TAC 到字节码的翻译器吗?
    • @Joao Martins:实际上,它非常直截了当。但即使是这个答案的第一个变体,也已经是一个简单(不是说幼稚)翻译器会产生的优化变体。只是每条 TAC 指令映射到多条指令,但生成的字节码仍然可以比 TAC 表示更紧凑(允许相同数量的变量)。不要被汇编表示误导,这对于人类交流来说很好,而没有工具会使用这种文本表示作为中间步骤......
    • @Holger,感谢您的评论,非常明确。我可以查看哪些源材料来帮助我构建这个幼稚的翻译器?你知道任何类似的实现吗?另外,关于符号表,我是否需要重建它来进行翻译?
    • @Joao Martins:局部变量仅使用索引来寻址,因此您所要做的就是为每个符号分配一个索引。然后,a := b op c 形式的每条 TAC 指令都被转换为 [load b], [load c], [op], [store a](使用 abc 的索引)。另见JVMS§2.6.1JVMS§6。对于仅分配一次的符号,您可以跳过保留局部变量并将其定义表达式内联到使用站点中。
    • @JoaoMartins:我的建议是忘记生成必须再次解析的文本表示。首先生成字节码,即类文件。
    猜你喜欢
    • 1970-01-01
    • 2017-09-24
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 2019-07-03
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    相关资源
    最近更新 更多