Reputation: 198014
java.lang.invoke.MethodHandle
and friends allow runtime code generation eligible for JIT via a series of combinators.
How can I create local variables in MethodHandles? Ideally, the method signature I want looks something like
MethodHandle withLocalVariable(
Class<?> varClazz, Function<VarHandle, MethodHandle> usingVar)
though I'm not sure VarHandle
is actually quite the right abstraction.
Note that just creating a holder variable isn't quite good enough -- I want different invocations of the MethodHandle
to use different variables.
Upvotes: 1
Views: 200
Reputation: 33845
You can not create a local variable. If you want to use a value multiple times you could create a pass-through with identity
and then copy the value using permuteArguments
(or just use permuteArguments
by itself if you can) e.g.:
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
Where the passed argument is used both as an argument to the side effect handle and as a return value. Essentially you can use the value multiple times.
But there's really no easy one-fits-all answer when it comes to method handles. Perhaps the best advice I can give is to try and not use them as much as possible. i.e. write a static method with the code you need and then use a method handle to that in a longer method handle chain.
Upvotes: 1