1237 lines · 44.9 KB · Java
RawDownload
    }     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