/** * Compute and cache information for this adapter, so that it can call out to targets of the * erasure-family of the given erased type. */ /*non-public*/ InvokeGeneric(MethodType erasedCallerType) throws ReflectiveOperationException { assert (erasedCallerType.equals(erasedCallerType.erase())); this.erasedCallerType = erasedCallerType; this.initialInvoker = makeInitialInvoker(); assert initialInvoker .type() .equals(erasedCallerType.insertParameterTypes(0, MethodType.class, MethodHandle.class)) : initialInvoker.type(); }
private MethodHandle addReturnConversion(MethodHandle finisher, Class<?> type) { // FIXME: This is slow because it creates a closure node on every call that requires a return // cast. MethodType finisherType = finisher.type(); MethodHandle caster = ValueConversions.identity(type); caster = caster.asType(caster.type().changeParameterType(0, finisherType.returnType())); finisher = MethodHandles.filterReturnValue(finisher, caster); return finisher.asType(finisherType); }
/** * Return a method handle to invoke on the callerType, target, and remaining arguments. The method * handle must finish the call. This is the first look at the caller type and target. */ private MethodHandle dispatch(MethodType callerType, MethodHandle target) { MethodType targetType = target.type(); if (USE_AS_TYPE_PATH || target.isVarargsCollector()) { MethodHandle newTarget = target.asType(callerType); targetType = callerType; Invokers invokers = targetType.invokers(); MethodHandle invoker = invokers.erasedInvokerWithDrops; if (invoker == null) { invokers.erasedInvokerWithDrops = invoker = dropDispatchArguments(invokers.erasedInvoker()); } return invoker.bindTo(newTarget); } throw new RuntimeException("NYI"); }
private boolean returnConversionNeeded(MethodType callerType, MethodHandle target) { Class<?> needType = callerType.returnType(); if (needType == erasedCallerType.returnType()) return false; // no conversions possible, since must be primitive or Object Class<?> haveType = target.type().returnType(); if (VerifyType.isNullConversion(haveType, needType) && !needType.isInterface()) return false; return true; }
private MethodHandle dropDispatchArguments(MethodHandle targetInvoker) { assert (targetInvoker.type().parameterType(0) == MethodHandle.class); return MethodHandles.dropArguments(targetInvoker, 1, EXTRA_ARGS); }