目前我正在修补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字节码并为类文件生成适当的头文件(换句话说,获取字节码并从中生成有效的类文件)。我想我自己可以编写一个脚本,但这需要一些我现在可能没有的时间。
答案 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