// checkArity(desc.anno, method, specificArity);
SmartBinder targetBinder;
SmartHandle target;
Signature baseSignature;
if (specificArity >= 0) {
baseSignature = SPECIFIC_ARITY_SIGNATURES[specificArity];
} else {
baseSignature = VARIABLE_ARITY_SIGNATURE;
}
targetBinder = SmartBinder.from(baseSignature);
MethodHandle returnFilter = null;
boolean castReturn = false;
if (desc.returnClass != IRubyObject.class) {
if (desc.returnClass == void.class) {
returnFilter = MethodHandles.constant(IRubyObject.class, runtime.getNil());
} else {
castReturn = true;
}
}
if (desc.isStatic) {
if (desc.hasContext) {
if (desc.hasBlock) {
// straight through with no permutation necessary
} else {
targetBinder = targetBinder.exclude("block");
}
} else {
if (desc.hasBlock) {
targetBinder = targetBinder.exclude("context");
} else {
targetBinder = targetBinder.exclude("context", "block");
}
}
if (returnFilter != null) {
targetBinder = targetBinder
.filterReturn(returnFilter);
} else if (castReturn) {
targetBinder = targetBinder
.castReturn(desc.returnClass);
}
} else {
if (desc.hasContext) {
if (desc.hasBlock) {
targetBinder = targetBinder.permute("self", "context", "arg*", "block");
} else {
targetBinder = targetBinder.permute("self", "context", "arg*");
}
} else {
if (desc.hasBlock) {
targetBinder = targetBinder.permute("self", "arg*", "block");
} else {
targetBinder = targetBinder.permute("self", "arg*");
}
}
if (returnFilter != null) {
targetBinder = targetBinder
.filterReturn(returnFilter);
} else if (castReturn) {
targetBinder = targetBinder
.castReturn(desc.returnClass);
}
targetBinder = targetBinder
.castArg("self", desc.getDeclaringClass());
}
if (desc.isStatic) {
target = targetBinder
.invokeStaticQuiet(LOOKUP, desc.getDeclaringClass(), javaMethodName);
} else {
target = targetBinder
.invokeVirtualQuiet(LOOKUP, javaMethodName);
}
CallConfiguration callConfig = CallConfiguration.getCallConfigByAnno(desc.anno);
if (!callConfig.isNoop()) {
target = SmartHandle
.from(target.signature(), InvocationLinker.wrapWithFraming(baseSignature, callConfig, implementationClass, rubyName, target.handle(), null));
}
if (specificArity >= 0) {
targets[specificArity] = target.handle();
} else {
targets[4] = target.handle();
}
}
if (targets[4] == null) {
// provide a variable-arity path for specific-arity target
Signature VARIABLE_ARITY_SIGNATURE = Signature
.returning(IRubyObject.class)
.appendArg("context", ThreadContext.class)
.appendArg("self", IRubyObject.class)
.appendArg("args", IRubyObject[].class)
.appendArg("block", Block.class);