3469 * variable-arity method handle}, even if the original target method handle was. 3470 * @param target the method handle to invoke after the argument is inserted 3471 * @param pos where to insert the argument (zero for the first) 3472 * @param values the series of arguments to insert 3473 * @return a method handle which inserts an additional argument, 3474 * before calling the original method handle 3475 * @throws NullPointerException if the target or the {@code values} array is null 3476 * @see MethodHandle#bindTo 3477 */ 3478 public static 3479 MethodHandle insertArguments(MethodHandle target, int pos, Object... values) { 3480 int insCount = values.length; 3481 Class<?>[] ptypes = insertArgumentsChecks(target, insCount, pos); 3482 if (insCount == 0) return target; 3483 BoundMethodHandle result = target.rebind(); 3484 for (int i = 0; i < insCount; i++) { 3485 Object value = values[i]; 3486 Class<?> ptype = ptypes[pos+i]; 3487 if (ptype.isPrimitive()) { 3488 result = insertArgumentPrimitive(result, pos, ptype, value); 3489 } else { 3490 value = ptype.cast(value); // throw CCE if needed 3491 result = result.bindArgumentL(pos, value); 3492 } 3493 } 3494 return result; 3495 } 3496 3497 private static BoundMethodHandle insertArgumentPrimitive(BoundMethodHandle result, int pos, 3498 Class<?> ptype, Object value) { 3499 Wrapper w = Wrapper.forPrimitiveType(ptype); 3500 // perform unboxing and/or primitive conversion 3501 value = w.convert(value, ptype); 3502 switch (w) { 3503 case INT: return result.bindArgumentI(pos, (int)value); 3504 case LONG: return result.bindArgumentJ(pos, (long)value); 3505 case FLOAT: return result.bindArgumentF(pos, (float)value); 3506 case DOUBLE: return result.bindArgumentD(pos, (double)value); 3507 default: return result.bindArgumentI(pos, ValueConversions.widenSubword(value)); 3508 } | 3469 * variable-arity method handle}, even if the original target method handle was. 3470 * @param target the method handle to invoke after the argument is inserted 3471 * @param pos where to insert the argument (zero for the first) 3472 * @param values the series of arguments to insert 3473 * @return a method handle which inserts an additional argument, 3474 * before calling the original method handle 3475 * @throws NullPointerException if the target or the {@code values} array is null 3476 * @see MethodHandle#bindTo 3477 */ 3478 public static 3479 MethodHandle insertArguments(MethodHandle target, int pos, Object... values) { 3480 int insCount = values.length; 3481 Class<?>[] ptypes = insertArgumentsChecks(target, insCount, pos); 3482 if (insCount == 0) return target; 3483 BoundMethodHandle result = target.rebind(); 3484 for (int i = 0; i < insCount; i++) { 3485 Object value = values[i]; 3486 Class<?> ptype = ptypes[pos+i]; 3487 if (ptype.isPrimitive()) { 3488 result = insertArgumentPrimitive(result, pos, ptype, value); 3489 } else if (MinimalValueTypes_1_0.isValueType(ptype)) { 3490 Class<?> vcc = MinimalValueTypes_1_0.getValueCapableClass(ptype); 3491 value = vcc.cast(value); // throw CCE if needed 3492 MethodHandle unbox = ValueType.forClass(vcc).unbox(); 3493 result = result.bindArgumentQ(pos, value, unbox); 3494 } else { 3495 value = ptype.cast(value); // throw CCE if needed 3496 result = result.bindArgumentL(pos, value); 3497 } 3498 } 3499 return result; 3500 } 3501 3502 private static BoundMethodHandle insertArgumentPrimitive(BoundMethodHandle result, int pos, 3503 Class<?> ptype, Object value) { 3504 Wrapper w = Wrapper.forPrimitiveType(ptype); 3505 // perform unboxing and/or primitive conversion 3506 value = w.convert(value, ptype); 3507 switch (w) { 3508 case INT: return result.bindArgumentI(pos, (int)value); 3509 case LONG: return result.bindArgumentJ(pos, (long)value); 3510 case FLOAT: return result.bindArgumentF(pos, (float)value); 3511 case DOUBLE: return result.bindArgumentD(pos, (double)value); 3512 default: return result.bindArgumentI(pos, ValueConversions.widenSubword(value)); 3513 } |