jdk/src/java.base/share/classes/sun/invoke/util/ValueConversions.java
changeset 26466 3bbb6a284bd4
parent 25859 3317bb8137f4
child 26474 655d08549e43
equal deleted inserted replaced
26465:5ff735dd0d52 26466:3bbb6a284bd4
    27 
    27 
    28 import java.lang.invoke.MethodHandle;
    28 import java.lang.invoke.MethodHandle;
    29 import java.lang.invoke.MethodHandles;
    29 import java.lang.invoke.MethodHandles;
    30 import java.lang.invoke.MethodHandles.Lookup;
    30 import java.lang.invoke.MethodHandles.Lookup;
    31 import java.lang.invoke.MethodType;
    31 import java.lang.invoke.MethodType;
    32 import java.security.AccessController;
       
    33 import java.security.PrivilegedAction;
       
    34 import java.util.ArrayList;
       
    35 import java.util.Arrays;
       
    36 import java.util.Collections;
       
    37 import java.util.EnumMap;
    32 import java.util.EnumMap;
    38 import java.util.List;
       
    39 
    33 
    40 public class ValueConversions {
    34 public class ValueConversions {
    41     private static final Class<?> THIS_CLASS = ValueConversions.class;
    35     private static final Class<?> THIS_CLASS = ValueConversions.class;
    42     // Do not adjust this except for special platforms:
       
    43     private static final int MAX_ARITY;
       
    44     static {
       
    45         final Object[] values = { 255 };
       
    46         AccessController.doPrivileged(new PrivilegedAction<Void>() {
       
    47                 @Override
       
    48                 public Void run() {
       
    49                     values[0] = Integer.getInteger(THIS_CLASS.getName()+".MAX_ARITY", 255);
       
    50                     return null;
       
    51                 }
       
    52             });
       
    53         MAX_ARITY = (Integer) values[0];
       
    54     }
       
    55 
       
    56     private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
    36     private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
    57 
    37 
    58     private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) {
    38     private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) {
    59         @SuppressWarnings("unchecked")  // generic array creation
    39         @SuppressWarnings("unchecked")  // generic array creation
    60         EnumMap<Wrapper, MethodHandle>[] caches
    40         EnumMap<Wrapper, MethodHandle>[] caches
   441 
   421 
   442     static double identity(double x) {
   422     static double identity(double x) {
   443         return x;
   423         return x;
   444     }
   424     }
   445 
   425 
   446     private static ClassCastException newClassCastException(Class<?> t, Object obj) {
   426     private static final MethodHandle IDENTITY, CAST_REFERENCE, ZERO_OBJECT, IGNORE, EMPTY;
   447         return new ClassCastException("Cannot cast " + obj.getClass().getName() + " to " + t.getName());
       
   448     }
       
   449 
       
   450     private static final MethodHandle IDENTITY, CAST_REFERENCE, ZERO_OBJECT, IGNORE, EMPTY,
       
   451             ARRAY_IDENTITY, FILL_NEW_TYPED_ARRAY, FILL_NEW_ARRAY;
       
   452     static {
   427     static {
   453         try {
   428         try {
   454             MethodType idType = MethodType.genericMethodType(1);
   429             MethodType idType = MethodType.genericMethodType(1);
   455             MethodType ignoreType = idType.changeReturnType(void.class);
   430             MethodType ignoreType = idType.changeReturnType(void.class);
   456             MethodType zeroObjectType = MethodType.genericMethodType(0);
   431             MethodType zeroObjectType = MethodType.genericMethodType(0);
   457             IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType);
   432             IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType);
   458             CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
   433             CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
   459             ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType);
   434             ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType);
   460             IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
   435             IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
   461             EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
   436             EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
   462             ARRAY_IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(Object[].class, Object[].class));
       
   463             FILL_NEW_ARRAY = IMPL_LOOKUP
       
   464                     .findStatic(THIS_CLASS, "fillNewArray",
       
   465                           MethodType.methodType(Object[].class, Integer.class, Object[].class));
       
   466             FILL_NEW_TYPED_ARRAY = IMPL_LOOKUP
       
   467                     .findStatic(THIS_CLASS, "fillNewTypedArray",
       
   468                           MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
       
   469         } catch (NoSuchMethodException | IllegalAccessException ex) {
   437         } catch (NoSuchMethodException | IllegalAccessException ex) {
   470             throw newInternalError("uncaught exception", ex);
   438             throw newInternalError("uncaught exception", ex);
   471         }
       
   472     }
       
   473 
       
   474     // Varargs methods need to be in a separately initialized class, to avoid bootstrapping problems.
       
   475     static class LazyStatics {
       
   476         private static final MethodHandle COPY_AS_REFERENCE_ARRAY, COPY_AS_PRIMITIVE_ARRAY, MAKE_LIST;
       
   477         static {
       
   478             try {
       
   479                 //MAKE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeArray", MethodType.methodType(Object[].class, Object[].class));
       
   480                 COPY_AS_REFERENCE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsReferenceArray", MethodType.methodType(Object[].class, Class.class, Object[].class));
       
   481                 COPY_AS_PRIMITIVE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsPrimitiveArray", MethodType.methodType(Object.class, Wrapper.class, Object[].class));
       
   482                 MAKE_LIST = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeList", MethodType.methodType(List.class, Object[].class));
       
   483             } catch (ReflectiveOperationException ex) {
       
   484                 throw newInternalError("uncaught exception", ex);
       
   485             }
       
   486         }
   439         }
   487     }
   440     }
   488 
   441 
   489     private static final EnumMap<Wrapper, MethodHandle>[] WRAPPER_CASTS
   442     private static final EnumMap<Wrapper, MethodHandle>[] WRAPPER_CASTS
   490             = newWrapperCaches(1);
   443             = newWrapperCaches(1);
   806 
   759 
   807     private static String capitalize(String x) {
   760     private static String capitalize(String x) {
   808         return Character.toUpperCase(x.charAt(0))+x.substring(1);
   761         return Character.toUpperCase(x.charAt(0))+x.substring(1);
   809     }
   762     }
   810 
   763 
   811     /// Collection of multiple arguments.
       
   812 
       
   813     public static Object convertArrayElements(Class<?> arrayType, Object array) {
       
   814         Class<?> src = array.getClass().getComponentType();
       
   815         Class<?> dst = arrayType.getComponentType();
       
   816         if (src == null || dst == null)  throw new IllegalArgumentException("not array type");
       
   817         Wrapper sw = (src.isPrimitive() ? Wrapper.forPrimitiveType(src) : null);
       
   818         Wrapper dw = (dst.isPrimitive() ? Wrapper.forPrimitiveType(dst) : null);
       
   819         int length;
       
   820         if (sw == null) {
       
   821             Object[] a = (Object[]) array;
       
   822             length = a.length;
       
   823             if (dw == null)
       
   824                 return Arrays.copyOf(a, length, arrayType.asSubclass(Object[].class));
       
   825             Object res = dw.makeArray(length);
       
   826             dw.copyArrayUnboxing(a, 0, res, 0, length);
       
   827             return res;
       
   828         }
       
   829         length = java.lang.reflect.Array.getLength(array);
       
   830         Object[] res;
       
   831         if (dw == null) {
       
   832             res = Arrays.copyOf(NO_ARGS_ARRAY, length, arrayType.asSubclass(Object[].class));
       
   833         } else {
       
   834             res = new Object[length];
       
   835         }
       
   836         sw.copyArrayBoxing(array, 0, res, 0, length);
       
   837         if (dw == null)  return res;
       
   838         Object a = dw.makeArray(length);
       
   839         dw.copyArrayUnboxing(res, 0, a, 0, length);
       
   840         return a;
       
   841     }
       
   842 
       
   843     private static MethodHandle findCollector(String name, int nargs, Class<?> rtype, Class<?>... ptypes) {
       
   844         MethodType type = MethodType.genericMethodType(nargs)
       
   845                 .changeReturnType(rtype)
       
   846                 .insertParameterTypes(0, ptypes);
       
   847         try {
       
   848             return IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
       
   849         } catch (ReflectiveOperationException ex) {
       
   850             return null;
       
   851         }
       
   852     }
       
   853 
       
   854     private static final Object[] NO_ARGS_ARRAY = {};
       
   855     private static Object[] makeArray(Object... args) { return args; }
       
   856     private static Object[] array() { return NO_ARGS_ARRAY; }
       
   857     private static Object[] array(Object a0)
       
   858                 { return makeArray(a0); }
       
   859     private static Object[] array(Object a0, Object a1)
       
   860                 { return makeArray(a0, a1); }
       
   861     private static Object[] array(Object a0, Object a1, Object a2)
       
   862                 { return makeArray(a0, a1, a2); }
       
   863     private static Object[] array(Object a0, Object a1, Object a2, Object a3)
       
   864                 { return makeArray(a0, a1, a2, a3); }
       
   865     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
       
   866                                   Object a4)
       
   867                 { return makeArray(a0, a1, a2, a3, a4); }
       
   868     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
       
   869                                   Object a4, Object a5)
       
   870                 { return makeArray(a0, a1, a2, a3, a4, a5); }
       
   871     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
       
   872                                   Object a4, Object a5, Object a6)
       
   873                 { return makeArray(a0, a1, a2, a3, a4, a5, a6); }
       
   874     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
       
   875                                   Object a4, Object a5, Object a6, Object a7)
       
   876                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
       
   877     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
       
   878                                   Object a4, Object a5, Object a6, Object a7,
       
   879                                   Object a8)
       
   880                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
       
   881     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
       
   882                                   Object a4, Object a5, Object a6, Object a7,
       
   883                                   Object a8, Object a9)
       
   884                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
       
   885     private static MethodHandle[] makeArrays() {
       
   886         ArrayList<MethodHandle> mhs = new ArrayList<>();
       
   887         for (;;) {
       
   888             MethodHandle mh = findCollector("array", mhs.size(), Object[].class);
       
   889             if (mh == null)  break;
       
   890             mhs.add(mh);
       
   891         }
       
   892         assert(mhs.size() == 11);  // current number of methods
       
   893         return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
       
   894     }
       
   895     private static final MethodHandle[] ARRAYS = makeArrays();
       
   896 
       
   897     // filling versions of the above:
       
   898     // using Integer len instead of int len and no varargs to avoid bootstrapping problems
       
   899     private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
       
   900         Object[] a = new Object[len];
       
   901         fillWithArguments(a, 0, args);
       
   902         return a;
       
   903     }
       
   904     private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
       
   905         Object[] a = Arrays.copyOf(example, len);
       
   906         fillWithArguments(a, 0, args);
       
   907         return a;
       
   908     }
       
   909     private static void fillWithArguments(Object[] a, int pos, Object... args) {
       
   910         System.arraycopy(args, 0, a, pos, args.length);
       
   911     }
       
   912     // using Integer pos instead of int pos to avoid bootstrapping problems
       
   913     private static Object[] fillArray(Integer pos, Object[] a, Object a0)
       
   914                 { fillWithArguments(a, pos, a0); return a; }
       
   915     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1)
       
   916                 { fillWithArguments(a, pos, a0, a1); return a; }
       
   917     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2)
       
   918                 { fillWithArguments(a, pos, a0, a1, a2); return a; }
       
   919     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3)
       
   920                 { fillWithArguments(a, pos, a0, a1, a2, a3); return a; }
       
   921     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
       
   922                                   Object a4)
       
   923                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
       
   924     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
       
   925                                   Object a4, Object a5)
       
   926                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
       
   927     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
       
   928                                   Object a4, Object a5, Object a6)
       
   929                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
       
   930     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
       
   931                                   Object a4, Object a5, Object a6, Object a7)
       
   932                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
       
   933     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
       
   934                                   Object a4, Object a5, Object a6, Object a7,
       
   935                                   Object a8)
       
   936                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
       
   937     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
       
   938                                   Object a4, Object a5, Object a6, Object a7,
       
   939                                   Object a8, Object a9)
       
   940                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
       
   941     private static MethodHandle[] makeFillArrays() {
       
   942         ArrayList<MethodHandle> mhs = new ArrayList<>();
       
   943         mhs.add(null);  // there is no empty fill; at least a0 is required
       
   944         for (;;) {
       
   945             MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
       
   946             if (mh == null)  break;
       
   947             mhs.add(mh);
       
   948         }
       
   949         assert(mhs.size() == 11);  // current number of methods
       
   950         return mhs.toArray(new MethodHandle[0]);
       
   951     }
       
   952     private static final MethodHandle[] FILL_ARRAYS = makeFillArrays();
       
   953 
       
   954     private static Object[] copyAsReferenceArray(Class<? extends Object[]> arrayType, Object... a) {
       
   955         return Arrays.copyOf(a, a.length, arrayType);
       
   956     }
       
   957     private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
       
   958         Object a = w.makeArray(boxes.length);
       
   959         w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);
       
   960         return a;
       
   961     }
       
   962 
       
   963     /** Return a method handle that takes the indicated number of Object
       
   964      *  arguments and returns an Object array of them, as if for varargs.
       
   965      */
       
   966     public static MethodHandle varargsArray(int nargs) {
       
   967         MethodHandle mh = ARRAYS[nargs];
       
   968         if (mh != null)  return mh;
       
   969         mh = findCollector("array", nargs, Object[].class);
       
   970         if (mh != null)  return ARRAYS[nargs] = mh;
       
   971         mh = buildVarargsArray(FILL_NEW_ARRAY, ARRAY_IDENTITY, nargs);
       
   972         assert(assertCorrectArity(mh, nargs));
       
   973         return ARRAYS[nargs] = mh;
       
   974     }
       
   975 
       
   976     private static boolean assertCorrectArity(MethodHandle mh, int arity) {
       
   977         assert(mh.type().parameterCount() == arity) : "arity != "+arity+": "+mh;
       
   978         return true;
       
   979     }
       
   980 
       
   981     private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
       
   982         // Build up the result mh as a sequence of fills like this:
       
   983         //   finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
       
   984         // The various fill(_,10*I,___*[J]) are reusable.
       
   985         int leftLen = Math.min(nargs, LEFT_ARGS);  // absorb some arguments immediately
       
   986         int rightLen = nargs - leftLen;
       
   987         MethodHandle leftCollector = newArray.bindTo(nargs);
       
   988         leftCollector = leftCollector.asCollector(Object[].class, leftLen);
       
   989         MethodHandle mh = finisher;
       
   990         if (rightLen > 0) {
       
   991             MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen);
       
   992             if (mh == ARRAY_IDENTITY)
       
   993                 mh = rightFiller;
       
   994             else
       
   995                 mh = MethodHandles.collectArguments(mh, 0, rightFiller);
       
   996         }
       
   997         if (mh == ARRAY_IDENTITY)
       
   998             mh = leftCollector;
       
   999         else
       
  1000             mh = MethodHandles.collectArguments(mh, 0, leftCollector);
       
  1001         return mh;
       
  1002     }
       
  1003 
       
  1004     private static final int LEFT_ARGS = (FILL_ARRAYS.length - 1);
       
  1005     private static final MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1];
       
  1006     /** fill_array_to_right(N).invoke(a, argL..arg[N-1])
       
  1007      *  fills a[L]..a[N-1] with corresponding arguments,
       
  1008      *  and then returns a.  The value L is a global constant (LEFT_ARGS).
       
  1009      */
       
  1010     private static MethodHandle fillToRight(int nargs) {
       
  1011         MethodHandle filler = FILL_ARRAY_TO_RIGHT[nargs];
       
  1012         if (filler != null)  return filler;
       
  1013         filler = buildFiller(nargs);
       
  1014         assert(assertCorrectArity(filler, nargs - LEFT_ARGS + 1));
       
  1015         return FILL_ARRAY_TO_RIGHT[nargs] = filler;
       
  1016     }
       
  1017     private static MethodHandle buildFiller(int nargs) {
       
  1018         if (nargs <= LEFT_ARGS)
       
  1019             return ARRAY_IDENTITY;  // no args to fill; return the array unchanged
       
  1020         // we need room for both mh and a in mh.invoke(a, arg*[nargs])
       
  1021         final int CHUNK = LEFT_ARGS;
       
  1022         int rightLen = nargs % CHUNK;
       
  1023         int midLen = nargs - rightLen;
       
  1024         if (rightLen == 0) {
       
  1025             midLen = nargs - (rightLen = CHUNK);
       
  1026             if (FILL_ARRAY_TO_RIGHT[midLen] == null) {
       
  1027                 // build some precursors from left to right
       
  1028                 for (int j = LEFT_ARGS % CHUNK; j < midLen; j += CHUNK)
       
  1029                     if (j > LEFT_ARGS)  fillToRight(j);
       
  1030             }
       
  1031         }
       
  1032         if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS);
       
  1033         assert(rightLen > 0);
       
  1034         MethodHandle midFill = fillToRight(midLen);  // recursive fill
       
  1035         MethodHandle rightFill = FILL_ARRAYS[rightLen].bindTo(midLen);  // [midLen..nargs-1]
       
  1036         assert(midFill.type().parameterCount()   == 1 + midLen - LEFT_ARGS);
       
  1037         assert(rightFill.type().parameterCount() == 1 + rightLen);
       
  1038 
       
  1039         // Combine the two fills:
       
  1040         //   right(mid(a, x10..x19), x20..x23)
       
  1041         // The final product will look like this:
       
  1042         //   right(mid(newArrayLeft(24, x0..x9), x10..x19), x20..x23)
       
  1043         if (midLen == LEFT_ARGS)
       
  1044             return rightFill;
       
  1045         else
       
  1046             return MethodHandles.collectArguments(rightFill, 0, midFill);
       
  1047     }
       
  1048 
       
  1049     // Type-polymorphic version of varargs maker.
       
  1050     private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS
       
  1051         = new ClassValue<MethodHandle[]>() {
       
  1052             @Override
       
  1053             protected MethodHandle[] computeValue(Class<?> type) {
       
  1054                 return new MethodHandle[256];
       
  1055             }
       
  1056     };
       
  1057 
       
  1058     static final int MAX_JVM_ARITY = 255;  // limit imposed by the JVM
       
  1059 
       
  1060     /** Return a method handle that takes the indicated number of
       
  1061      *  typed arguments and returns an array of them.
       
  1062      *  The type argument is the array type.
       
  1063      */
       
  1064     public static MethodHandle varargsArray(Class<?> arrayType, int nargs) {
       
  1065         Class<?> elemType = arrayType.getComponentType();
       
  1066         if (elemType == null)  throw new IllegalArgumentException("not an array: "+arrayType);
       
  1067         // FIXME: Need more special casing and caching here.
       
  1068         if (nargs >= MAX_JVM_ARITY/2 - 1) {
       
  1069             int slots = nargs;
       
  1070             final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1;  // 1 for receiver MH
       
  1071             if (arrayType == double[].class || arrayType == long[].class)
       
  1072                 slots *= 2;
       
  1073             if (slots > MAX_ARRAY_SLOTS)
       
  1074                 throw new IllegalArgumentException("too many arguments: "+arrayType.getSimpleName()+", length "+nargs);
       
  1075         }
       
  1076         if (elemType == Object.class)
       
  1077             return varargsArray(nargs);
       
  1078         // other cases:  primitive arrays, subtypes of Object[]
       
  1079         MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);
       
  1080         MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
       
  1081         if (mh != null)  return mh;
       
  1082         if (elemType.isPrimitive()) {
       
  1083             MethodHandle builder = FILL_NEW_ARRAY;
       
  1084             MethodHandle producer = buildArrayProducer(arrayType);
       
  1085             mh = buildVarargsArray(builder, producer, nargs);
       
  1086         } else {
       
  1087             @SuppressWarnings("unchecked")
       
  1088             Class<? extends Object[]> objArrayType = (Class<? extends Object[]>) arrayType;
       
  1089             Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
       
  1090             MethodHandle builder = FILL_NEW_TYPED_ARRAY.bindTo(example);
       
  1091             MethodHandle producer = ARRAY_IDENTITY;
       
  1092             mh = buildVarargsArray(builder, producer, nargs);
       
  1093         }
       
  1094         mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
       
  1095         assert(assertCorrectArity(mh, nargs));
       
  1096         if (nargs < cache.length)
       
  1097             cache[nargs] = mh;
       
  1098         return mh;
       
  1099     }
       
  1100 
       
  1101     private static MethodHandle buildArrayProducer(Class<?> arrayType) {
       
  1102         Class<?> elemType = arrayType.getComponentType();
       
  1103         if (elemType.isPrimitive())
       
  1104             return LazyStatics.COPY_AS_PRIMITIVE_ARRAY.bindTo(Wrapper.forPrimitiveType(elemType));
       
  1105         else
       
  1106             return LazyStatics.COPY_AS_REFERENCE_ARRAY.bindTo(arrayType);
       
  1107     }
       
  1108 
       
  1109     // List version of varargs maker.
       
  1110 
       
  1111     private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);
       
  1112     private static List<Object> makeList(Object... args) { return Arrays.asList(args); }
       
  1113     private static List<Object> list() { return NO_ARGS_LIST; }
       
  1114     private static List<Object> list(Object a0)
       
  1115                 { return makeList(a0); }
       
  1116     private static List<Object> list(Object a0, Object a1)
       
  1117                 { return makeList(a0, a1); }
       
  1118     private static List<Object> list(Object a0, Object a1, Object a2)
       
  1119                 { return makeList(a0, a1, a2); }
       
  1120     private static List<Object> list(Object a0, Object a1, Object a2, Object a3)
       
  1121                 { return makeList(a0, a1, a2, a3); }
       
  1122     private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
       
  1123                                      Object a4)
       
  1124                 { return makeList(a0, a1, a2, a3, a4); }
       
  1125     private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
       
  1126                                      Object a4, Object a5)
       
  1127                 { return makeList(a0, a1, a2, a3, a4, a5); }
       
  1128     private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
       
  1129                                      Object a4, Object a5, Object a6)
       
  1130                 { return makeList(a0, a1, a2, a3, a4, a5, a6); }
       
  1131     private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
       
  1132                                      Object a4, Object a5, Object a6, Object a7)
       
  1133                 { return makeList(a0, a1, a2, a3, a4, a5, a6, a7); }
       
  1134     private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
       
  1135                                      Object a4, Object a5, Object a6, Object a7,
       
  1136                                      Object a8)
       
  1137                 { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
       
  1138     private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
       
  1139                                      Object a4, Object a5, Object a6, Object a7,
       
  1140                                      Object a8, Object a9)
       
  1141                 { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
       
  1142     private static MethodHandle[] makeLists() {
       
  1143         ArrayList<MethodHandle> mhs = new ArrayList<>();
       
  1144         for (;;) {
       
  1145             MethodHandle mh = findCollector("list", mhs.size(), List.class);
       
  1146             if (mh == null)  break;
       
  1147             mhs.add(mh);
       
  1148         }
       
  1149         assert(mhs.size() == 11);  // current number of methods
       
  1150         return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
       
  1151     }
       
  1152     private static final MethodHandle[] LISTS = makeLists();
       
  1153 
       
  1154     /** Return a method handle that takes the indicated number of Object
       
  1155      *  arguments and returns a List.
       
  1156      */
       
  1157     public static MethodHandle varargsList(int nargs) {
       
  1158         MethodHandle mh = LISTS[nargs];
       
  1159         if (mh != null)  return mh;
       
  1160         mh = findCollector("list", nargs, List.class);
       
  1161         if (mh != null)  return LISTS[nargs] = mh;
       
  1162         return LISTS[nargs] = buildVarargsList(nargs);
       
  1163     }
       
  1164     private static MethodHandle buildVarargsList(int nargs) {
       
  1165         return MethodHandles.filterReturnValue(varargsArray(nargs), LazyStatics.MAKE_LIST);
       
  1166     }
       
  1167 
       
  1168     // handy shared exception makers (they simplify the common case code)
   764     // handy shared exception makers (they simplify the common case code)
  1169     private static InternalError newInternalError(String message, Throwable cause) {
   765     private static InternalError newInternalError(String message, Throwable cause) {
  1170         return new InternalError(message, cause);
   766         return new InternalError(message, cause);
  1171     }
   767     }
  1172     private static InternalError newInternalError(Throwable cause) {
   768     private static InternalError newInternalError(Throwable cause) {