On Fri, Jun 10, 2011 at 6:36 PM, Charles Oliver Nutter
<[email protected]> wrote:
> I can handle the exceptional case with MethodHandles.catchException
> ok. There's no return value because an exception was thrown, so I just
> do the post logic and propagate the exception. But I can't handle the
> non-exceptional case; there's no way to do post-processing of a call.
> What I really need is something like:
>
> MethodHandles.postProcess(mh, post)
>
> where the "post" handle will receive the incoming arguments AND the
> result of the call and decide what to return.
>
> Of course I would discover this in June, right after high resistance
> for Java 7 :(
And of course I'd come to this realization on a Friday when Europe is
already going to sleep and US is approaching COB.
First off, I'm more and more convinced this is a hole. catchException
mentions doing try/finally logic, but the finally part will never fire
if there's no exception raised. That's obviously only covering half
the story for try/finally; we're missing the insertion of the finally
logic after non-exceptional return.
Brainstorming ways this could be fixed in JSR-292, if it's not already
impossible to do so.
1. A new MethodHandles API postProcess, that receives all incoming
arguments, invokes the handle, and runs a post-processor on the
arguments plus the result of the handle
int blah(Object arg1) {
try {
return foo(arg1);
} finally {
post(arg1);
}
}
would become:
int postCall(int retVal, Object arg1) {
post(arg1);
return retVal;
}
int postException(Throwable exception, Object arg1) throws Throwable {
post(arg1);
throw exception;
}
MethodHandles foo = <get foo() handle>
MethodHandles postCall = <get postCall() handle>
MethodHandles postException = <get postException() handle>
MethodHandle result = MethodHandles.postProcess(foo, postCall)
result = MethodHandles.catchException(result, Throwable.class, postException);
This is *pretty close* to real finally logic; the flaw in this design
is that exceptions from postCall will *also* end up in postException.
2. A new overload for catchException that takes a *non-exceptional*
handler. If there's no exception, the non-exceptional handler is
called with the original arguments and the target's return value. The
Java code above would become:
int postCall(int retVal, Object arg1) {
post(arg1);
return retVal;
}
int postException(Throwable exception, Object arg1) throws Throwable {
post(arg1);
throw exception;
}
MethodHandles foo = <get foo() handle>
MethodHandles postCall = <get postCall() handle>
MethodHandles postException = <get postException() handle>
MethodHandle result = MethodHandles.catchException(foo,
Throwable.class, postException, postCall);
This *would* do the correct thing for both paths, since postException
and postCall are mutually exclusive here.
There may be a more generalized form possible, too.
- Charlie
--
You received this message because you are subscribed to the Google Groups "JVM
Languages" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/jvm-languages?hl=en.