ANN: InvokeBinder

30 views
Skip to first unread message

Charles Oliver Nutter

unread,
Feb 4, 2012, 11:39:03 AM2/4/12
to Da Vinci Machine Project, JVM Languages
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

Jochen Theodorou

unread,
Feb 4, 2012, 1:54:43 PM2/4/12
to jvm-la...@googlegroups.com
Am 04.02.2012 17:39, schrieb Charles Oliver Nutter:
> 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.

In general I have till now a bit a problem of keeping the numbers of
method handles low. If I for example have to bind multiple values at
different places in my code, this usually turns out to be multiple
insertArguments calls, each of them producing new method handles. I am
wondering how to avoid that problem

bye Jochen

--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org

Reply all
Reply to author
Forward
0 new messages