Louis Wasserman
Louis Wasserman

Reputation: 198014

Local variables in MethodHandle

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

Answers (1)

Jorn Vernee
Jorn Vernee

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

Related Questions