从jvm字节码生成java类文件头

时间:2017-02-04 19:25:49

标签: java jvm bytecode

目前我正在修补jvm字节码指令。我做了一个简单的编译器,给出源代码(C like style)生成有效的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字节码编辑器,我加载了一个已编译的主类,并用我的代码替换了主方法代码。之后,我能够使用我的代码完全正常运行类文件。我的问题是,是否有一个没有UI的工具/脚本可以使用java字节码并为类文件生成适当的头文件(换句话说,获取字节码并从中生成有效的类文件)。我想我自己可以编写一个脚本,但这需要一些我现在可能没有的时间。

1 个答案:

答案 0 :(得分:2)

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

它类似于旧的Jasmin汇编程序,但是为了消除歧义并支持Jasmin无法处理的类文件功能,需要进行少量语法更改。与Jasmin不同,它完全支持整个Java 8类文件格式,并可选择允许完全控制类文件的二进制表示。

例如,这是一个使用Krakatau汇编格式的lambdas的类。

.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$0 (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$0 : (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