2563 * creating collectors.
2564 *
2565 * Make sure arguments are paired correctly.
2566 * @param methodHandle MethodHandle to adjust.
2567 * @param callType MethodType of the call site.
2568 * @param callerVarArg true if the caller is vararg, false otherwise, null if it should be inferred from the
2569 * {@code callType}; basically, if the last parameter type of the call site is an array, it'll be considered a
2570 * variable arity call site. These are ordinarily rare; Nashorn code generator creates variable arity call sites
2571 * when the call has more than {@link LinkerCallSite#ARGLIMIT} parameters.
2572 *
2573 * @return method handle with adjusted arguments
2574 */
2575 public static MethodHandle pairArguments(final MethodHandle methodHandle, final MethodType callType, final Boolean callerVarArg) {
2576 final MethodType methodType = methodHandle.type();
2577 if (methodType.equals(callType.changeReturnType(methodType.returnType()))) {
2578 return methodHandle;
2579 }
2580
2581 final int parameterCount = methodType.parameterCount();
2582 final int callCount = callType.parameterCount();
2583
2584 final boolean isCalleeVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
2585 final boolean isCallerVarArg = callerVarArg != null ? callerVarArg.booleanValue() : callCount > 0 &&
2586 callType.parameterType(callCount - 1).isArray();
2587
2588 if (isCalleeVarArg) {
2589 return isCallerVarArg ?
2590 methodHandle :
2591 MH.asCollector(methodHandle, Object[].class, callCount - parameterCount + 1);
2592 }
2593
2594 if (isCallerVarArg) {
2595 return adaptHandleToVarArgCallSite(methodHandle, callCount);
2596 }
2597
2598 if (callCount < parameterCount) {
2599 final int missingArgs = parameterCount - callCount;
2600 final Object[] fillers = new Object[missingArgs];
2601
2602 Arrays.fill(fillers, UNDEFINED);
2603
2604 if (isCalleeVarArg) {
2605 fillers[missingArgs - 1] = ScriptRuntime.EMPTY_ARRAY;
2606 }
2607
2608 return MH.insertArguments(
2609 methodHandle,
2610 parameterCount - missingArgs,
2611 fillers);
|
2563 * creating collectors.
2564 *
2565 * Make sure arguments are paired correctly.
2566 * @param methodHandle MethodHandle to adjust.
2567 * @param callType MethodType of the call site.
2568 * @param callerVarArg true if the caller is vararg, false otherwise, null if it should be inferred from the
2569 * {@code callType}; basically, if the last parameter type of the call site is an array, it'll be considered a
2570 * variable arity call site. These are ordinarily rare; Nashorn code generator creates variable arity call sites
2571 * when the call has more than {@link LinkerCallSite#ARGLIMIT} parameters.
2572 *
2573 * @return method handle with adjusted arguments
2574 */
2575 public static MethodHandle pairArguments(final MethodHandle methodHandle, final MethodType callType, final Boolean callerVarArg) {
2576 final MethodType methodType = methodHandle.type();
2577 if (methodType.equals(callType.changeReturnType(methodType.returnType()))) {
2578 return methodHandle;
2579 }
2580
2581 final int parameterCount = methodType.parameterCount();
2582 final int callCount = callType.parameterCount();
2583 final int pdiff = callCount - parameterCount + 1;
2584
2585 final boolean isCalleeVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
2586 final boolean isCallerVarArg = callerVarArg != null ? callerVarArg : callCount > 0 &&
2587 callType.parameterType(callCount - 1).isArray();
2588
2589 // A value of pdiff < 0 means that there are additional normal arguments in the callee that must not be consumed
2590 // by the vararg collector. No vararg collector is required in that case, and no varargs are passed.
2591 if (isCalleeVarArg && pdiff >= 0) {
2592 return isCallerVarArg ?
2593 methodHandle :
2594 MH.asCollector(methodHandle, Object[].class, pdiff);
2595 }
2596
2597 if (isCallerVarArg) {
2598 return adaptHandleToVarArgCallSite(methodHandle, callCount);
2599 }
2600
2601 if (callCount < parameterCount) {
2602 final int missingArgs = parameterCount - callCount;
2603 final Object[] fillers = new Object[missingArgs];
2604
2605 Arrays.fill(fillers, UNDEFINED);
2606
2607 if (isCalleeVarArg) {
2608 fillers[missingArgs - 1] = ScriptRuntime.EMPTY_ARRAY;
2609 }
2610
2611 return MH.insertArguments(
2612 methodHandle,
2613 parameterCount - missingArgs,
2614 fillers);
|