1237 lines · 44.9 KB · Java
RawDownload
                                  Object a4, Object a5, Object a6, Object a7)                { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }    private static Object[] array(Object a0, Object a1, Object a2, Object a3,                                  Object a4, Object a5, Object a6, Object a7,                                  Object a8)                { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }    private static Object[] array(Object a0, Object a1, Object a2, Object a3,                                  Object a4, Object a5, Object a6, Object a7,                                  Object a8, Object a9)                { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }    private static MethodHandle[] makeArrays() {        ArrayList<MethodHandle> mhs = new ArrayList<>();        for (;;) {            MethodHandle mh = findCollector("array", mhs.size(), Object[].class);            if (mh == null)  break;            mhs.add(mh);        }        assert(mhs.size() == 11);  // current number of methods        return mhs.toArray(new MethodHandle[MAX_ARITY+1]);    }    private static final MethodHandle[] ARRAYS = makeArrays();     // mh-fill versions of the above:    private static Object[] newArray(int len) { return new Object[len]; }    private static void fillWithArguments(Object[] a, int pos, Object... args) {        System.arraycopy(args, 0, a, pos, args.length);    }    // using Integer pos instead of int pos to avoid bootstrapping problems    private static Object[] fillArray(Object[] a, Integer pos, Object a0)                { fillWithArguments(a, pos, a0); return a; }    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1)                { fillWithArguments(a, pos, a0, a1); return a; }    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2)                { fillWithArguments(a, pos, a0, a1, a2); return a; }    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3)                { fillWithArguments(a, pos, a0, a1, a2, a3); return a; }    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,                                  Object a4)                { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,                                  Object a4, Object a5)                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,                                  Object a4, Object a5, Object a6)                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,                                  Object a4, Object a5, Object a6, Object a7)                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,                                  Object a4, Object a5, Object a6, Object a7,                                  Object a8)                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,                                  Object a4, Object a5, Object a6, Object a7,                                  Object a8, Object a9)                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }    private static MethodHandle[] makeFillArrays() {        ArrayList<MethodHandle> mhs = new ArrayList<>();        mhs.add(null);  // there is no empty fill; at least a0 is required        for (;;) {            MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Object[].class, Integer.class);            if (mh == null)  break;            mhs.add(mh);        }        assert(mhs.size() == 11);  // current number of methods        return mhs.toArray(new MethodHandle[0]);    }    private static final MethodHandle[] FILL_ARRAYS = makeFillArrays();     private static Object[] copyAsReferenceArray(Class<? extends Object[]> arrayType, Object... a) {        return Arrays.copyOf(a, a.length, arrayType);    }    private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {        Object a = w.makeArray(boxes.length);        w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);        return a;    }     /** Return a method handle that takes the indicated number of Object     *  arguments and returns an Object array of them, as if for varargs.     */    public static MethodHandle varargsArray(int nargs) {        MethodHandle mh = ARRAYS[nargs];        if (mh != null)  return mh;        mh = findCollector("array", nargs, Object[].class);        if (mh != null)  return ARRAYS[nargs] = mh;        MethodHandle producer = filler(0);  // identity function produces result        return ARRAYS[nargs] = buildVarargsArray(producer, nargs);    }     private static MethodHandle buildVarargsArray(MethodHandle producer, int nargs) {        // Build up the result mh as a sequence of fills like this:        //   producer(fill(fill(fill(newArray(23),0,x1..x10),10,x11..x20),20,x21..x23))        // The various fill(_,10*I,___*[J]) are reusable.        MethodHandle filler = filler(nargs);        MethodHandle mh = producer;        mh = MethodHandles.dropArguments(mh, 1, filler.type().parameterList());        mh = MethodHandles.foldArguments(mh, filler);        mh = MethodHandles.foldArguments(mh, buildNewArray(nargs));        return mh;    }     private static MethodHandle buildNewArray(int nargs) {        return MethodHandles.insertArguments(NEW_ARRAY, 0, (int) nargs);    }     private static final MethodHandle[] FILLERS = new MethodHandle[MAX_ARITY+1];    // filler(N).invoke(a, arg0..arg[N-1]) fills a[0]..a[N-1]    private static MethodHandle filler(int nargs) {        MethodHandle filler = FILLERS[nargs];        if (filler != null)  return filler;        return FILLERS[nargs] = buildFiller(nargs);    }    private static MethodHandle buildFiller(int nargs) {        if (nargs == 0)            return MethodHandles.identity(Object[].class);        final int CHUNK = (FILL_ARRAYS.length - 1);        int rightLen = nargs % CHUNK;        int leftLen = nargs - rightLen;        if (rightLen == 0) {            leftLen = nargs - (rightLen = CHUNK);            if (FILLERS[leftLen] == null) {                // build some precursors from left to right                for (int j = 0; j < leftLen; j += CHUNK)  filler(j);            }        }        MethodHandle leftFill = filler(leftLen);  // recursive fill        MethodHandle rightFill = FILL_ARRAYS[rightLen];        rightFill = MethodHandles.insertArguments(rightFill, 1, (int) leftLen);  // [leftLen..nargs-1]         // Combine the two fills: right(left(newArray(nargs), x1..x20), x21..x23)        MethodHandle mh = filler(0);  // identity function produces result        mh = MethodHandles.dropArguments(mh, 1, rightFill.type().parameterList());        mh = MethodHandles.foldArguments(mh, rightFill);        if (leftLen > 0) {            mh = MethodHandles.dropArguments(mh, 1, leftFill.type().parameterList());            mh = MethodHandles.foldArguments(mh, leftFill);        }        return mh;    }     // Type-polymorphic version of varargs maker.    private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS        = new ClassValue<MethodHandle[]>() {            protected MethodHandle[] computeValue(Class<?> type) {                return new MethodHandle[256];            }    };     /** Return a method handle that takes the indicated number of     *  typed arguments and returns an array of them.     *  The type argument is the array type.     */    public static MethodHandle varargsArray(Class<?> arrayType, int nargs) {        Class<?> elemType = arrayType.getComponentType();        if (elemType == null)  throw new IllegalArgumentException("not an array: "+arrayType);        // FIXME: Need more special casing and caching here.        if (elemType == Object.class)            return varargsArray(nargs);        // other cases:  primitive arrays, subtypes of Object[]        MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);        MethodHandle mh = nargs < cache.length ? cache[nargs] : null;        if (mh != null)  return mh;        MethodHandle producer = buildArrayProducer(arrayType);        mh = buildVarargsArray(producer, nargs);        mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));        cache[nargs] = mh;        return mh;    }     private static MethodHandle buildArrayProducer(Class<?> arrayType) {        Class<?> elemType = arrayType.getComponentType();        if (elemType.isPrimitive())            return LazyStatics.COPY_AS_PRIMITIVE_ARRAY.bindTo(Wrapper.forPrimitiveType(elemType));        else            return LazyStatics.COPY_AS_REFERENCE_ARRAY.bindTo(arrayType);    }     // List version of varargs maker.     private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);    private static List<Object> makeList(Object... args) { return Arrays.asList(args); }    private static List<Object> list() { return NO_ARGS_LIST; }    private static List<Object> list(Object a0)                { return makeList(a0); }    private static List<Object> list(Object a0, Object a1)                { return makeList(a0, a1); }    private static List<Object> list(Object a0, Object a1, Object a2)                { return makeList(a0, a1, a2); }    private static List<Object> list(Object a0, Object a1, Object a2, Object a3)                { return makeList(a0, a1, a2, a3); }    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,                                     Object a4)                { return makeList(a0, a1, a2, a3, a4); }    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,                                     Object a4, Object a5)                { return makeList(a0, a1, a2, a3, a4, a5); }    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,                                     Object a4, Object a5, Object a6)                { return makeList(a0, a1, a2, a3, a4, a5, a6); }    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,                                     Object a4, Object a5, Object a6, Object a7)                { return makeList(a0, a1, a2, a3, a4, a5, a6, a7); }    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,                                     Object a4, Object a5, Object a6, Object a7,                                     Object a8)                { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8); }    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,                                     Object a4, Object a5, Object a6, Object a7,                                     Object a8, Object a9)                { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }    private static MethodHandle[] makeLists() {        ArrayList<MethodHandle> mhs = new ArrayList<>();        for (;;) {            MethodHandle mh = findCollector("list", mhs.size(), List.class);            if (mh == null)  break;            mhs.add(mh);        }        assert(mhs.size() == 11);  // current number of methods        return mhs.toArray(new MethodHandle[MAX_ARITY+1]);    }    private static final MethodHandle[] LISTS = makeLists();     /** Return a method handle that takes the indicated number of Object     *  arguments and returns a List.     */    public static MethodHandle varargsList(int nargs) {        MethodHandle mh = LISTS[nargs];        if (mh != null)  return mh;        mh = findCollector("list", nargs, List.class);        if (mh != null)  return LISTS[nargs] = mh;        return LISTS[nargs] = buildVarargsList(nargs);    }    private static MethodHandle buildVarargsList(int nargs) {        return MethodHandles.filterReturnValue(varargsArray(nargs), LazyStatics.MAKE_LIST);    }}

Lines 1001–1237 of 1237. Previous lines