Локальные переменные в MethodHandle

java.lang.invoke.MethodHandle и друзья позволяют генерировать исполняемый код, отвечающий требованиям JIT, с помощью ряда комбинаторов.

Как я могу создать локальные переменные в MethodHandles? В идеале метод подписи, который я хочу, выглядит примерно так

MethodHandle withLocalVariable(
    Class<?> varClazz, Function<VarHandle, MethodHandle> usingVar)

хотя я не уверен VarHandle на самом деле вполне правильная абстракция.

Обратите внимание, что просто создать переменную-держатель недостаточно хорошо - я хочу разные вызовы MethodHandle использовать разные переменные.

1 ответ

Решение

Вы не можете создать локальную переменную. Если вы хотите использовать значение несколько раз, вы можете создать сквозную передачу с identity а затем скопируйте значение с помощью permuteArguments (или просто использовать permuteArguments сам по себе, если вы можете) например:

MethodHandle start = identity(String.class);
MethodHandle sideEffect = lookup().findVirtual(PrintStream.class, "println", methodType(void.class, String.class)).bindTo(System.out);
MethodHandle result = collectArguments(start, 0, sideEffect); // sideEffect needs to return nothing
result = permuteArguments(result, methodType(String.class, String.class), 0, 0); // copy argument

System.out.println((String) result.invokeExact("Hello")); // Hello\nHello

Где переданный аргумент используется как в качестве аргумента дескриптора побочного эффекта, так и в качестве возвращаемого значения. По сути, вы можете использовать значение несколько раз.

Но на самом деле нет простого универсального ответа, когда дело доходит до дескрипторов методов. Возможно, лучший совет, который я могу дать, это стараться не использовать их как можно больше. т.е. напишите статический метод с нужным вам кодом, а затем используйте дескриптор метода для этого в более длинной цепочке дескрипторов метода.

Другие вопросы по тегам