【问题标题】:Compile to java bytecode (without using Java)编译成java字节码(不使用Java)
【发布时间】:2009-03-27 00:43:44
【问题描述】:

我的编译器类正在创建一种我们打算编译为 Java 字节码的语言。我们已经取得了很大进展,并且已经接近生成代码的时间了。

我们在查找有关如何从我们的编译器创建 .class 文件的信息时遇到问题。你有什么资源可以给我们一些帮助吗?我们已经有很多关于指令集的文档,但是需要关于如何直接填写类文件/十六进制编写的信息。

我们不需要有关反编译 .class 文件的信息或建议。

即使是从头开始写出 .class 文件的简单示例也非常棒。

JVM 规范不是我们所追求的。我们真正需要的是示例或演练。

【问题讨论】:

  • 我刚刚写了一个类文件解析器...您需要发出字节码的信息包含在第 4 章中。您发现第 4 章具体缺少什么?
  • 能给我们一个教程或例子吗?
  • 查看我的更新,但我认为您需要更具体地说明发出您不理解的类文件的哪一部分。
  • 确实如此。类文件格式就是“如何直接填写类文件/写十六进制的信息”。
  • 我建议用 Java 编写一个最小的类,编译它,然后用十六进制调试器和规范查看类文件——最好做很多笔记。使用 BCEL 或类似的东西会更快,但你会学到更少。

标签: java compiler-construction bytecode


【解决方案1】:

有许多项目提供了创建 Java 类文件的高级接口,而无需您自己编写类文件。请看以下内容:

都提供了一个 API 来创建类文件。您总是可以查看他们为此编写的代码并为您的编译器编写一些类似的代码,尽管我认为这是相当多的工作。

使用 BCEL 看看 ClassGen,它应该可以让你以你想要的格式写出类文件,一个简单的例子如下:

ClassGen cg = new ClassGen("HelloWorld", "java.lang.Object",
                             "<generated>", ACC_PUBLIC | ACC_SUPER,
                             null);

【讨论】:

    【解决方案2】:

    VM 规范:The Class File FormatThe Java Virtual Machine Instruction Set 应该这样做。

    您可以查看字节码工程库 (BCEL) 以及 Findbugs(它必须阅读/理解类文件)来获得一些灵感。

    【讨论】:

    • 为了你自己的理智,我建议 ASM 而不是 BCEL。
    • 没有使用过,只是建议作为参考,看看类文件是如何编写的(我仍然说第 4 章和第 6 章就足够了),除非出现特定问题。
    【解决方案3】:

    我想您可以尝试使用现有工具并检查增量更改对生成的字节码的影响。

    来源:

    public class Hello {
            public static void main(String[] args) {
                    System.out.println("H");
            }
    }
    

    javap 输出:

    Compiled from "Hello.java"
    public class Hello extends java.lang.Object{
    public Hello();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   return
    
    public static void main(java.lang.String[]);
      Code:
       0:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       3:   ldc     #3; //String H
       5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8:   return
    
    }
    

    二进制:

    CA FE BA BE 00 00 00 32 00 1D 0A 00 06 00 0F 09         _______2________
    00 10 00 11 08 00 12 0A 00 13 00 14 07 00 15 07         ________________
    00 16 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29         _____<init>___()
    56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E         V___Code___LineN
    75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69         umberTable___mai
    6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67         n___([Ljava/lang
    2F 53 74 72 69 6E 67 3B 29 56 01 00 0A 53 6F 75         /String;)V___Sou
    72 63 65 46 69 6C 65 01 00 0A 48 65 6C 6C 6F 2E         rceFile___Hello.
    6A 61 76 61 0C 00 07 00 08 07 00 17 0C 00 18 00         java____________
    19 01 00 01 48 07 00 1A 0C 00 1B 00 1C 01 00 05         ____H___________
    48 65 6C 6C 6F 01 00 10 6A 61 76 61 2F 6C 61 6E         Hello___java/lan
    67 2F 4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F         g/Object___java/
    6C 61 6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75         lang/System___ou
    74 01 00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69         t___Ljava/io/Pri
    6E 74 53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61         ntStream;___java
    2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01         /io/PrintStream_
    00 07 70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61         __println___(Lja
    76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29         va/lang/String;)
    56 00 21 00 05 00 06 00 00 00 00 00 02 00 01 00         V_!_____________
    07 00 08 00 01 00 09 00 00 00 1D 00 01 00 01 00         ________________
    00 00 05 2A B7 00 01 B1 00 00 00 01 00 0A 00 00         ___*____________
    00 06 00 01 00 00 00 01 00 09 00 0B 00 0C 00 01         ________________
    00 09 00 00 00 25 00 02 00 01 00 00 00 09 B2 00         _____%__________
    02 12 03 B6 00 04 B1 00 00 00 01 00 0A 00 00 00         ________________
    0A 00 02 00 00 00 03 00 08 00 04 00 01 00 0D 00         ________________
    00 00 02 00 0E                                          _____
    

    【讨论】:

      【解决方案4】:

      JVM specification 可能是您正在寻找的,尤其是chapter 4 - the class file format

      【讨论】:

      • 其他人给出了这个答案,尽管这句话用粗体表示,但他们在推荐 JVM 规范方面获得了反对票——但 Jon 获得了三票。他是对的,但我敢打赌,一个没有乔恩积累的疯狂信誉的人会被鄙视。支持你,乔恩。
      • 很难说,因为 Jon 的回答和编辑都发生在“一个小时前”,但是关于不想要 JVM 规范的粗体线已被编辑,因此 Jon 的回答很可能发生在编辑之前。
      • Jon 和我建议使用 VM 规范。投反对票发生,然后是编辑或编辑和投反对票。无论哪种方式,编辑和否决票几乎同时发生。
      • 编辑肯定是在我的回答之后 - 我想指出我也得到了反对意见。在撰写本文时,此答案为 +4 -1。
      • 是的 - 我很困惑你有 4 我有 1 然后是 3 和 0 :-) 花了我一点时间来弄清楚看似随机的否决票(我真的希望人们会离开cmets 当他们投反对票时):-)
      【解决方案5】:

      SmartEiffel 包含一个开源的 java .class 文件生成器。

      http://smarteiffel.loria.fr/

      【讨论】:

        猜你喜欢
        • 2013-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-13
        相关资源
        最近更新 更多