< prev index next >

src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java

Print this page




1665 
1666     /** Return a method handle that takes the indicated number of
1667      *  typed arguments and returns an array of them.
1668      *  The type argument is the array type.
1669      */
1670     static MethodHandle varargsArray(Class<?> arrayType, int nargs) {
1671         Class<?> elemType = arrayType.getComponentType();
1672         if (elemType == null)  throw new IllegalArgumentException("not an array: "+arrayType);
1673         // FIXME: Need more special casing and caching here.
1674         if (nargs >= MAX_JVM_ARITY/2 - 1) {
1675             int slots = nargs;
1676             final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1;  // 1 for receiver MH
1677             if (slots <= MAX_ARRAY_SLOTS && elemType.isPrimitive())
1678                 slots *= Wrapper.forPrimitiveType(elemType).stackSlots();
1679             if (slots > MAX_ARRAY_SLOTS)
1680                 throw new IllegalArgumentException("too many arguments: "+arrayType.getSimpleName()+", length "+nargs);
1681         }
1682         if (elemType == Object.class)
1683             return varargsArray(nargs);
1684         // other cases:  primitive arrays, subtypes of Object[]
1685         MethodHandle cache[] = Makers.TYPED_COLLECTORS.get(elemType);
1686         MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
1687         if (mh != null)  return mh;
1688         if (nargs == 0) {
1689             Object example = java.lang.reflect.Array.newInstance(arrayType.getComponentType(), 0);
1690             mh = MethodHandles.constant(arrayType, example);
1691         } else if (elemType.isPrimitive()) {
1692             MethodHandle builder = getConstantHandle(MH_fillNewArray);
1693             MethodHandle producer = buildArrayProducer(arrayType);
1694             mh = buildVarargsArray(builder, producer, nargs);
1695         } else {
1696             Class<? extends Object[]> objArrayType = arrayType.asSubclass(Object[].class);
1697             Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
1698             MethodHandle builder = getConstantHandle(MH_fillNewTypedArray).bindTo(example);
1699             MethodHandle producer = getConstantHandle(MH_arrayIdentity); // must be weakly typed
1700             mh = buildVarargsArray(builder, producer, nargs);
1701         }
1702         mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
1703         mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
1704         assert(assertCorrectArity(mh, nargs));
1705         if (nargs < cache.length)




1665 
1666     /** Return a method handle that takes the indicated number of
1667      *  typed arguments and returns an array of them.
1668      *  The type argument is the array type.
1669      */
1670     static MethodHandle varargsArray(Class<?> arrayType, int nargs) {
1671         Class<?> elemType = arrayType.getComponentType();
1672         if (elemType == null)  throw new IllegalArgumentException("not an array: "+arrayType);
1673         // FIXME: Need more special casing and caching here.
1674         if (nargs >= MAX_JVM_ARITY/2 - 1) {
1675             int slots = nargs;
1676             final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1;  // 1 for receiver MH
1677             if (slots <= MAX_ARRAY_SLOTS && elemType.isPrimitive())
1678                 slots *= Wrapper.forPrimitiveType(elemType).stackSlots();
1679             if (slots > MAX_ARRAY_SLOTS)
1680                 throw new IllegalArgumentException("too many arguments: "+arrayType.getSimpleName()+", length "+nargs);
1681         }
1682         if (elemType == Object.class)
1683             return varargsArray(nargs);
1684         // other cases:  primitive arrays, subtypes of Object[]
1685         MethodHandle[] cache = Makers.TYPED_COLLECTORS.get(elemType);
1686         MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
1687         if (mh != null)  return mh;
1688         if (nargs == 0) {
1689             Object example = java.lang.reflect.Array.newInstance(arrayType.getComponentType(), 0);
1690             mh = MethodHandles.constant(arrayType, example);
1691         } else if (elemType.isPrimitive()) {
1692             MethodHandle builder = getConstantHandle(MH_fillNewArray);
1693             MethodHandle producer = buildArrayProducer(arrayType);
1694             mh = buildVarargsArray(builder, producer, nargs);
1695         } else {
1696             Class<? extends Object[]> objArrayType = arrayType.asSubclass(Object[].class);
1697             Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
1698             MethodHandle builder = getConstantHandle(MH_fillNewTypedArray).bindTo(example);
1699             MethodHandle producer = getConstantHandle(MH_arrayIdentity); // must be weakly typed
1700             mh = buildVarargsArray(builder, producer, nargs);
1701         }
1702         mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
1703         mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
1704         assert(assertCorrectArity(mh, nargs));
1705         if (nargs < cache.length)


< prev index next >