16

我正在寻找以下想法的现有实现:假设有人想在普通 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 调用。

PS 我知道 ASM 框架的 ASMifier,它不能解决上述问题。

4

2 回答 2

6

ClassLoader有一个方法,defineClass,它允许您通过提供字节码来动态生成一个类。将此与Javassist或上一个问题的其他建议结合起来。

于 2013-08-04T05:45:10.840 回答
1

如果您正在寻找专利的“现有技术”,我认为 JNode 本机代码编译器在其Unsafe类版本中使用一些方法完成了这种事情。但是,原语不是字节码。相反,它们是无法表示为字节码的东西。


以这种方式注入字节码对我来说似乎不是一个好主意:

  • 有更好的方法可以做到这一点;例如 BCEL。

  • 将注入的字节码试图与方法的其余部分集成起来可能很棘手(对于程序员来说)。特别是考虑到该方法其余部分的字节码将取决于您使用的 java 编译器。

  • 对于传统 JVM 平台上的 Java,您需要Asm在加载类之前将“调用”转换为字节码。然后它将接受验证者的检查。

于 2013-08-04T06:01:15.007 回答