517 if (len == n) return;
518 }
519 // fall through to error:
520 throw newIllegalArgumentException("array is not of length "+n);
521 }
522
523 /**
524 * Pre-initialized NamedFunctions for bootstrapping purposes.
525 * Factored in an inner class to delay initialization until first usage.
526 */
527 private static class Lazy {
528 private static final Class<?> MHI = MethodHandleImpl.class;
529
530 static final NamedFunction NF_checkSpreadArgument;
531 static final NamedFunction NF_guardWithCatch;
532 static final NamedFunction NF_selectAlternative;
533 static final NamedFunction NF_throwException;
534
535 static final MethodHandle MH_castReference;
536 static final MethodHandle MH_copyAsPrimitiveArray;
537 static final MethodHandle MH_copyAsReferenceArray;
538 static final MethodHandle MH_fillNewTypedArray;
539 static final MethodHandle MH_fillNewArray;
540 static final MethodHandle MH_arrayIdentity;
541
542 static {
543 try {
544 NF_checkSpreadArgument = new NamedFunction(MHI.getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
545 NF_guardWithCatch = new NamedFunction(MHI.getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
546 MethodHandle.class, Object[].class));
547 NF_selectAlternative = new NamedFunction(MHI.getDeclaredMethod("selectAlternative", boolean.class, MethodHandle.class,
548 MethodHandle.class));
549 NF_throwException = new NamedFunction(MHI.getDeclaredMethod("throwException", Throwable.class));
550
551 NF_checkSpreadArgument.resolve();
552 NF_guardWithCatch.resolve();
553 NF_selectAlternative.resolve();
554 NF_throwException.resolve();
555
556 MH_castReference = IMPL_LOOKUP.findStatic(MHI, "castReference",
557 MethodType.methodType(Object.class, Class.class, Object.class));
558 MH_copyAsPrimitiveArray = IMPL_LOOKUP.findStatic(MHI, "copyAsPrimitiveArray",
559 MethodType.methodType(Object.class, Wrapper.class, Object[].class));
560 MH_copyAsReferenceArray = IMPL_LOOKUP.findStatic(MHI, "copyAsReferenceArray",
561 MethodType.methodType(Object[].class, Class.class, Object[].class));
562 MH_arrayIdentity = IMPL_LOOKUP.findStatic(MHI, "identity",
563 MethodType.methodType(Object[].class, Object[].class));
564 MH_fillNewArray = IMPL_LOOKUP.findStatic(MHI, "fillNewArray",
565 MethodType.methodType(Object[].class, Integer.class, Object[].class));
566 MH_fillNewTypedArray = IMPL_LOOKUP.findStatic(MHI, "fillNewTypedArray",
567 MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
568 } catch (ReflectiveOperationException ex) {
569 throw newInternalError(ex);
570 }
571 }
572 }
573
574 /** Factory method: Collect or filter selected argument(s). */
575 static MethodHandle makeCollectArguments(MethodHandle target,
576 MethodHandle collector, int collectArgPos, boolean retainOriginalArgs) {
577 MethodType targetType = target.type(); // (a..., c, [b...])=>r
578 MethodType collectorType = collector.type(); // (b...)=>c
579 int collectArgCount = collectorType.parameterCount();
580 Class<?> collectValType = collectorType.returnType();
581 int collectValCount = (collectValType == void.class ? 0 : 1);
741 MethodHandle catcher) {
742 MethodType type = target.type();
743 LambdaForm form = makeGuardWithCatchForm(type.basicType());
744
745 // Prepare auxiliary method handles used during LambdaForm interpreation.
746 // Box arguments and wrap them into Object[]: ValueConversions.array().
747 MethodType varargsType = type.changeReturnType(Object[].class);
748 MethodHandle collectArgs = varargsArray(type.parameterCount()).asType(varargsType);
749 // Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore().
750 MethodHandle unboxResult;
751 if (type.returnType().isPrimitive()) {
752 unboxResult = ValueConversions.unbox(type.returnType());
753 } else {
754 unboxResult = ValueConversions.identity();
755 }
756
757 BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
758 BoundMethodHandle mh;
759 try {
760 mh = (BoundMethodHandle)
761 data.constructor[0].invokeBasic(type, form, (Object) target, (Object) exType, (Object) catcher,
762 (Object) collectArgs, (Object) unboxResult);
763 } catch (Throwable ex) {
764 throw uncaughtException(ex);
765 }
766 assert(mh.type() == type);
767 return mh;
768 }
769
770 /**
771 * Intrinsified during LambdaForm compilation
772 * (see {@link InvokerBytecodeGenerator#emitGuardWithCatch emitGuardWithCatch}).
773 */
774 @LambdaForm.Hidden
775 static Object guardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher,
776 Object... av) throws Throwable {
777 // Use asFixedArity() to avoid unnecessary boxing of last argument for VarargsCollector case.
778 try {
779 return target.asFixedArity().invokeWithArguments(av);
780 } catch (Throwable t) {
781 if (!exType.isInstance(t)) throw t;
1078 ArrayList<MethodHandle> mhs = new ArrayList<>();
1079 for (;;) {
1080 MethodHandle mh = findCollector("array", mhs.size(), Object[].class);
1081 if (mh == null) break;
1082 mhs.add(mh);
1083 }
1084 assert(mhs.size() == 11); // current number of methods
1085 return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
1086 }
1087 private static final MethodHandle[] ARRAYS = makeArrays();
1088
1089 // filling versions of the above:
1090 // using Integer len instead of int len and no varargs to avoid bootstrapping problems
1091 private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
1092 Object[] a = new Object[len];
1093 fillWithArguments(a, 0, args);
1094 return a;
1095 }
1096 private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
1097 Object[] a = Arrays.copyOf(example, len);
1098 fillWithArguments(a, 0, args);
1099 return a;
1100 }
1101 private static void fillWithArguments(Object[] a, int pos, Object... args) {
1102 System.arraycopy(args, 0, a, pos, args.length);
1103 }
1104 // using Integer pos instead of int pos to avoid bootstrapping problems
1105 private static Object[] fillArray(Integer pos, Object[] a, Object a0)
1106 { fillWithArguments(a, pos, a0); return a; }
1107 private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1)
1108 { fillWithArguments(a, pos, a0, a1); return a; }
1109 private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2)
1110 { fillWithArguments(a, pos, a0, a1, a2); return a; }
1111 private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3)
1112 { fillWithArguments(a, pos, a0, a1, a2, a3); return a; }
1113 private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1114 Object a4)
1115 { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
1116 private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1117 Object a4, Object a5)
1126 Object a4, Object a5, Object a6, Object a7,
1127 Object a8)
1128 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
1129 private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1130 Object a4, Object a5, Object a6, Object a7,
1131 Object a8, Object a9)
1132 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
1133 private static MethodHandle[] makeFillArrays() {
1134 ArrayList<MethodHandle> mhs = new ArrayList<>();
1135 mhs.add(null); // there is no empty fill; at least a0 is required
1136 for (;;) {
1137 MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
1138 if (mh == null) break;
1139 mhs.add(mh);
1140 }
1141 assert(mhs.size() == 11); // current number of methods
1142 return mhs.toArray(new MethodHandle[0]);
1143 }
1144 private static final MethodHandle[] FILL_ARRAYS = makeFillArrays();
1145
1146 private static Object[] copyAsReferenceArray(Class<? extends Object[]> arrayType, Object... a) {
1147 return Arrays.copyOf(a, a.length, arrayType);
1148 }
1149 private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
1150 Object a = w.makeArray(boxes.length);
1151 w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);
1152 return a;
1153 }
1154
1155 /** Return a method handle that takes the indicated number of Object
1156 * arguments and returns an Object array of them, as if for varargs.
1157 */
1158 static MethodHandle varargsArray(int nargs) {
1159 MethodHandle mh = ARRAYS[nargs];
1160 if (mh != null) return mh;
1161 mh = findCollector("array", nargs, Object[].class);
1162 if (mh != null) return ARRAYS[nargs] = mh;
1163 mh = buildVarargsArray(Lazy.MH_fillNewArray, Lazy.MH_arrayIdentity, nargs);
1164 assert(assertCorrectArity(mh, nargs));
1165 return ARRAYS[nargs] = mh;
1166 }
1167
1168 private static boolean assertCorrectArity(MethodHandle mh, int arity) {
1248 = new ClassValue<MethodHandle[]>() {
1249 @Override
1250 protected MethodHandle[] computeValue(Class<?> type) {
1251 return new MethodHandle[256];
1252 }
1253 };
1254
1255 static final int MAX_JVM_ARITY = 255; // limit imposed by the JVM
1256
1257 /** Return a method handle that takes the indicated number of
1258 * typed arguments and returns an array of them.
1259 * The type argument is the array type.
1260 */
1261 static MethodHandle varargsArray(Class<?> arrayType, int nargs) {
1262 Class<?> elemType = arrayType.getComponentType();
1263 if (elemType == null) throw new IllegalArgumentException("not an array: "+arrayType);
1264 // FIXME: Need more special casing and caching here.
1265 if (nargs >= MAX_JVM_ARITY/2 - 1) {
1266 int slots = nargs;
1267 final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1; // 1 for receiver MH
1268 if (arrayType == double[].class || arrayType == long[].class)
1269 slots *= 2;
1270 if (slots > MAX_ARRAY_SLOTS)
1271 throw new IllegalArgumentException("too many arguments: "+arrayType.getSimpleName()+", length "+nargs);
1272 }
1273 if (elemType == Object.class)
1274 return varargsArray(nargs);
1275 // other cases: primitive arrays, subtypes of Object[]
1276 MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);
1277 MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
1278 if (mh != null) return mh;
1279 if (elemType.isPrimitive()) {
1280 MethodHandle builder = Lazy.MH_fillNewArray;
1281 MethodHandle producer = buildArrayProducer(arrayType);
1282 mh = buildVarargsArray(builder, producer, nargs);
1283 } else {
1284 @SuppressWarnings("unchecked")
1285 Class<? extends Object[]> objArrayType = (Class<? extends Object[]>) arrayType;
1286 Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
1287 MethodHandle builder = Lazy.MH_fillNewTypedArray.bindTo(example);
1288 MethodHandle producer = Lazy.MH_arrayIdentity;
1289 mh = buildVarargsArray(builder, producer, nargs);
1290 }
1291 mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
1292 assert(assertCorrectArity(mh, nargs));
1293 if (nargs < cache.length)
1294 cache[nargs] = mh;
1295 return mh;
1296 }
1297
1298 private static MethodHandle buildArrayProducer(Class<?> arrayType) {
1299 Class<?> elemType = arrayType.getComponentType();
1300 if (elemType.isPrimitive())
1301 return Lazy.MH_copyAsPrimitiveArray.bindTo(Wrapper.forPrimitiveType(elemType));
1302 else
1303 return Lazy.MH_copyAsReferenceArray.bindTo(arrayType);
1304 }
1305 }
|
517 if (len == n) return;
518 }
519 // fall through to error:
520 throw newIllegalArgumentException("array is not of length "+n);
521 }
522
523 /**
524 * Pre-initialized NamedFunctions for bootstrapping purposes.
525 * Factored in an inner class to delay initialization until first usage.
526 */
527 private static class Lazy {
528 private static final Class<?> MHI = MethodHandleImpl.class;
529
530 static final NamedFunction NF_checkSpreadArgument;
531 static final NamedFunction NF_guardWithCatch;
532 static final NamedFunction NF_selectAlternative;
533 static final NamedFunction NF_throwException;
534
535 static final MethodHandle MH_castReference;
536 static final MethodHandle MH_copyAsPrimitiveArray;
537 static final MethodHandle MH_fillNewTypedArray;
538 static final MethodHandle MH_fillNewArray;
539 static final MethodHandle MH_arrayIdentity;
540
541 static {
542 try {
543 NF_checkSpreadArgument = new NamedFunction(MHI.getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
544 NF_guardWithCatch = new NamedFunction(MHI.getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
545 MethodHandle.class, Object[].class));
546 NF_selectAlternative = new NamedFunction(MHI.getDeclaredMethod("selectAlternative", boolean.class, MethodHandle.class,
547 MethodHandle.class));
548 NF_throwException = new NamedFunction(MHI.getDeclaredMethod("throwException", Throwable.class));
549
550 NF_checkSpreadArgument.resolve();
551 NF_guardWithCatch.resolve();
552 NF_selectAlternative.resolve();
553 NF_throwException.resolve();
554
555 MH_castReference = IMPL_LOOKUP.findStatic(MHI, "castReference",
556 MethodType.methodType(Object.class, Class.class, Object.class));
557 MH_copyAsPrimitiveArray = IMPL_LOOKUP.findStatic(MHI, "copyAsPrimitiveArray",
558 MethodType.methodType(Object.class, Wrapper.class, Object[].class));
559 MH_arrayIdentity = IMPL_LOOKUP.findStatic(MHI, "identity",
560 MethodType.methodType(Object[].class, Object[].class));
561 MH_fillNewArray = IMPL_LOOKUP.findStatic(MHI, "fillNewArray",
562 MethodType.methodType(Object[].class, Integer.class, Object[].class));
563 MH_fillNewTypedArray = IMPL_LOOKUP.findStatic(MHI, "fillNewTypedArray",
564 MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
565 } catch (ReflectiveOperationException ex) {
566 throw newInternalError(ex);
567 }
568 }
569 }
570
571 /** Factory method: Collect or filter selected argument(s). */
572 static MethodHandle makeCollectArguments(MethodHandle target,
573 MethodHandle collector, int collectArgPos, boolean retainOriginalArgs) {
574 MethodType targetType = target.type(); // (a..., c, [b...])=>r
575 MethodType collectorType = collector.type(); // (b...)=>c
576 int collectArgCount = collectorType.parameterCount();
577 Class<?> collectValType = collectorType.returnType();
578 int collectValCount = (collectValType == void.class ? 0 : 1);
738 MethodHandle catcher) {
739 MethodType type = target.type();
740 LambdaForm form = makeGuardWithCatchForm(type.basicType());
741
742 // Prepare auxiliary method handles used during LambdaForm interpreation.
743 // Box arguments and wrap them into Object[]: ValueConversions.array().
744 MethodType varargsType = type.changeReturnType(Object[].class);
745 MethodHandle collectArgs = varargsArray(type.parameterCount()).asType(varargsType);
746 // Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore().
747 MethodHandle unboxResult;
748 if (type.returnType().isPrimitive()) {
749 unboxResult = ValueConversions.unbox(type.returnType());
750 } else {
751 unboxResult = ValueConversions.identity();
752 }
753
754 BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
755 BoundMethodHandle mh;
756 try {
757 mh = (BoundMethodHandle)
758 data.constructor().invokeBasic(type, form, (Object) target, (Object) exType, (Object) catcher,
759 (Object) collectArgs, (Object) unboxResult);
760 } catch (Throwable ex) {
761 throw uncaughtException(ex);
762 }
763 assert(mh.type() == type);
764 return mh;
765 }
766
767 /**
768 * Intrinsified during LambdaForm compilation
769 * (see {@link InvokerBytecodeGenerator#emitGuardWithCatch emitGuardWithCatch}).
770 */
771 @LambdaForm.Hidden
772 static Object guardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher,
773 Object... av) throws Throwable {
774 // Use asFixedArity() to avoid unnecessary boxing of last argument for VarargsCollector case.
775 try {
776 return target.asFixedArity().invokeWithArguments(av);
777 } catch (Throwable t) {
778 if (!exType.isInstance(t)) throw t;
1075 ArrayList<MethodHandle> mhs = new ArrayList<>();
1076 for (;;) {
1077 MethodHandle mh = findCollector("array", mhs.size(), Object[].class);
1078 if (mh == null) break;
1079 mhs.add(mh);
1080 }
1081 assert(mhs.size() == 11); // current number of methods
1082 return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
1083 }
1084 private static final MethodHandle[] ARRAYS = makeArrays();
1085
1086 // filling versions of the above:
1087 // using Integer len instead of int len and no varargs to avoid bootstrapping problems
1088 private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
1089 Object[] a = new Object[len];
1090 fillWithArguments(a, 0, args);
1091 return a;
1092 }
1093 private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
1094 Object[] a = Arrays.copyOf(example, len);
1095 assert(a.getClass() != Object[].class);
1096 fillWithArguments(a, 0, args);
1097 return a;
1098 }
1099 private static void fillWithArguments(Object[] a, int pos, Object... args) {
1100 System.arraycopy(args, 0, a, pos, args.length);
1101 }
1102 // using Integer pos instead of int pos to avoid bootstrapping problems
1103 private static Object[] fillArray(Integer pos, Object[] a, Object a0)
1104 { fillWithArguments(a, pos, a0); return a; }
1105 private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1)
1106 { fillWithArguments(a, pos, a0, a1); return a; }
1107 private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2)
1108 { fillWithArguments(a, pos, a0, a1, a2); return a; }
1109 private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3)
1110 { fillWithArguments(a, pos, a0, a1, a2, a3); return a; }
1111 private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1112 Object a4)
1113 { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
1114 private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1115 Object a4, Object a5)
1124 Object a4, Object a5, Object a6, Object a7,
1125 Object a8)
1126 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
1127 private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1128 Object a4, Object a5, Object a6, Object a7,
1129 Object a8, Object a9)
1130 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
1131 private static MethodHandle[] makeFillArrays() {
1132 ArrayList<MethodHandle> mhs = new ArrayList<>();
1133 mhs.add(null); // there is no empty fill; at least a0 is required
1134 for (;;) {
1135 MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
1136 if (mh == null) break;
1137 mhs.add(mh);
1138 }
1139 assert(mhs.size() == 11); // current number of methods
1140 return mhs.toArray(new MethodHandle[0]);
1141 }
1142 private static final MethodHandle[] FILL_ARRAYS = makeFillArrays();
1143
1144 private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
1145 Object a = w.makeArray(boxes.length);
1146 w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);
1147 return a;
1148 }
1149
1150 /** Return a method handle that takes the indicated number of Object
1151 * arguments and returns an Object array of them, as if for varargs.
1152 */
1153 static MethodHandle varargsArray(int nargs) {
1154 MethodHandle mh = ARRAYS[nargs];
1155 if (mh != null) return mh;
1156 mh = findCollector("array", nargs, Object[].class);
1157 if (mh != null) return ARRAYS[nargs] = mh;
1158 mh = buildVarargsArray(Lazy.MH_fillNewArray, Lazy.MH_arrayIdentity, nargs);
1159 assert(assertCorrectArity(mh, nargs));
1160 return ARRAYS[nargs] = mh;
1161 }
1162
1163 private static boolean assertCorrectArity(MethodHandle mh, int arity) {
1243 = new ClassValue<MethodHandle[]>() {
1244 @Override
1245 protected MethodHandle[] computeValue(Class<?> type) {
1246 return new MethodHandle[256];
1247 }
1248 };
1249
1250 static final int MAX_JVM_ARITY = 255; // limit imposed by the JVM
1251
1252 /** Return a method handle that takes the indicated number of
1253 * typed arguments and returns an array of them.
1254 * The type argument is the array type.
1255 */
1256 static MethodHandle varargsArray(Class<?> arrayType, int nargs) {
1257 Class<?> elemType = arrayType.getComponentType();
1258 if (elemType == null) throw new IllegalArgumentException("not an array: "+arrayType);
1259 // FIXME: Need more special casing and caching here.
1260 if (nargs >= MAX_JVM_ARITY/2 - 1) {
1261 int slots = nargs;
1262 final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1; // 1 for receiver MH
1263 if (slots <= MAX_ARRAY_SLOTS && elemType.isPrimitive())
1264 slots *= Wrapper.forPrimitiveType(elemType).stackSlots();
1265 if (slots > MAX_ARRAY_SLOTS)
1266 throw new IllegalArgumentException("too many arguments: "+arrayType.getSimpleName()+", length "+nargs);
1267 }
1268 if (elemType == Object.class)
1269 return varargsArray(nargs);
1270 // other cases: primitive arrays, subtypes of Object[]
1271 MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);
1272 MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
1273 if (mh != null) return mh;
1274 if (nargs == 0) {
1275 Object example = java.lang.reflect.Array.newInstance(arrayType.getComponentType(), 0);
1276 mh = MethodHandles.constant(arrayType, example);
1277 } else if (elemType.isPrimitive()) {
1278 MethodHandle builder = Lazy.MH_fillNewArray;
1279 MethodHandle producer = buildArrayProducer(arrayType);
1280 mh = buildVarargsArray(builder, producer, nargs);
1281 } else {
1282 Class<? extends Object[]> objArrayType = arrayType.asSubclass(Object[].class);
1283 Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
1284 MethodHandle builder = Lazy.MH_fillNewTypedArray.bindTo(example);
1285 MethodHandle producer = Lazy.MH_arrayIdentity; // must be weakly typed
1286 mh = buildVarargsArray(builder, producer, nargs);
1287 }
1288 mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
1289 assert(assertCorrectArity(mh, nargs));
1290 if (nargs < cache.length)
1291 cache[nargs] = mh;
1292 return mh;
1293 }
1294
1295 private static MethodHandle buildArrayProducer(Class<?> arrayType) {
1296 Class<?> elemType = arrayType.getComponentType();
1297 assert(elemType.isPrimitive());
1298 return Lazy.MH_copyAsPrimitiveArray.bindTo(Wrapper.forPrimitiveType(elemType));
1299 }
1300 }
|