On Fri, Jun 10, 2011 at 6:36 PM, Charles Oliver Nutter
<head...@headius.com> 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 jvm-languages@googlegroups.com.
To unsubscribe from this group, send email to 
jvm-languages+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/jvm-languages?hl=en.

Reply via email to