"Встроенная сборка" для байт-кодов Java

Я ищу существующие реализации следующей идеи: предположим, что кто-то хочет писать байтовые коды inline assembly внутри обычной Java-программы (большинство релевантных приложений будут включать в себя invokedynamic инструкцию, которая в других случаях не доступна на Java). Один из способов сделать это будет следующим:

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. Я знаю ASMifier ASM Framework, он не решает проблему, указанную выше.

Ответы

Ответ 1

ClassLoader имеет метод defineClass, который позволяет динамически генерировать класс, предоставляя байт-код. Объедините это с Javassist или другими предложениями из этого предыдущего вопроса.

Ответ 2

Если вы ищете "предшествующий уровень техники" для патента, я думаю, что собственный компилятор JNode-кода сделал подобные вещи с некоторыми методами в своей версии класса Unsafe. Однако примитивы не были байтокодами. Скорее, это были вещи, которые не могли быть выражены как байт-коды.


Включение байт-кодов таким образом не кажется мне хорошей идеей:

  • Есть лучшие способы сделать это; например BCEL.

  • Может быть сложно (для программиста) интегрировать то, что пытались делать инъецированные байт-коды с остальной частью метода. Особенно учитывая, что байт-коды для остальной части метода будут зависеть от того, какой java-компилятор вы используете.

  • Для Java на обычной платформе JVM вам нужно будет сделать перевод Asm "вызовов" на байт-коды... до загрузки класса. Затем он будет проверяться верификатором.