MethodType invokedType = MethodType.fromMethodDescriptorString(indyNameAndDescriptor.substring(descriptorStart), callerLoader);
// Use bsmArgs to build the parameters
MethodType samMethodType = MethodType.fromMethodDescriptorString((String)(((Type)bsmArgs[0]).getDescriptor()), callerLoader);
Handle bsmArgsHandle = (Handle)bsmArgs[1];
String owner = bsmArgsHandle.getOwner();
String name = bsmArgsHandle.getName();
String descriptor = bsmArgsHandle.getDesc();
MethodType implMethodType = MethodType.fromMethodDescriptorString(descriptor, callerLoader);
// Looking up the lambda$run method in the caller class (note the caller class is the executor, which gets us around the
// problem of having to hack into LambdaMetafactory to intercept reflection)
MethodHandle implMethod = null;
switch (bsmArgsHandle.getTag()) {
case Opcodes.H_INVOKESTATIC:
implMethod = caller.findStatic(caller.lookupClass(), name, implMethodType);
break;
case Opcodes.H_INVOKESPECIAL:
// If there is an executor, the lambda function is actually modified from 'private instance' to 'public static' so adjust lookup. The method
// will be static with a new leading parameter.
if (executorClass == null) {
// TODO is final parameter here correct?
implMethod = caller.findSpecial(caller.lookupClass(), name, implMethodType, caller.lookupClass());
}
else {
implMethod = caller.findStatic(caller.lookupClass(), name, MethodType.fromMethodDescriptorString("(L"+owner+";"+descriptor.substring(1),callerLoader));
}
break;
case Opcodes.H_INVOKEVIRTUAL:
// If there is an executor, the lambda function is actually modified from 'private instance' to 'public static' so adjust lookup. The method
// will be static with a new leading parameter.
if (executorClass == null) {
// TODO when can this scenario occur? Aren't we only here if reloading has happened?
implMethod = caller.findVirtual(caller.lookupClass(), name, implMethodType);
}
else {
implMethod = caller.findStatic(caller.lookupClass(), name, MethodType.fromMethodDescriptorString("(L"+owner+";"+descriptor.substring(1),callerLoader));
}
break;
default:
throw new IllegalStateException("nyi "+bsmArgsHandle.getTag());
}
MethodType instantiatedMethodType = MethodType.fromMethodDescriptorString((String)(((Type)bsmArgs[2]).getDescriptor()), callerLoader);
return LambdaMetafactory.metafactory(caller, invokedName, invokedType, samMethodType, implMethod, instantiatedMethodType);