我正在寻找以下想法的现有实现:假设有人想在普通Java程序中编写“内联汇编”字节代码(大多数相关应用程序将涉及Java中无法提供的invokedynamic指令)。一种方法是:
void foo(boolean b) {
Label l1 = Asm.label();
Label l2 = Asm.label();
int i = Asm.no_int();
Asm._const(0);
Asm.store(i);
l1.bind();
Asm.load(i);
Asm.push(10);
Asm.if_cmpge(l2);
Asm.getstatic("java/lang/System", "out", "Ljava/io/PrintStream");
Asm.load(i);
Asm.invokevirtual("java/io/PrintStream", "println", "(I)V");
Asm.inc(i);
Asm._goto(l1);
l2.bind();
Asm._return();
}
指令被编码为API调用,然后我们需要运行普通的java编译器,然后对字节代码进行后处理并用实际指令替换API调用。
P.S。我知道ASM框架的ASMifier,它没有解决上述问题。
答案 0 :(得分:6)
ClassLoader
有一个方法defineClass
,它允许您通过提供字节码动态生成类。将此与Javassist或此previous问题的其他建议相结合。
答案 1 :(得分:1)
如果您正在寻找专利的“现有技术”,我认为JNode本机代码编译器在Unsafe
类的版本中使用某些方法来做这种事情。但是,原语不是字节码。相反,它们是无法用字节码表示的东西。
以这种方式注入字节码对我来说似乎不是一个好主意:
有更好的方法可以做到这一点;例如BCEL。
将注入的字节码尝试与方法的其余部分进行集成可能会非常棘手(对程序员而言)。特别是考虑到方法其余部分的字节码将取决于你正在使用的java编译器。
对于传统JVM平台上的Java,您需要在加载类之前将Asm
“调用”转换为字节码。然后由验证者进行检查。