use of java.lang.invoke.MethodHandle in project gravel by gravel-st.
the class SuperCallSite method lookupMethod.
public MethodHandle lookupMethod(Class receiverClass, String selector) {
Reference reference = Reference.factory.value_(lookupStart);
AbstractMethodMapping mapping = ImageBootstrapper.systemMapping.superMethodMappingFor_methodName_(reference, selector);
if (mapping == null) {
if (selector.equals("doesNotUnderstand_"))
throw new RuntimeException("Can't find DNU method");
return wrapDNUHandle(lookupMethod(receiverClass, "doesNotUnderstand_"));
}
MethodHandle methodHandle;
try {
Method method = MethodTools.searchForMethod(mapping.definingClass(), selector, type.parameterArray(), true);
if (method != null) {
return mapping.methodHandle().asType(type);
}
methodHandle = lookup.findSpecial(mapping.definingClass(), selector, type.dropParameterTypes(0, 1), lookup.lookupClass());
} catch (NoSuchMethodException | IllegalAccessException r) {
try {
methodHandle = lookup.findStatic(mapping.definingClass(), selector, type);
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
return methodHandle.asType(type);
}
use of java.lang.invoke.MethodHandle in project gravel by gravel-st.
the class SuperCallSite method addTargetToCache.
@Override
protected void addTargetToCache(Object receiver) {
Class receiverClass = receiver.getClass();
MethodHandle target = lookupMethod(receiverClass);
setTarget(target);
}
use of java.lang.invoke.MethodHandle in project invokebinder by headius.
the class TryFinally method up.
public MethodHandle up(MethodHandle target) {
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);
}
use of java.lang.invoke.MethodHandle in project invokebinder by headius.
the class BinderTest method testTryFinallyReturn3.
@Test
public void testTryFinallyReturn3() throws Throwable {
MethodHandle post = Binder.from(void.class, String[].class).invokeStatic(LOOKUP, BinderTest.class, "finallyLogic");
MethodHandle ignoreException = Binder.from(int.class, BlahException.class, String[].class).drop(0, 2).constant(1);
MethodHandle handle = Binder.from(int.class, String[].class).tryFinally(post).catchException(BlahException.class, ignoreException).invokeStatic(LOOKUP, BinderTest.class, "setZeroToFooReturnIntAndRaise");
assertEquals(MethodType.methodType(int.class, String[].class), handle.type());
String[] stringAry = new String[1];
try {
assertEquals(1, (int) handle.invokeExact(stringAry));
} catch (BlahException be) {
assertTrue("should not have reached here", false);
}
assertEquals("foofinally", stringAry[0]);
}
use of java.lang.invoke.MethodHandle in project invokebinder by headius.
the class BinderTest method testConstant.
@Test
public void testConstant() throws Throwable {
MethodHandle handle = Binder.from(String.class).constant("hello");
assertEquals(MethodType.methodType(String.class), handle.type());
assertEquals("hello", (String) handle.invokeExact());
}
Aggregations