从 jvm 字节码生成 java class 文件 headers

Generating java class file headers from jvm bytecode

目前我正在修改 jvm 字节码指令。我制作了一个简单的编译器,给定源代码(C 风格)生成有效的 jvm 字节码表示。例如下面的代码:

float x = 3;
float y = 4.5;
float z = x + y;
print z;

编译为:

ldc 3
i2f
fstore 1
ldc 4.5
fstore 2
fload 1
fload 2
fadd
fstore 3
getstatic java/lang/System/out Ljava/io/PrintStream;
fload 3
invokevirtual java/io/PrintStream/println(F)V
return

(我知道生成的 java 代码目前不是最有效的,但这不是重点)。

使用 Java 字节码编辑器,我加载了一个已编译的 main class 并用我的代码替换了 main 方法代码。在那之后,我可以用我的代码完美地 运行 class 文件。我的问题是,是否有一个没有 UI 的 tool/script 可以采用 java 字节码并为 class 文件生成适当的 headers (换句话说,采用字节码并从中创建一个有效的 class 文件)。我想我可以自己写一个脚本,但这需要一些我现在可能没有的时间。

Krakatau assembler 允许您以文本格式编写字节码并将其组装到 class 文件中,为您处理所有二进制编码细节。

它类似于旧的 Jasmin 汇编程序,但语法上有细微的变化以消除歧义并支持 classJasmin 无法处理的文件功能。与 Jasmin 不同,它完全支持整个 Java 8 class 文件格式,并可选择允许完全控制 class 文件的二进制表示。

例如,这里是 class 使用 Krakatau 汇编格式的 lambda。

.version 52 0
.class public super LambdaTest1
.super java/lang/Object

.method public <init> : ()V
    .code stack 1 locals 1
        aload_0
        invokespecial Method java/lang/Object <init> ()V
        return
    .end code
.end method

.method public static varargs main : ([Ljava/lang/String;)V
    .code stack 4 locals 2
        invokedynamic InvokeDynamic invokeStatic Method java/lang/invoke/LambdaMetafactory metafactory (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; MethodType (J)J MethodHandle invokeStatic Method LambdaTest1 lambda$main[=10=] (J)J MethodType (J)J : applyAsLong ()Ljava/util/function/LongUnaryOperator;
        astore_1
        getstatic Field java/lang/System out Ljava/io/PrintStream;
        aload_1
        ldc2_w 42L
        invokeinterface InterfaceMethod java/util/function/LongUnaryOperator applyAsLong (J)J 3
        invokevirtual Method java/io/PrintStream println (J)V
        return
    .end code
.end method

.method private static synthetic lambda$main[=10=] : (J)J
    .code stack 4 locals 2
        lload_0
        lload_0
        l2i
        lshl
        lreturn
    .end code
.end method

.innerclasses
    java/lang/invoke/MethodHandles$Lookup java/lang/invoke/MethodHandles Lookup public static final
.end innerclasses

.end class