} static Integer narrowBoxedLong(Long x) { return (int)(long) x; } /// Constant functions static void ignore(Object x) { // no value to return; this is an unbox of null return; } static void empty() { return; } static Object zeroObject() { return null; } static int zeroInteger() { return 0; } static long zeroLong() { return 0; } static float zeroFloat() { return 0; } static double zeroDouble() { return 0; } private static final EnumMap<Wrapper, MethodHandle>[] CONSTANT_FUNCTIONS = newWrapperCaches(2); public static MethodHandle zeroConstantFunction(Wrapper wrap) { EnumMap<Wrapper, MethodHandle> cache = CONSTANT_FUNCTIONS[0]; MethodHandle mh = cache.get(wrap); if (mh != null) { return mh; } // slow path MethodType type = MethodType.methodType(wrap.primitiveType()); switch (wrap) { case VOID: mh = EMPTY; break; case OBJECT: case INT: case LONG: case FLOAT: case DOUBLE: try { mh = IMPL_LOOKUP.findStatic(THIS_CLASS, "zero"+wrap.simpleName(), type); } catch (ReflectiveOperationException ex) { mh = null; } break; } if (mh != null) { cache.put(wrap, mh); return mh; } // use the raw method Wrapper rawWrap = wrap.rawPrimitive(); if (mh == null && rawWrap != wrap) { mh = MethodHandles.explicitCastArguments(zeroConstantFunction(rawWrap), type); } if (mh != null) { cache.put(wrap, mh); return mh; } throw new IllegalArgumentException("cannot find zero constant for " + wrap); } /// Converting references to references. /** * Value-killing function. * @param x an arbitrary reference value * @return a null */ static Object alwaysNull(Object x) { return null; } /** * Value-killing function. * @param x an arbitrary reference value * @return a zero */ static int alwaysZero(Object x) { return 0; } /** * Identity function. * @param x an arbitrary reference value * @return the same value x */ static <T> T identity(T x) { return x; } /** * Identity function on ints. * @param x an arbitrary int value * @return the same value x */ static int identity(int x) { return x; } static byte identity(byte x) { return x; } static short identity(short x) { return x; } static boolean identity(boolean x) { return x; } static char identity(char x) { return x; } /** * Identity function on longs. * @param x an arbitrary long value * @return the same value x */ static long identity(long x) { return x; } static float identity(float x) { return x; } static double identity(double x) { return x; } /** * Identity function, with reference cast. * @param t an arbitrary reference type * @param x an arbitrary reference value * @return the same value x */ static <T,U> T castReference(Class<? extends T> t, U x) { return t.cast(x); } private static final MethodHandle IDENTITY, IDENTITY_I, IDENTITY_J, CAST_REFERENCE, ALWAYS_NULL, ALWAYS_ZERO, ZERO_OBJECT, IGNORE, EMPTY, NEW_ARRAY; static { try { MethodType idType = MethodType.genericMethodType(1); MethodType castType = idType.insertParameterTypes(0, Class.class); MethodType alwaysZeroType = idType.changeReturnType(int.class); MethodType ignoreType = idType.changeReturnType(void.class); MethodType zeroObjectType = MethodType.genericMethodType(0); IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType); IDENTITY_I = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(int.class, int.class)); IDENTITY_J = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(long.class, long.class)); //CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType); CAST_REFERENCE = IMPL_LOOKUP.findStatic(THIS_CLASS, "castReference", castType); ALWAYS_NULL = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysNull", idType); ALWAYS_ZERO = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysZero", alwaysZeroType); ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType); IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType); EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1)); NEW_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "newArray", MethodType.methodType(Object[].class, int.class)); } catch (NoSuchMethodException | IllegalAccessException ex) { Error err = new InternalError("uncaught exception"); err.initCause(ex); throw err; } } // Varargs methods need to be in a separately initialized class, to bootstrapping problems. static class LazyStatics { private static final MethodHandle COPY_AS_REFERENCE_ARRAY, COPY_AS_PRIMITIVE_ARRAY, MAKE_LIST; static { try { //MAKE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeArray", MethodType.methodType(Object[].class, Object[].class)); COPY_AS_REFERENCE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsReferenceArray", MethodType.methodType(Object[].class, Class.class, Object[].class)); COPY_AS_PRIMITIVE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsPrimitiveArray", MethodType.methodType(Object.class, Wrapper.class, Object[].class)); MAKE_LIST = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeList", MethodType.methodType(List.class, Object[].class)); } catch (ReflectiveOperationException ex) { Error err = new InternalError("uncaught exception"); err.initCause(ex); throw err; } } } private static final EnumMap<Wrapper, MethodHandle>[] WRAPPER_CASTS = newWrapperCaches(2); /** Return a method that casts its sole argument (an Object) to the given type * and returns it as the given type (if exact is true), or as plain Object (if erase is true). */ public static MethodHandle cast(Class<?> type) { boolean exact = false; if (type.isPrimitive()) throw new IllegalArgumentException("cannot cast primitive type "+type); MethodHandle mh = null; Wrapper wrap = null; EnumMap<Wrapper, MethodHandle> cache = null; if (Wrapper.isWrapperType(type)) { wrap = Wrapper.forWrapperType(type); cache = WRAPPER_CASTS[exact?1:0]; mh = cache.get(wrap); if (mh != null) return mh; } if (VerifyType.isNullReferenceConversion(Object.class, type)) mh = IDENTITY; else if (VerifyType.isNullType(type)) mh = ALWAYS_NULL; else mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type); if (exact) { MethodType xmt = MethodType.methodType(type, Object.class); mh = MethodHandles.explicitCastArguments(mh, xmt); //mh = AdapterMethodHandle.makeRetypeRaw(IMPL_TOKEN, xmt, mh); } if (cache != null) cache.put(wrap, mh); return mh; } public static MethodHandle identity() { return IDENTITY; } public static MethodHandle identity(Class<?> type) { // This stuff has been moved into MethodHandles: return MethodHandles.identity(type); } public static MethodHandle identity(Wrapper wrap) { EnumMap<Wrapper, MethodHandle> cache = CONSTANT_FUNCTIONS[1]; MethodHandle mh = cache.get(wrap); if (mh != null) { return mh; } // slow path MethodType type = MethodType.methodType(wrap.primitiveType()); if (wrap != Wrapper.VOID) type = type.appendParameterTypes(wrap.primitiveType()); try { mh = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", type); } catch (ReflectiveOperationException ex) { mh = null; } if (mh == null && wrap == Wrapper.VOID) { mh = EMPTY; // #(){} : #()void } if (mh != null) { cache.put(wrap, mh); return mh; } if (mh != null) { cache.put(wrap, mh); return mh; } throw new IllegalArgumentException("cannot find identity for " + wrap); } /// Float/non-float conversions. static float doubleToFloat(double x) { return (float) x; } static double floatToDouble(float x) { return x; } // narrow double to integral type static long doubleToLong(double x) { return (long) x; } static int doubleToInt(double x) { return (int) x; } static short doubleToShort(double x) { return (short) x; } static char doubleToChar(double x) { return (char) x; } static byte doubleToByte(double x) { return (byte) x; } static boolean doubleToBoolean(double x) { return toBoolean((byte) x); } // narrow float to integral type static long floatToLong(float x) { return (long) x; } static int floatToInt(float x) { return (int) x; } static short floatToShort(float x) { return (short) x; } static char floatToChar(float x) { return (char) x; } static byte floatToByte(float x) { return (byte) x; } static boolean floatToBoolean(float x) { return toBoolean((byte) x); } // widen integral type to double static double longToDouble(long x) { return x; } static double intToDouble(int x) { return x; } static double shortToDouble(short x) { return x; } static double charToDouble(char x) { return x; } static double byteToDouble(byte x) { return x; } static double booleanToDouble(boolean x) { return fromBoolean(x); } // widen integral type to float static float longToFloat(long x) { return x; } static float intToFloat(int x) { return x; } static float shortToFloat(short x) { return x; } static float charToFloat(char x) { return x; } static float byteToFloat(byte x) { return x; } static float booleanToFloat(boolean x) { return fromBoolean(x); } static boolean toBoolean(byte x) { // see javadoc for MethodHandles.explicitCastArguments return ((x & 1) != 0); } static byte fromBoolean(boolean x) { // see javadoc for MethodHandles.explicitCastArguments return (x ? (byte)1 : (byte)0); } private static final EnumMap<Wrapper, MethodHandle>[] CONVERT_FLOAT_FUNCTIONS = newWrapperCaches(4); static MethodHandle convertFloatFunction(Wrapper wrap, boolean toFloat, boolean doubleSize) { EnumMap<Wrapper, MethodHandle> cache = CONVERT_FLOAT_FUNCTIONS[(toFloat?1:0)+(doubleSize?2:0)]; MethodHandle mh = cache.get(wrap); if (mh != null) { return mh; } // slow path Wrapper fwrap = (doubleSize ? Wrapper.DOUBLE : Wrapper.FLOAT); Class<?> fix = wrap.primitiveType(); Class<?> flt = (doubleSize ? double.class : float.class); Class<?> src = toFloat ? fix : flt; Class<?> dst = toFloat ? flt : fix; if (src == dst) return identity(wrap); MethodType type = MethodType.methodType(dst, src); switch (wrap) { case VOID: mh = toFloat ? zeroConstantFunction(fwrap) : MethodHandles.dropArguments(EMPTY, 0, flt); break; case OBJECT: mh = toFloat ? unbox(flt) : box(flt); break; default: try { mh = IMPL_LOOKUP.findStatic(THIS_CLASS, src.getSimpleName()+"To"+capitalize(dst.getSimpleName()), type); } catch (ReflectiveOperationException ex) { mh = null; } break; } if (mh != null) { assert(mh.type() == type) : mh; cache.put(wrap, mh); return mh; } throw new IllegalArgumentException("cannot find float conversion constant for " + src.getSimpleName()+" -> "+dst.getSimpleName()); } public static MethodHandle convertFromFloat(Class<?> fixType) { Wrapper wrap = Wrapper.forPrimitiveType(fixType); return convertFloatFunction(wrap, false, false); } public static MethodHandle convertFromDouble(Class<?> fixType) { Wrapper wrap = Wrapper.forPrimitiveType(fixType); return convertFloatFunction(wrap, false, true); } public static MethodHandle convertToFloat(Class<?> fixType) { Wrapper wrap = Wrapper.forPrimitiveType(fixType); return convertFloatFunction(wrap, true, false); } public static MethodHandle convertToDouble(Class<?> fixType) { Wrapper wrap = Wrapper.forPrimitiveType(fixType); return convertFloatFunction(wrap, true, true); } private static String capitalize(String x) { return Character.toUpperCase(x.charAt(0))+x.substring(1); } /// Collection of multiple arguments. public static Object convertArrayElements(Class<?> arrayType, Object array) { Class<?> src = array.getClass().getComponentType(); Class<?> dst = arrayType.getComponentType(); if (src == null || dst == null) throw new IllegalArgumentException("not array type"); Wrapper sw = (src.isPrimitive() ? Wrapper.forPrimitiveType(src) : null); Wrapper dw = (dst.isPrimitive() ? Wrapper.forPrimitiveType(dst) : null); int length; if (sw == null) { Object[] a = (Object[]) array; length = a.length; if (dw == null) return Arrays.copyOf(a, length, arrayType.asSubclass(Object[].class)); Object res = dw.makeArray(length); dw.copyArrayUnboxing(a, 0, res, 0, length); return res; } length = java.lang.reflect.Array.getLength(array); Object[] res; if (dw == null) { res = Arrays.copyOf(NO_ARGS_ARRAY, length, arrayType.asSubclass(Object[].class)); } else { res = new Object[length]; } sw.copyArrayBoxing(array, 0, res, 0, length); if (dw == null) return res; Object a = dw.makeArray(length); dw.copyArrayUnboxing(res, 0, a, 0, length); return a; } private static MethodHandle findCollector(String name, int nargs, Class<?> rtype, Class<?>... ptypes) { MethodType type = MethodType.genericMethodType(nargs) .changeReturnType(rtype) .insertParameterTypes(0, ptypes); try { return IMPL_LOOKUP.findStatic(THIS_CLASS, name, type); } catch (ReflectiveOperationException ex) { return null; } } private static final Object[] NO_ARGS_ARRAY = {}; private static Object[] makeArray(Object... args) { return args; } private static Object[] array() { return NO_ARGS_ARRAY; } private static Object[] array(Object a0) { return makeArray(a0); } private static Object[] array(Object a0, Object a1) { return makeArray(a0, a1); } private static Object[] array(Object a0, Object a1, Object a2) { return makeArray(a0, a1, a2); } private static Object[] array(Object a0, Object a1, Object a2, Object a3) { return makeArray(a0, a1, a2, a3); } private static Object[] array(Object a0, Object a1, Object a2, Object a3, Object a4) { return makeArray(a0, a1, a2, a3, a4); } private static Object[] array(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return makeArray(a0, a1, a2, a3, a4, a5); } private static Object[] array(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { return makeArray(a0, a1, a2, a3, a4, a5, a6); } private static Object[] array(Object a0, Object a1, Object a2, Object a3,Lines 501–1000 of 1237. Previous lines Load more
} static Integer narrowBoxedLong(Long x) { return (int)(long) x; } /// Constant functions static void ignore(Object x) { // no value to return; this is an unbox of null return; } static void empty() { return; } static Object zeroObject() { return null; } static int zeroInteger() { return 0; } static long zeroLong() { return 0; } static float zeroFloat() { return 0; } static double zeroDouble() { return 0; } private static final EnumMap<Wrapper, MethodHandle>[] CONSTANT_FUNCTIONS = newWrapperCaches(2); public static MethodHandle zeroConstantFunction(Wrapper wrap) { EnumMap<Wrapper, MethodHandle> cache = CONSTANT_FUNCTIONS[0]; MethodHandle mh = cache.get(wrap); if (mh != null) { return mh; } // slow path MethodType type = MethodType.methodType(wrap.primitiveType()); switch (wrap) { case VOID: mh = EMPTY; break; case OBJECT: case INT: case LONG: case FLOAT: case DOUBLE: try { mh = IMPL_LOOKUP.findStatic(THIS_CLASS, "zero"+wrap.simpleName(), type); } catch (ReflectiveOperationException ex) { mh = null; } break; } if (mh != null) { cache.put(wrap, mh); return mh; } // use the raw method Wrapper rawWrap = wrap.rawPrimitive(); if (mh == null && rawWrap != wrap) { mh = MethodHandles.explicitCastArguments(zeroConstantFunction(rawWrap), type); } if (mh != null) { cache.put(wrap, mh); return mh; } throw new IllegalArgumentException("cannot find zero constant for " + wrap); } /// Converting references to references. /** * Value-killing function. * @param x an arbitrary reference value * @return a null */ static Object alwaysNull(Object x) { return null; } /** * Value-killing function. * @param x an arbitrary reference value * @return a zero */ static int alwaysZero(Object x) { return 0; } /** * Identity function. * @param x an arbitrary reference value * @return the same value x */ static <T> T identity(T x) { return x; } /** * Identity function on ints. * @param x an arbitrary int value * @return the same value x */ static int identity(int x) { return x; } static byte identity(byte x) { return x; } static short identity(short x) { return x; } static boolean identity(boolean x) { return x; } static char identity(char x) { return x; } /** * Identity function on longs. * @param x an arbitrary long value * @return the same value x */ static long identity(long x) { return x; } static float identity(float x) { return x; } static double identity(double x) { return x; } /** * Identity function, with reference cast. * @param t an arbitrary reference type * @param x an arbitrary reference value * @return the same value x */ static <T,U> T castReference(Class<? extends T> t, U x) { return t.cast(x); } private static final MethodHandle IDENTITY, IDENTITY_I, IDENTITY_J, CAST_REFERENCE, ALWAYS_NULL, ALWAYS_ZERO, ZERO_OBJECT, IGNORE, EMPTY, NEW_ARRAY; static { try { MethodType idType = MethodType.genericMethodType(1); MethodType castType = idType.insertParameterTypes(0, Class.class); MethodType alwaysZeroType = idType.changeReturnType(int.class); MethodType ignoreType = idType.changeReturnType(void.class); MethodType zeroObjectType = MethodType.genericMethodType(0); IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType); IDENTITY_I = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(int.class, int.class)); IDENTITY_J = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(long.class, long.class)); //CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType); CAST_REFERENCE = IMPL_LOOKUP.findStatic(THIS_CLASS, "castReference", castType); ALWAYS_NULL = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysNull", idType); ALWAYS_ZERO = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysZero", alwaysZeroType); ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType); IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType); EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1)); NEW_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "newArray", MethodType.methodType(Object[].class, int.class)); } catch (NoSuchMethodException | IllegalAccessException ex) { Error err = new InternalError("uncaught exception"); err.initCause(ex); throw err; } } // Varargs methods need to be in a separately initialized class, to bootstrapping problems. static class LazyStatics { private static final MethodHandle COPY_AS_REFERENCE_ARRAY, COPY_AS_PRIMITIVE_ARRAY, MAKE_LIST; static { try { //MAKE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeArray", MethodType.methodType(Object[].class, Object[].class)); COPY_AS_REFERENCE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsReferenceArray", MethodType.methodType(Object[].class, Class.class, Object[].class)); COPY_AS_PRIMITIVE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsPrimitiveArray", MethodType.methodType(Object.class, Wrapper.class, Object[].class)); MAKE_LIST = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeList", MethodType.methodType(List.class, Object[].class)); } catch (ReflectiveOperationException ex) { Error err = new InternalError("uncaught exception"); err.initCause(ex); throw err; } } } private static final EnumMap<Wrapper, MethodHandle>[] WRAPPER_CASTS = newWrapperCaches(2); /** Return a method that casts its sole argument (an Object) to the given type * and returns it as the given type (if exact is true), or as plain Object (if erase is true). */ public static MethodHandle cast(Class<?> type) { boolean exact = false; if (type.isPrimitive()) throw new IllegalArgumentException("cannot cast primitive type "+type); MethodHandle mh = null; Wrapper wrap = null; EnumMap<Wrapper, MethodHandle> cache = null; if (Wrapper.isWrapperType(type)) { wrap = Wrapper.forWrapperType(type); cache = WRAPPER_CASTS[exact?1:0]; mh = cache.get(wrap); if (mh != null) return mh; } if (VerifyType.isNullReferenceConversion(Object.class, type)) mh = IDENTITY; else if (VerifyType.isNullType(type)) mh = ALWAYS_NULL; else mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type); if (exact) { MethodType xmt = MethodType.methodType(type, Object.class); mh = MethodHandles.explicitCastArguments(mh, xmt); //mh = AdapterMethodHandle.makeRetypeRaw(IMPL_TOKEN, xmt, mh); } if (cache != null) cache.put(wrap, mh); return mh; } public static MethodHandle identity() { return IDENTITY; } public static MethodHandle identity(Class<?> type) { // This stuff has been moved into MethodHandles: return MethodHandles.identity(type); } public static MethodHandle identity(Wrapper wrap) { EnumMap<Wrapper, MethodHandle> cache = CONSTANT_FUNCTIONS[1]; MethodHandle mh = cache.get(wrap); if (mh != null) { return mh; } // slow path MethodType type = MethodType.methodType(wrap.primitiveType()); if (wrap != Wrapper.VOID) type = type.appendParameterTypes(wrap.primitiveType()); try { mh = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", type); } catch (ReflectiveOperationException ex) { mh = null; } if (mh == null && wrap == Wrapper.VOID) { mh = EMPTY; // #(){} : #()void } if (mh != null) { cache.put(wrap, mh); return mh; } if (mh != null) { cache.put(wrap, mh); return mh; } throw new IllegalArgumentException("cannot find identity for " + wrap); } /// Float/non-float conversions. static float doubleToFloat(double x) { return (float) x; } static double floatToDouble(float x) { return x; } // narrow double to integral type static long doubleToLong(double x) { return (long) x; } static int doubleToInt(double x) { return (int) x; } static short doubleToShort(double x) { return (short) x; } static char doubleToChar(double x) { return (char) x; } static byte doubleToByte(double x) { return (byte) x; } static boolean doubleToBoolean(double x) { return toBoolean((byte) x); } // narrow float to integral type static long floatToLong(float x) { return (long) x; } static int floatToInt(float x) { return (int) x; } static short floatToShort(float x) { return (short) x; } static char floatToChar(float x) { return (char) x; } static byte floatToByte(float x) { return (byte) x; } static boolean floatToBoolean(float x) { return toBoolean((byte) x); } // widen integral type to double static double longToDouble(long x) { return x; } static double intToDouble(int x) { return x; } static double shortToDouble(short x) { return x; } static double charToDouble(char x) { return x; } static double byteToDouble(byte x) { return x; } static double booleanToDouble(boolean x) { return fromBoolean(x); } // widen integral type to float static float longToFloat(long x) { return x; } static float intToFloat(int x) { return x; } static float shortToFloat(short x) { return x; } static float charToFloat(char x) { return x; } static float byteToFloat(byte x) { return x; } static float booleanToFloat(boolean x) { return fromBoolean(x); } static boolean toBoolean(byte x) { // see javadoc for MethodHandles.explicitCastArguments return ((x & 1) != 0); } static byte fromBoolean(boolean x) { // see javadoc for MethodHandles.explicitCastArguments return (x ? (byte)1 : (byte)0); } private static final EnumMap<Wrapper, MethodHandle>[] CONVERT_FLOAT_FUNCTIONS = newWrapperCaches(4); static MethodHandle convertFloatFunction(Wrapper wrap, boolean toFloat, boolean doubleSize) { EnumMap<Wrapper, MethodHandle> cache = CONVERT_FLOAT_FUNCTIONS[(toFloat?1:0)+(doubleSize?2:0)]; MethodHandle mh = cache.get(wrap); if (mh != null) { return mh; } // slow path Wrapper fwrap = (doubleSize ? Wrapper.DOUBLE : Wrapper.FLOAT); Class<?> fix = wrap.primitiveType(); Class<?> flt = (doubleSize ? double.class : float.class); Class<?> src = toFloat ? fix : flt; Class<?> dst = toFloat ? flt : fix; if (src == dst) return identity(wrap); MethodType type = MethodType.methodType(dst, src); switch (wrap) { case VOID: mh = toFloat ? zeroConstantFunction(fwrap) : MethodHandles.dropArguments(EMPTY, 0, flt); break; case OBJECT: mh = toFloat ? unbox(flt) : box(flt); break; default: try { mh = IMPL_LOOKUP.findStatic(THIS_CLASS, src.getSimpleName()+"To"+capitalize(dst.getSimpleName()), type); } catch (ReflectiveOperationException ex) { mh = null; } break; } if (mh != null) { assert(mh.type() == type) : mh; cache.put(wrap, mh); return mh; } throw new IllegalArgumentException("cannot find float conversion constant for " + src.getSimpleName()+" -> "+dst.getSimpleName()); } public static MethodHandle convertFromFloat(Class<?> fixType) { Wrapper wrap = Wrapper.forPrimitiveType(fixType); return convertFloatFunction(wrap, false, false); } public static MethodHandle convertFromDouble(Class<?> fixType) { Wrapper wrap = Wrapper.forPrimitiveType(fixType); return convertFloatFunction(wrap, false, true); } public static MethodHandle convertToFloat(Class<?> fixType) { Wrapper wrap = Wrapper.forPrimitiveType(fixType); return convertFloatFunction(wrap, true, false); } public static MethodHandle convertToDouble(Class<?> fixType) { Wrapper wrap = Wrapper.forPrimitiveType(fixType); return convertFloatFunction(wrap, true, true); } private static String capitalize(String x) { return Character.toUpperCase(x.charAt(0))+x.substring(1); } /// Collection of multiple arguments. public static Object convertArrayElements(Class<?> arrayType, Object array) { Class<?> src = array.getClass().getComponentType(); Class<?> dst = arrayType.getComponentType(); if (src == null || dst == null) throw new IllegalArgumentException("not array type"); Wrapper sw = (src.isPrimitive() ? Wrapper.forPrimitiveType(src) : null); Wrapper dw = (dst.isPrimitive() ? Wrapper.forPrimitiveType(dst) : null); int length; if (sw == null) { Object[] a = (Object[]) array; length = a.length; if (dw == null) return Arrays.copyOf(a, length, arrayType.asSubclass(Object[].class)); Object res = dw.makeArray(length); dw.copyArrayUnboxing(a, 0, res, 0, length); return res; } length = java.lang.reflect.Array.getLength(array); Object[] res; if (dw == null) { res = Arrays.copyOf(NO_ARGS_ARRAY, length, arrayType.asSubclass(Object[].class)); } else { res = new Object[length]; } sw.copyArrayBoxing(array, 0, res, 0, length); if (dw == null) return res; Object a = dw.makeArray(length); dw.copyArrayUnboxing(res, 0, a, 0, length); return a; } private static MethodHandle findCollector(String name, int nargs, Class<?> rtype, Class<?>... ptypes) { MethodType type = MethodType.genericMethodType(nargs) .changeReturnType(rtype) .insertParameterTypes(0, ptypes); try { return IMPL_LOOKUP.findStatic(THIS_CLASS, name, type); } catch (ReflectiveOperationException ex) { return null; } } private static final Object[] NO_ARGS_ARRAY = {}; private static Object[] makeArray(Object... args) { return args; } private static Object[] array() { return NO_ARGS_ARRAY; } private static Object[] array(Object a0) { return makeArray(a0); } private static Object[] array(Object a0, Object a1) { return makeArray(a0, a1); } private static Object[] array(Object a0, Object a1, Object a2) { return makeArray(a0, a1, a2); } private static Object[] array(Object a0, Object a1, Object a2, Object a3) { return makeArray(a0, a1, a2, a3); } private static Object[] array(Object a0, Object a1, Object a2, Object a3, Object a4) { return makeArray(a0, a1, a2, a3, a4); } private static Object[] array(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return makeArray(a0, a1, a2, a3, a4, a5); } private static Object[] array(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { return makeArray(a0, a1, a2, a3, a4, a5, a6); } private static Object[] array(Object a0, Object a1, Object a2, Object a3,