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); }
public static MethodHandle convertPrimitive(Wrapper wsrc, Wrapper wdst) { EnumMap<Wrapper, MethodHandle> cache = CONVERT_PRIMITIVE_FUNCTIONS[wsrc.ordinal()]; MethodHandle mh = cache.get(wdst); if (mh != null) { return mh; } // slow path Class<?> src = wsrc.primitiveType(); Class<?> dst = wdst.primitiveType(); MethodType type = src == void.class ? MethodType.methodType(dst) : MethodType.methodType(dst, src); if (wsrc == wdst) { mh = identity(src); } else if (wsrc == Wrapper.VOID) { mh = zeroConstantFunction(wdst); } else if (wdst == Wrapper.VOID) { mh = MethodHandles.dropArguments(EMPTY, 0, src); // Defer back to MethodHandles. } else if (wsrc == Wrapper.OBJECT) { mh = unboxCast(dst); } else if (wdst == Wrapper.OBJECT) { mh = box(src); } else { assert (src.isPrimitive() && dst.isPrimitive()); try { mh = IMPL_LOOKUP.findStatic( THIS_CLASS, src.getSimpleName() + "To" + capitalize(dst.getSimpleName()), type); } catch (ReflectiveOperationException ex) { mh = null; } } if (mh != null) { assert (mh.type() == type) : mh; cache.put(wdst, mh); return mh; } throw new IllegalArgumentException( "cannot find primitive conversion function for " + src.getSimpleName() + " -> " + dst.getSimpleName()); }
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.wrapperSimpleName(), type); } catch (ReflectiveOperationException ex) { mh = null; } break; } if (mh != null) { cache.put(wrap, mh); return mh; } // use zeroInt and cast the result if (wrap.isSubwordOrInt() && wrap != Wrapper.INT) { mh = MethodHandles.explicitCastArguments(zeroConstantFunction(Wrapper.INT), type); cache.put(wrap, mh); return mh; } throw new IllegalArgumentException("cannot find zero constant for " + wrap); }
private static MethodType boxType(Wrapper wrap) { // be exact, since return casts are hard to compose Class<?> boxType = wrap.wrapperType(); return MethodType.methodType(boxType, wrap.primitiveType()); }
private static MethodType unboxType(Wrapper wrap) { return MethodType.methodType(wrap.primitiveType(), Object.class, boolean.class); }