编译为java字节码(不使用Java)

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

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

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

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

JVM规范不是我们追求的。 我们真正需要的是一个例子或演练。

VM规范: 类文件格式和Java虚拟机指令集应该这样做。

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

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

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

使用BCEL查看ClassGen,它应该能够以您想要的格式写出类文件,下面是一个简单的例子:

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

很抱歉让你失望,但VM的规格 正是你所追求的。 如果你不能处理规范那么也许你不应该编写编译器。

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

资源:

 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."":()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 ________() 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 _____ 

JVM规范可能正是您所需要的,特别是第4章 – 类文件格式 。

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

http://smarteiffel.loria.fr/