ANN: InvokeBinder
Charles Oliver Nutter
headius at headius.com
Sat Feb 4 08:39:03 PST 2012
InvokeBinder is a small Java DSL for binding method handles *forward*
rather than *backward* from target endpoint.
https://github.com/headius/invokebinder/
I've finished mapping MethodHandles.* and Lookup.* to its API, and
have also added a couple convenience utilities like tryFinally and nop
that are hard or confusing to implement with the MethodHandles API.
I'm interested in incorporating other utilities and patterns that you
might have...feel free to submit a pull request.
Not released to Maven yet, but will be soon as 1.0.
BinderTest (https://github.com/headius/invokebinder/blob/master/src/test/java/com/headius/invoke/binder/BinderTest.java)
has several good examples but I'm particularly proud of tryFinally:
MethodHandle post = Binder
.from(void.class, String[].class)
.invokeStatic(MethodHandles.lookup(),
BinderTest.class, "finallyLogic");
MethodHandle handle = Binder
.from(void.class, String[].class)
.tryFinally(post)
.invokeStatic(MethodHandles.lookup(),
BinderTest.class, "setZeroToFoo");
Which is implemented as follows:
MethodHandle exceptionHandler = Binder
.from(target.type().insertParameterTypes(0,
Throwable.class).changeReturnType(void.class))
.drop(0)
.invoke(post);
MethodHandle rethrow = Binder
.from(target.type().insertParameterTypes(0, Throwable.class))
.fold(exceptionHandler)
.drop(1, target.type().parameterCount())
.throwException();
target = MethodHandles.catchException(target, Throwable.class, rethrow);
// if target returns a value, we must return it regardless of post
MethodHandle realPost = post;
if (target.type().returnType() != void.class) {
// modify post to ignore return value
MethodHandle newPost = Binder
.from(target.type().insertParameterTypes(0,
target.type().returnType()).changeReturnType(void.class))
.drop(0)
.invoke(post);
// fold post into an identity chain that only returns the value
realPost = Binder
.from(target.type().insertParameterTypes(0,
target.type().returnType()))
.fold(newPost)
.drop(1, target.type().parameterCount())
.identity();
}
return MethodHandles.foldArguments(realPost, target);
Which would be quite a bit more code (and more confusing) using the
MethodHandles API directly.
- Charlie
More information about the mlvm-dev
mailing list