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 = j86.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; }
/** * Finds method that accessible from specified class. * * @param method object that represents found method * @param generic generic type that is used to find accessible method * @return object that represents accessible method * @throws NoSuchMethodException if method is not accessible or is not found in specified * superclass or interface */ private static Method findAccessibleMethod(Method method, Type generic) throws NoSuchMethodException { String name = method.getName(); Class<?>[] params = method.getParameterTypes(); if (generic instanceof Class) { Class<?> type = (Class<?>) generic; return findAccessibleMethod(type.getMethod(name, params)); } if (generic instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) generic; Class<?> type = (Class<?>) pt.getRawType(); for (Method m : type.getMethods()) { if (m.getName().equals(name)) { Class<?>[] pts = m.getParameterTypes(); if (pts.length == params.length) { if (Arrays.equals(params, pts)) { return findAccessibleMethod(m); } Type[] gpts = m.getGenericParameterTypes(); if (params.length == gpts.length) { if (Arrays.equals(params, TypeResolver.erase(TypeResolver.resolve(pt, gpts)))) { return findAccessibleMethod(m); } } } } } } throw new NoSuchMethodException("Method '" + name + "' is not accessible"); }
/** * Constructs a <code>BatchUpdateException</code> object initialized with a given <code>reason * </code>, <code>SQLState</code>, <code>vendorCode</code> <code>cause</code> and <code> * updateCounts</code>. * * <p>This constructor should be used when the returned update count may exceed {@link * Integer#MAX_VALUE}. * * <p> * * @param reason a description of the error * @param SQLState an XOPEN or SQL:2003 code identifying the exception * @param vendorCode an exception code used by a particular database vendor * @param updateCounts an array of <code>long</code>, with each element indicating the update * count, <code>Statement.SUCCESS_NO_INFO</code> or <code>Statement.EXECUTE_FAILED</code> for * each SQL command in the batch for JDBC drivers that continue processing after a command * failure; an update count or <code>Statement.SUCCESS_NO_INFO</code> for each SQL command in * the batch prior to the failure for JDBC drivers that stop processing after a command * failure * @param cause the underlying reason for this <code>SQLException</code> (which is saved for later * retrieval by the <code>getCause()</code> method); may be null indicating the cause is * non-existent or unknown. * @since 1.8 */ public BatchUpdateException( String reason, String SQLState, int vendorCode, long[] updateCounts, Throwable cause) { super(reason, SQLState, vendorCode, cause); this.longUpdateCounts = (updateCounts == null) ? null : Arrays.copyOf(updateCounts, updateCounts.length); this.updateCounts = (longUpdateCounts == null) ? null : copyUpdateCount(longUpdateCounts); }
/** * Return a method handle that takes the indicated number of typed arguments and returns an array * of them. The type argument is the array type. */ public static MethodHandle varargsArray(Class<?> arrayType, int nargs) { Class<?> elemType = arrayType.getComponentType(); if (elemType == null) throw new IllegalArgumentException("not an array: " + arrayType); // FIXME: Need more special casing and caching here. if (nargs >= MAX_JVM_ARITY / 2 - 1) { int slots = nargs; final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1; // 1 for receiver MH if (arrayType == double[].class || arrayType == long[].class) slots *= 2; if (slots > MAX_ARRAY_SLOTS) throw new IllegalArgumentException( "too many arguments: " + arrayType.getSimpleName() + ", length " + nargs); } if (elemType == Object.class) return varargsArray(nargs); // other cases: primitive arrays, subtypes of Object[] MethodHandle cache[] = TYPED_COLLECTORS.get(elemType); MethodHandle mh = nargs < cache.length ? cache[nargs] : null; if (mh != null) return mh; if (elemType.isPrimitive()) { MethodHandle builder = FILL_NEW_ARRAY; MethodHandle producer = buildArrayProducer(arrayType); mh = buildVarargsArray(builder, producer, nargs); } else { @SuppressWarnings("unchecked") Class<? extends Object[]> objArrayType = (Class<? extends Object[]>) arrayType; Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType); MethodHandle builder = FILL_NEW_TYPED_ARRAY.bindTo(example); MethodHandle producer = ARRAY_IDENTITY; mh = buildVarargsArray(builder, producer, nargs); } mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType))); assert (assertCorrectArity(mh, nargs)); if (nargs < cache.length) cache[nargs] = mh; return mh; }
/** * Returns the epochMonth found by locating the epochDay in the table. The epochMonth is the index * in the table * * @param epochDay * @return The index of the element of the start of the month containing the epochDay. */ private int epochDayToEpochMonth(int epochDay) { // binary search int ndx = Arrays.binarySearch(hijrahEpochMonthStartDays, epochDay); if (ndx < 0) { ndx = -ndx - 2; } return ndx; }
@Override public int hashCode() { int result = 17; result = 37 * result + cksumType; if (checksum != null) { result = 37 * result + Arrays.hashCode(checksum); } return result; }
/** * Compares this finite field for equality with the specified object. * * @param obj the object to be compared. * @return true if {@code obj} is an instance of ECFieldF2m and both {@code m} and the reduction * polynomial match, false otherwise. */ public boolean equals(Object obj) { if (this == obj) return true; if (obj instanceof ECFieldF2m) { // no need to compare rp here since ks and rp // should be equivalent return ((m == ((ECFieldF2m) obj).m) && (Arrays.equals(ks, ((ECFieldF2m) obj).ks))); } return false; }
private static byte[][] genConst() { int n = 10; byte[][] arr = new byte[n][]; for (int i = 0; i < n; i++) { byte[] b = new byte[i + 1]; Arrays.fill(b, (byte) ('A' + i)); arr[i] = b; } return arr; }
private String contentString() { StringBuilder sb = new StringBuilder("{"); String sep = ""; for (Map.Entry<String, Object> entry : contents.entrySet()) { sb.append(sep).append(entry.getKey()).append("="); String s = Arrays.deepToString(new Object[] {entry.getValue()}); sb.append(s.substring(1, s.length() - 1)); sep = ", "; } sb.append("}"); return sb.toString(); }
/** * This method may return false negatives. But if it says two names are equals, then there is some * mechanism that authenticates them as the same principal. */ public boolean equals(GSSName other) throws GSSException { if (this.isAnonymous() || other.isAnonymous()) return false; if (other == this) return true; if (!(other instanceof GSSNameImpl)) return equals(gssManager.createName(other.toString(), other.getStringNameType())); /* * XXX Do a comparison of the appNameStr/appNameBytes if * available. If that fails, then proceed with this test. */ GSSNameImpl that = (GSSNameImpl) other; GSSNameSpi myElement = this.mechElement; GSSNameSpi element = that.mechElement; /* * XXX If they are not of the same mechanism type, convert both to * Kerberos since it is guaranteed to be present. */ if ((myElement == null) && (element != null)) { myElement = this.getElement(element.getMechanism()); } else if ((myElement != null) && (element == null)) { element = that.getElement(myElement.getMechanism()); } if (myElement != null && element != null) { return myElement.equals(element); } if ((this.appNameType != null) && (that.appNameType != null)) { if (!this.appNameType.equals(that.appNameType)) { return false; } byte[] myBytes = null; byte[] bytes = null; try { myBytes = (this.appNameStr != null ? this.appNameStr.getBytes("UTF-8") : this.appNameBytes); bytes = (that.appNameStr != null ? that.appNameStr.getBytes("UTF-8") : that.appNameBytes); } catch (UnsupportedEncodingException e) { // Won't happen } return Arrays.equals(myBytes, bytes); } return false; }
/** * Returns the hash code value for this <code>CompositeDataSupport</code> instance. * * <p>The hash code of a <code>CompositeDataSupport</code> instance is the sum of the hash codes * of all elements of information used in <code>equals</code> comparisons (ie: its <i>composite * type</i> and all the item values). * * <p>This ensures that <code> t1.equals(t2) </code> implies that <code> * t1.hashCode()==t2.hashCode() </code> for any two <code>CompositeDataSupport</code> instances * <code>t1</code> and <code>t2</code>, as required by the general contract of the method {@link * Object#hashCode() Object.hashCode()}. * * <p>Each item value's hash code is added to the returned hash code. If an item value is an * array, its hash code is obtained as if by calling the {@link * j86.java.util.Arrays#deepHashCode(Object[]) deepHashCode} method for arrays of object reference * types or the appropriate overloading of {@code Arrays.hashCode(e)} for arrays of primitive * types. * * @return the hash code value for this <code>CompositeDataSupport</code> instance */ @Override public int hashCode() { int hashcode = compositeType.hashCode(); for (Object o : contents.values()) { if (o instanceof Object[]) hashcode += Arrays.deepHashCode((Object[]) o); else if (o instanceof byte[]) hashcode += Arrays.hashCode((byte[]) o); else if (o instanceof short[]) hashcode += Arrays.hashCode((short[]) o); else if (o instanceof int[]) hashcode += Arrays.hashCode((int[]) o); else if (o instanceof long[]) hashcode += Arrays.hashCode((long[]) o); else if (o instanceof char[]) hashcode += Arrays.hashCode((char[]) o); else if (o instanceof float[]) hashcode += Arrays.hashCode((float[]) o); else if (o instanceof double[]) hashcode += Arrays.hashCode((double[]) o); else if (o instanceof boolean[]) hashcode += Arrays.hashCode((boolean[]) o); else if (o != null) hashcode += o.hashCode(); } return hashcode; }
/** * Facilitates the creation of simple "function objects" that implement one or more interfaces by * delegation to a provided {@link MethodHandle}, after appropriate type adaptation and partial * evaluation of arguments. Typically used as a <em>bootstrap method</em> for {@code * invokedynamic} call sites, to support the <em>lambda expression</em> and <em>method reference * expression</em> features of the Java Programming Language. * * <p>This is the general, more flexible metafactory; a streamlined version is provided by {@link * #altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)}. A general description of * the behavior of this method is provided {@link LambdaMetafactory above}. * * <p>The argument list for this method includes three fixed parameters, corresponding to the * parameters automatically stacked by the VM for the bootstrap method in an {@code invokedynamic} * invocation, and an {@code Object[]} parameter that contains additional parameters. The declared * argument list for this method is: * * <pre>{@code * CallSite altMetafactory(MethodHandles.Lookup caller, * String invokedName, * MethodType invokedType, * Object... args) * }</pre> * * <p>but it behaves as if the argument list is as follows: * * <pre>{@code * CallSite altMetafactory(MethodHandles.Lookup caller, * String invokedName, * MethodType invokedType, * MethodType samMethodType, * MethodHandle implMethod, * MethodType instantiatedMethodType, * int flags, * int markerInterfaceCount, // IF flags has MARKERS set * Class... markerInterfaces, // IF flags has MARKERS set * int bridgeCount, // IF flags has BRIDGES set * MethodType... bridges // IF flags has BRIDGES set * ) * }</pre> * * <p>Arguments that appear in the argument list for {@link #metafactory(MethodHandles.Lookup, * String, MethodType, MethodType, MethodHandle, MethodType)} have the same specification as in * that method. The additional arguments are interpreted as follows: * * <ul> * <li>{@code flags} indicates additional options; this is a bitwise OR of desired flags. * Defined flags are {@link #FLAG_BRIDGES}, {@link #FLAG_MARKERS}, and {@link * #FLAG_SERIALIZABLE}. * <li>{@code markerInterfaceCount} is the number of additional interfaces the function object * should implement, and is present if and only if the {@code FLAG_MARKERS} flag is set. * <li>{@code markerInterfaces} is a variable-length list of additional interfaces to implement, * whose length equals {@code markerInterfaceCount}, and is present if and only if the * {@code FLAG_MARKERS} flag is set. * <li>{@code bridgeCount} is the number of additional method signatures the function object * should implement, and is present if and only if the {@code FLAG_BRIDGES} flag is set. * <li>{@code bridges} is a variable-length list of additional methods signatures to implement, * whose length equals {@code bridgeCount}, and is present if and only if the {@code * FLAG_BRIDGES} flag is set. * </ul> * * <p>Each class named by {@code markerInterfaces} is subject to the same restrictions as {@code * Rd}, the return type of {@code invokedType}, as described {@link LambdaMetafactory above}. Each * {@code MethodType} named by {@code bridges} is subject to the same restrictions as {@code * samMethodType}, as described {@link LambdaMetafactory above}. * * <p>When FLAG_SERIALIZABLE is set in {@code flags}, the function objects will implement {@code * Serializable}, and will have a {@code writeReplace} method that returns an appropriate {@link * SerializedLambda}. The {@code caller} class must have an appropriate {@code * $deserializeLambda$} method, as described in {@link SerializedLambda}. * * <p>When the target of the {@code CallSite} returned from this method is invoked, the resulting * function objects are instances of a class with the following properties: * * <ul> * <li>The class implements the interface named by the return type of {@code invokedType} and * any interfaces named by {@code markerInterfaces} * <li>The class declares methods with the name given by {@code invokedName}, and the signature * given by {@code samMethodType} and additional signatures given by {@code bridges} * <li>The class may override methods from {@code Object}, and may implement methods related to * serialization. * </ul> * * @param caller Represents a lookup context with the accessibility privileges of the caller. When * used with {@code invokedynamic}, this is stacked automatically by the VM. * @param invokedName The name of the method to implement. When used with {@code invokedynamic}, * this is provided by the {@code NameAndType} of the {@code InvokeDynamic} structure and is * stacked automatically by the VM. * @param invokedType The expected signature of the {@code CallSite}. The parameter types * represent the types of capture variables; the return type is the interface to implement. * When used with {@code invokedynamic}, this is provided by the {@code NameAndType} of the * {@code InvokeDynamic} structure and is stacked automatically by the VM. In the event that * the implementation method is an instance method and this signature has any parameters, the * first parameter in the invocation signature must correspond to the receiver. * @param args An {@code Object[]} array containing the required arguments {@code samMethodType}, * {@code implMethod}, {@code instantiatedMethodType}, {@code flags}, and any optional * arguments, as described {@link #altMetafactory(MethodHandles.Lookup, String, MethodType, * Object...)} above} * @return a CallSite whose target can be used to perform capture, generating instances of the * interface named by {@code invokedType} * @throws LambdaConversionException If any of the linkage invariants described {@link * LambdaMetafactory above} are violated */ public static CallSite altMetafactory( MethodHandles.Lookup caller, String invokedName, MethodType invokedType, Object... args) throws LambdaConversionException { MethodType samMethodType = (MethodType) args[0]; MethodHandle implMethod = (MethodHandle) args[1]; MethodType instantiatedMethodType = (MethodType) args[2]; int flags = (Integer) args[3]; Class<?>[] markerInterfaces; MethodType[] bridges; int argIndex = 4; if ((flags & FLAG_MARKERS) != 0) { int markerCount = (Integer) args[argIndex++]; markerInterfaces = new Class<?>[markerCount]; System.arraycopy(args, argIndex, markerInterfaces, 0, markerCount); argIndex += markerCount; } else markerInterfaces = EMPTY_CLASS_ARRAY; if ((flags & FLAG_BRIDGES) != 0) { int bridgeCount = (Integer) args[argIndex++]; bridges = new MethodType[bridgeCount]; System.arraycopy(args, argIndex, bridges, 0, bridgeCount); argIndex += bridgeCount; } else bridges = EMPTY_MT_ARRAY; boolean isSerializable = ((flags & FLAG_SERIALIZABLE) != 0); if (isSerializable) { boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(invokedType.returnType()); for (Class<?> c : markerInterfaces) foundSerializableSupertype |= Serializable.class.isAssignableFrom(c); if (!foundSerializableSupertype) { markerInterfaces = Arrays.copyOf(markerInterfaces, markerInterfaces.length + 1); markerInterfaces[markerInterfaces.length - 1] = Serializable.class; } } AbstractValidatingLambdaMetafactory mf = new InnerClassLambdaMetafactory( caller, invokedType, invokedName, samMethodType, implMethod, instantiatedMethodType, isSerializable, markerInterfaces, bridges); mf.validateMetafactoryArgs(); return mf.buildCallSite(); }
/** * Parses the 12 months lengths from a property value for a specific year. * * @param line the value of a year property * @return an array of int[12] containing the 12 month lengths * @throws IllegalArgumentException if the number of months is not 12 * @throws NumberFormatException if the 12 tokens are not numbers */ private int[] parseMonths(String line) { int[] months = new int[12]; String[] numbers = line.split("\\s"); if (numbers.length != 12) { throw new IllegalArgumentException( "wrong number of months on line: " + Arrays.toString(numbers) + "; count: " + numbers.length); } for (int i = 0; i < 12; i++) { try { months[i] = Integer.valueOf(numbers[i]); } catch (NumberFormatException nfe) { throw new IllegalArgumentException("bad key: " + numbers[i]); } } return months; }
/** * Compares the specified <var>obj</var> parameter with this <code>CompositeDataSupport</code> * instance for equality. * * <p>Returns <tt>true</tt> if and only if all of the following statements are true: * * <ul> * <li><var>obj</var> is non null, * <li><var>obj</var> also implements the <code>CompositeData</code> interface, * <li>their composite types are equal * <li>their contents, i.e. (name, value) pairs are equal. If a value contained in the content * is an array, the value comparison is done as if by calling the {@link * j86.java.util.Arrays#deepEquals(Object[], Object[]) deepEquals} method for arrays of * object reference types or the appropriate overloading of {@code Arrays.equals(e1,e2)} for * arrays of primitive types * </ul> * * <p>This ensures that this <tt>equals</tt> method works properly for <var>obj</var> parameters * which are different implementations of the <code>CompositeData</code> interface, with the * restrictions mentioned in the {@link j86.java.util.Collection#equals(Object) equals} method of * the <tt>j86.java.util.Collection</tt> interface. * * @param obj the object to be compared for equality with this <code>CompositeDataSupport</code> * instance. * @return <code>true</code> if the specified object is equal to this <code>CompositeDataSupport * </code> instance. */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } // if obj is not a CompositeData, return false if (!(obj instanceof CompositeData)) { return false; } CompositeData other = (CompositeData) obj; // their compositeType should be equal if (!this.getCompositeType().equals(other.getCompositeType())) { return false; } if (contents.size() != other.values().size()) { return false; } for (Map.Entry<String, Object> entry : contents.entrySet()) { Object e1 = entry.getValue(); Object e2 = other.get(entry.getKey()); if (e1 == e2) continue; if (e1 == null) return false; boolean eq = e1.getClass().isArray() ? Arrays.deepEquals(new Object[] {e1}, new Object[] {e2}) : e1.equals(e2); if (!eq) return false; } // All tests for equality were successful // return true; }
/** * Retrieves the update count for each update statement in the batch update that executed * successfully before this exception occurred. A driver that implements batch updates may or may * not continue to process the remaining commands in a batch when one of the commands fails to * execute properly. If the driver continues processing commands, the array returned by this * method will have as many elements as there are commands in the batch; otherwise, it will * contain an update count for each command that executed successfully before the <code> * BatchUpdateException</code> was thrown. * * <p>The possible return values for this method were modified for the Java 2 SDK, Standard * Edition, version 1.3. This was done to accommodate the new option of continuing to process * commands in a batch update after a <code>BatchUpdateException</code> object has been thrown. * * @return an array of <code>int</code> containing the update counts for the updates that were * executed successfully before this error occurred. Or, if the driver continues to process * commands after an error, one of the following for every command in the batch: * <OL> * <LI>an update count * <LI><code>Statement.SUCCESS_NO_INFO</code> to indicate that the command executed * successfully but the number of rows affected is unknown * <LI><code>Statement.EXECUTE_FAILED</code> to indicate that the command failed to execute * successfully * </OL> * * @since 1.3 * @see #getLargeUpdateCounts() */ public int[] getUpdateCounts() { return (updateCounts == null) ? null : Arrays.copyOf(updateCounts, updateCounts.length); }
public SF2Instrument[] getInstruments() { SF2Instrument[] inslist_array = instruments.toArray(new SF2Instrument[instruments.size()]); Arrays.sort(inslist_array, new ModelInstrumentComparator()); return inslist_array; }
public class ValueConversions { private static final Class<?> THIS_CLASS = ValueConversions.class; // Do not adjust this except for special platforms: private static final int MAX_ARITY; static { final Object[] values = {255}; AccessController.doPrivileged( new PrivilegedAction<Void>() { @Override public Void run() { values[0] = Integer.getInteger(THIS_CLASS.getName() + ".MAX_ARITY", 255); return null; } }); MAX_ARITY = (Integer) values[0]; } private static final Lookup IMPL_LOOKUP = MethodHandles.lookup(); private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) { @SuppressWarnings("unchecked") // generic array creation EnumMap<Wrapper, MethodHandle>[] caches = (EnumMap<Wrapper, MethodHandle>[]) new EnumMap<?, ?>[n]; for (int i = 0; i < n; i++) caches[i] = new EnumMap<>(Wrapper.class); return caches; } /// Converting references to values. // There are several levels of this unboxing conversions: // no conversions: exactly Integer.valueOf, etc. // implicit conversions sanctioned by JLS 5.1.2, etc. // explicit conversions as allowed by explicitCastArguments static int unboxInteger(Object x, boolean cast) { if (x instanceof Integer) return ((Integer) x).intValue(); return primitiveConversion(Wrapper.INT, x, cast).intValue(); } static byte unboxByte(Object x, boolean cast) { if (x instanceof Byte) return ((Byte) x).byteValue(); return primitiveConversion(Wrapper.BYTE, x, cast).byteValue(); } static short unboxShort(Object x, boolean cast) { if (x instanceof Short) return ((Short) x).shortValue(); return primitiveConversion(Wrapper.SHORT, x, cast).shortValue(); } static boolean unboxBoolean(Object x, boolean cast) { if (x instanceof Boolean) return ((Boolean) x).booleanValue(); return (primitiveConversion(Wrapper.BOOLEAN, x, cast).intValue() & 1) != 0; } static char unboxCharacter(Object x, boolean cast) { if (x instanceof Character) return ((Character) x).charValue(); return (char) primitiveConversion(Wrapper.CHAR, x, cast).intValue(); } static long unboxLong(Object x, boolean cast) { if (x instanceof Long) return ((Long) x).longValue(); return primitiveConversion(Wrapper.LONG, x, cast).longValue(); } static float unboxFloat(Object x, boolean cast) { if (x instanceof Float) return ((Float) x).floatValue(); return primitiveConversion(Wrapper.FLOAT, x, cast).floatValue(); } static double unboxDouble(Object x, boolean cast) { if (x instanceof Double) return ((Double) x).doubleValue(); return primitiveConversion(Wrapper.DOUBLE, x, cast).doubleValue(); } private static MethodType unboxType(Wrapper wrap) { return MethodType.methodType(wrap.primitiveType(), Object.class, boolean.class); } private static final EnumMap<Wrapper, MethodHandle>[] UNBOX_CONVERSIONS = newWrapperCaches(2); private static MethodHandle unbox(Wrapper wrap, boolean cast) { EnumMap<Wrapper, MethodHandle> cache = UNBOX_CONVERSIONS[(cast ? 1 : 0)]; MethodHandle mh = cache.get(wrap); if (mh != null) { return mh; } // slow path switch (wrap) { case OBJECT: mh = IDENTITY; break; case VOID: mh = IGNORE; break; } if (mh != null) { cache.put(wrap, mh); return mh; } // look up the method String name = "unbox" + wrap.wrapperSimpleName(); MethodType type = unboxType(wrap); try { mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type); } catch (ReflectiveOperationException ex) { mh = null; } if (mh != null) { mh = MethodHandles.insertArguments(mh, 1, cast); cache.put(wrap, mh); return mh; } throw new IllegalArgumentException( "cannot find unbox adapter for " + wrap + (cast ? " (cast)" : "")); } public static MethodHandle unboxCast(Wrapper type) { return unbox(type, true); } public static MethodHandle unbox(Class<?> type) { return unbox(Wrapper.forPrimitiveType(type), false); } public static MethodHandle unboxCast(Class<?> type) { return unbox(Wrapper.forPrimitiveType(type), true); } private static final Integer ZERO_INT = 0, ONE_INT = 1; /// Primitive conversions /** * Produce a Number which represents the given value {@code x} according to the primitive type of * the given wrapper {@code wrap}. Caller must invoke intValue, byteValue, longValue (etc.) on the * result to retrieve the desired primitive value. */ public static Number primitiveConversion(Wrapper wrap, Object x, boolean cast) { // Maybe merge this code with Wrapper.convert/cast. Number res; if (x == null) { if (!cast) return null; return ZERO_INT; } if (x instanceof Number) { res = (Number) x; } else if (x instanceof Boolean) { res = ((boolean) x ? ONE_INT : ZERO_INT); } else if (x instanceof Character) { res = (int) (char) x; } else { // this will fail with the required ClassCastException: res = (Number) x; } Wrapper xwrap = Wrapper.findWrapperType(x.getClass()); if (xwrap == null || !cast && !wrap.isConvertibleFrom(xwrap)) // this will fail with the required ClassCastException: return (Number) wrap.wrapperType().cast(x); return res; } /** * The JVM verifier allows boolean, byte, short, or char to widen to int. Support exactly this * conversion, from a boxed value type Boolean, Byte, Short, Character, or Integer. */ public static int widenSubword(Object x) { if (x instanceof Integer) return (int) x; else if (x instanceof Boolean) return fromBoolean((boolean) x); else if (x instanceof Character) return (char) x; else if (x instanceof Short) return (short) x; else if (x instanceof Byte) return (byte) x; else // Fail with a ClassCastException. return (int) x; } /// Converting primitives to references static Integer boxInteger(int x) { return x; } static Byte boxByte(byte x) { return x; } static Short boxShort(short x) { return x; } static Boolean boxBoolean(boolean x) { return x; } static Character boxCharacter(char x) { return x; } static Long boxLong(long x) { return x; } static Float boxFloat(float x) { return x; } static Double boxDouble(double x) { return x; } 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 final EnumMap<Wrapper, MethodHandle>[] BOX_CONVERSIONS = newWrapperCaches(2); private static MethodHandle box(Wrapper wrap, boolean exact) { EnumMap<Wrapper, MethodHandle> cache = BOX_CONVERSIONS[(exact ? 1 : 0)]; MethodHandle mh = cache.get(wrap); if (mh != null) { return mh; } // slow path switch (wrap) { case OBJECT: mh = IDENTITY; break; case VOID: mh = ZERO_OBJECT; break; } if (mh != null) { cache.put(wrap, mh); return mh; } // look up the method String name = "box" + wrap.wrapperSimpleName(); MethodType type = boxType(wrap); if (exact) { try { mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type); } catch (ReflectiveOperationException ex) { mh = null; } } else { mh = box(wrap, !exact).asType(type.erase()); } if (mh != null) { cache.put(wrap, mh); return mh; } throw new IllegalArgumentException( "cannot find box adapter for " + wrap + (exact ? " (exact)" : "")); } public static MethodHandle box(Class<?> type) { boolean exact = false; // e.g., boxShort(short)Short if exact, // e.g., boxShort(short)Object if !exact return box(Wrapper.forPrimitiveType(type), exact); } public static MethodHandle box(Wrapper type) { boolean exact = false; return box(type, exact); } /// Constant functions static void ignore(Object x) { // no value to return; this is an unbox of null } static void empty() {} 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.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); } /// Converting references to references. /** * Identity function. * * @param x an arbitrary reference value * @return the same value x */ static <T> T identity(T x) { return 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 */ @SuppressWarnings("unchecked") static <T, U> T castReference(Class<? extends T> t, U x) { // inlined Class.cast because we can't ForceInline it if (x != null && !t.isInstance(x)) throw newClassCastException(t, x); return (T) x; } private static ClassCastException newClassCastException(Class<?> t, Object obj) { return new ClassCastException("Cannot cast " + obj.getClass().getName() + " to " + t.getName()); } private static final MethodHandle IDENTITY, CAST_REFERENCE, ZERO_OBJECT, IGNORE, EMPTY, ARRAY_IDENTITY, FILL_NEW_TYPED_ARRAY, FILL_NEW_ARRAY; static { try { MethodType idType = MethodType.genericMethodType(1); MethodType castType = idType.insertParameterTypes(0, Class.class); MethodType ignoreType = idType.changeReturnType(void.class); MethodType zeroObjectType = MethodType.genericMethodType(0); IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType); // CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType); CAST_REFERENCE = IMPL_LOOKUP.findStatic(THIS_CLASS, "castReference", castType); 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)); ARRAY_IDENTITY = IMPL_LOOKUP.findStatic( THIS_CLASS, "identity", MethodType.methodType(Object[].class, Object[].class)); FILL_NEW_ARRAY = IMPL_LOOKUP.findStatic( THIS_CLASS, "fillNewArray", MethodType.methodType(Object[].class, Integer.class, Object[].class)); FILL_NEW_TYPED_ARRAY = IMPL_LOOKUP.findStatic( THIS_CLASS, "fillNewTypedArray", MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class)); } catch (NoSuchMethodException | IllegalAccessException ex) { throw newInternalError("uncaught exception", ex); } } // Varargs methods need to be in a separately initialized class, to avoid 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) { throw newInternalError("uncaught exception", ex); } } } private static final EnumMap<Wrapper, MethodHandle>[] WRAPPER_CASTS = newWrapperCaches(1); /** * Return a method that casts its sole argument (an Object) to the given type and returns it as * the given type. */ public static MethodHandle cast(Class<?> type) { if (type.isPrimitive()) throw new IllegalArgumentException("cannot cast primitive type " + type); MethodHandle mh; Wrapper wrap = null; EnumMap<Wrapper, MethodHandle> cache = null; if (Wrapper.isWrapperType(type)) { wrap = Wrapper.forWrapperType(type); cache = WRAPPER_CASTS[0]; mh = cache.get(wrap); if (mh != null) return mh; } mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type); if (cache != null) cache.put(wrap, mh); return mh; } public static MethodHandle identity() { return IDENTITY; } public static MethodHandle identity(Class<?> type) { if (!type.isPrimitive()) // Reference identity has been moved into MethodHandles: return MethodHandles.identity(type); return identity(Wrapper.findPrimitiveType(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); } /// Primitive conversions. // These are supported directly by the JVM, usually by a single instruction. // In the case of narrowing to a subword, there may be a pair of instructions. // In the case of booleans, there may be a helper routine to manage a 1-bit value. // This is the full 8x8 matrix (minus the diagonal). // narrow double to all other types: static float doubleToFloat(double x) { // bytecode: d2f return (float) x; } static long doubleToLong(double x) { // bytecode: d2l return (long) x; } static int doubleToInt(double x) { // bytecode: d2i return (int) x; } static short doubleToShort(double x) { // bytecodes: d2i, i2s return (short) x; } static char doubleToChar(double x) { // bytecodes: d2i, i2c return (char) x; } static byte doubleToByte(double x) { // bytecodes: d2i, i2b return (byte) x; } static boolean doubleToBoolean(double x) { return toBoolean((byte) x); } // widen float: static double floatToDouble(float x) { // bytecode: f2d return x; } // narrow float: static long floatToLong(float x) { // bytecode: f2l return (long) x; } static int floatToInt(float x) { // bytecode: f2i return (int) x; } static short floatToShort(float x) { // bytecodes: f2i, i2s return (short) x; } static char floatToChar(float x) { // bytecodes: f2i, i2c return (char) x; } static byte floatToByte(float x) { // bytecodes: f2i, i2b return (byte) x; } static boolean floatToBoolean(float x) { return toBoolean((byte) x); } // widen long: static double longToDouble(long x) { // bytecode: l2d return x; } static float longToFloat(long x) { // bytecode: l2f return x; } // narrow long: static int longToInt(long x) { // bytecode: l2i return (int) x; } static short longToShort(long x) { // bytecodes: f2i, i2s return (short) x; } static char longToChar(long x) { // bytecodes: f2i, i2c return (char) x; } static byte longToByte(long x) { // bytecodes: f2i, i2b return (byte) x; } static boolean longToBoolean(long x) { return toBoolean((byte) x); } // widen int: static double intToDouble(int x) { // bytecode: i2d return x; } static float intToFloat(int x) { // bytecode: i2f return x; } static long intToLong(int x) { // bytecode: i2l return x; } // narrow int: static short intToShort(int x) { // bytecode: i2s return (short) x; } static char intToChar(int x) { // bytecode: i2c return (char) x; } static byte intToByte(int x) { // bytecode: i2b return (byte) x; } static boolean intToBoolean(int x) { return toBoolean((byte) x); } // widen short: static double shortToDouble(short x) { // bytecode: i2d (implicit 's2i') return x; } static float shortToFloat(short x) { // bytecode: i2f (implicit 's2i') return x; } static long shortToLong(short x) { // bytecode: i2l (implicit 's2i') return x; } static int shortToInt(short x) { // (implicit 's2i') return x; } // narrow short: static char shortToChar(short x) { // bytecode: i2c (implicit 's2i') return (char) x; } static byte shortToByte(short x) { // bytecode: i2b (implicit 's2i') return (byte) x; } static boolean shortToBoolean(short x) { return toBoolean((byte) x); } // widen char: static double charToDouble(char x) { // bytecode: i2d (implicit 'c2i') return x; } static float charToFloat(char x) { // bytecode: i2f (implicit 'c2i') return x; } static long charToLong(char x) { // bytecode: i2l (implicit 'c2i') return x; } static int charToInt(char x) { // (implicit 'c2i') return x; } // narrow char: static short charToShort(char x) { // bytecode: i2s (implicit 'c2i') return (short) x; } static byte charToByte(char x) { // bytecode: i2b (implicit 'c2i') return (byte) x; } static boolean charToBoolean(char x) { return toBoolean((byte) x); } // widen byte: static double byteToDouble(byte x) { // bytecode: i2d (implicit 'b2i') return x; } static float byteToFloat(byte x) { // bytecode: i2f (implicit 'b2i') return x; } static long byteToLong(byte x) { // bytecode: i2l (implicit 'b2i') return x; } static int byteToInt(byte x) { // (implicit 'b2i') return x; } static short byteToShort(byte x) { // bytecode: i2s (implicit 'b2i') return (short) x; } static char byteToChar(byte x) { // bytecode: i2b (implicit 'b2i') return (char) x; } // narrow byte to boolean: static boolean byteToBoolean(byte x) { return toBoolean(x); } // widen boolean to all types: static double booleanToDouble(boolean x) { return fromBoolean(x); } static float booleanToFloat(boolean x) { return fromBoolean(x); } static long booleanToLong(boolean x) { return fromBoolean(x); } static int booleanToInt(boolean x) { return fromBoolean(x); } static short booleanToShort(boolean x) { return fromBoolean(x); } static char booleanToChar(boolean x) { return (char) fromBoolean(x); } static byte booleanToByte(boolean x) { return fromBoolean(x); } // helpers to force boolean into the conversion scheme: 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_PRIMITIVE_FUNCTIONS = newWrapperCaches(Wrapper.values().length); 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 convertPrimitive(Class<?> src, Class<?> dst) { return convertPrimitive(Wrapper.forPrimitiveType(src), Wrapper.forPrimitiveType(dst)); } 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 = j86.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, Object a4, Object a5, Object a6, Object a7) { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); } private static Object[] array( Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); } private static Object[] array( Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); } private static MethodHandle[] makeArrays() { ArrayList<MethodHandle> mhs = new ArrayList<>(); for (; ; ) { MethodHandle mh = findCollector("array", mhs.size(), Object[].class); if (mh == null) break; mhs.add(mh); } assert (mhs.size() == 11); // current number of methods return mhs.toArray(new MethodHandle[MAX_ARITY + 1]); } private static final MethodHandle[] ARRAYS = makeArrays(); // filling versions of the above: // using Integer len instead of int len and no varargs to avoid bootstrapping problems private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) { Object[] a = new Object[len]; fillWithArguments(a, 0, args); return a; } private static Object[] fillNewTypedArray( Object[] example, Integer len, Object[] /*not ...*/ args) { Object[] a = Arrays.copyOf(example, len); fillWithArguments(a, 0, args); return a; } private static void fillWithArguments(Object[] a, int pos, Object... args) { System.arraycopy(args, 0, a, pos, args.length); } // using Integer pos instead of int pos to avoid bootstrapping problems private static Object[] fillArray(Integer pos, Object[] a, Object a0) { fillWithArguments(a, pos, a0); return a; } private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1) { fillWithArguments(a, pos, a0, a1); return a; } private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2) { fillWithArguments(a, pos, a0, a1, a2); return a; } private static Object[] fillArray( Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3) { fillWithArguments(a, pos, a0, a1, a2, a3); return a; } private static Object[] fillArray( Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3, Object a4) { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; } private static Object[] fillArray( Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; } private static Object[] fillArray( Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; } private static Object[] fillArray( Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; } private static Object[] fillArray( Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; } private static Object[] fillArray( Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; } private static MethodHandle[] makeFillArrays() { ArrayList<MethodHandle> mhs = new ArrayList<>(); mhs.add(null); // there is no empty fill; at least a0 is required for (; ; ) { MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class); if (mh == null) break; mhs.add(mh); } assert (mhs.size() == 11); // current number of methods return mhs.toArray(new MethodHandle[0]); } private static final MethodHandle[] FILL_ARRAYS = makeFillArrays(); private static Object[] copyAsReferenceArray(Class<? extends Object[]> arrayType, Object... a) { return Arrays.copyOf(a, a.length, arrayType); } private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) { Object a = w.makeArray(boxes.length); w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length); return a; } /** * Return a method handle that takes the indicated number of Object arguments and returns an * Object array of them, as if for varargs. */ public static MethodHandle varargsArray(int nargs) { MethodHandle mh = ARRAYS[nargs]; if (mh != null) return mh; mh = findCollector("array", nargs, Object[].class); if (mh != null) return ARRAYS[nargs] = mh; mh = buildVarargsArray(FILL_NEW_ARRAY, ARRAY_IDENTITY, nargs); assert (assertCorrectArity(mh, nargs)); return ARRAYS[nargs] = mh; } private static boolean assertCorrectArity(MethodHandle mh, int arity) { assert (mh.type().parameterCount() == arity) : "arity != " + arity + ": " + mh; return true; } private static MethodHandle buildVarargsArray( MethodHandle newArray, MethodHandle finisher, int nargs) { // Build up the result mh as a sequence of fills like this: // finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23)) // The various fill(_,10*I,___*[J]) are reusable. int leftLen = Math.min(nargs, LEFT_ARGS); // absorb some arguments immediately int rightLen = nargs - leftLen; MethodHandle leftCollector = newArray.bindTo(nargs); leftCollector = leftCollector.asCollector(Object[].class, leftLen); MethodHandle mh = finisher; if (rightLen > 0) { MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen); if (mh == ARRAY_IDENTITY) mh = rightFiller; else mh = MethodHandles.collectArguments(mh, 0, rightFiller); } if (mh == ARRAY_IDENTITY) mh = leftCollector; else mh = MethodHandles.collectArguments(mh, 0, leftCollector); return mh; } private static final int LEFT_ARGS = (FILL_ARRAYS.length - 1); private static final MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY + 1]; /** * fill_array_to_right(N).invoke(a, argL..arg[N-1]) fills a[L]..a[N-1] with corresponding * arguments, and then returns a. The value L is a global constant (LEFT_ARGS). */ private static MethodHandle fillToRight(int nargs) { MethodHandle filler = FILL_ARRAY_TO_RIGHT[nargs]; if (filler != null) return filler; filler = buildFiller(nargs); assert (assertCorrectArity(filler, nargs - LEFT_ARGS + 1)); return FILL_ARRAY_TO_RIGHT[nargs] = filler; } private static MethodHandle buildFiller(int nargs) { if (nargs <= LEFT_ARGS) return ARRAY_IDENTITY; // no args to fill; return the array unchanged // we need room for both mh and a in mh.invoke(a, arg*[nargs]) final int CHUNK = LEFT_ARGS; int rightLen = nargs % CHUNK; int midLen = nargs - rightLen; if (rightLen == 0) { midLen = nargs - (rightLen = CHUNK); if (FILL_ARRAY_TO_RIGHT[midLen] == null) { // build some precursors from left to right for (int j = LEFT_ARGS % CHUNK; j < midLen; j += CHUNK) if (j > LEFT_ARGS) fillToRight(j); } } if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS); assert (rightLen > 0); MethodHandle midFill = fillToRight(midLen); // recursive fill MethodHandle rightFill = FILL_ARRAYS[rightLen].bindTo(midLen); // [midLen..nargs-1] assert (midFill.type().parameterCount() == 1 + midLen - LEFT_ARGS); assert (rightFill.type().parameterCount() == 1 + rightLen); // Combine the two fills: // right(mid(a, x10..x19), x20..x23) // The final product will look like this: // right(mid(newArrayLeft(24, x0..x9), x10..x19), x20..x23) if (midLen == LEFT_ARGS) return rightFill; else return MethodHandles.collectArguments(rightFill, 0, midFill); } // Type-polymorphic version of varargs maker. private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS = new ClassValue<MethodHandle[]>() { @Override protected MethodHandle[] computeValue(Class<?> type) { return new MethodHandle[256]; } }; static final int MAX_JVM_ARITY = 255; // limit imposed by the JVM /** * Return a method handle that takes the indicated number of typed arguments and returns an array * of them. The type argument is the array type. */ public static MethodHandle varargsArray(Class<?> arrayType, int nargs) { Class<?> elemType = arrayType.getComponentType(); if (elemType == null) throw new IllegalArgumentException("not an array: " + arrayType); // FIXME: Need more special casing and caching here. if (nargs >= MAX_JVM_ARITY / 2 - 1) { int slots = nargs; final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1; // 1 for receiver MH if (arrayType == double[].class || arrayType == long[].class) slots *= 2; if (slots > MAX_ARRAY_SLOTS) throw new IllegalArgumentException( "too many arguments: " + arrayType.getSimpleName() + ", length " + nargs); } if (elemType == Object.class) return varargsArray(nargs); // other cases: primitive arrays, subtypes of Object[] MethodHandle cache[] = TYPED_COLLECTORS.get(elemType); MethodHandle mh = nargs < cache.length ? cache[nargs] : null; if (mh != null) return mh; if (elemType.isPrimitive()) { MethodHandle builder = FILL_NEW_ARRAY; MethodHandle producer = buildArrayProducer(arrayType); mh = buildVarargsArray(builder, producer, nargs); } else { @SuppressWarnings("unchecked") Class<? extends Object[]> objArrayType = (Class<? extends Object[]>) arrayType; Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType); MethodHandle builder = FILL_NEW_TYPED_ARRAY.bindTo(example); MethodHandle producer = ARRAY_IDENTITY; mh = buildVarargsArray(builder, producer, nargs); } mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType))); assert (assertCorrectArity(mh, nargs)); if (nargs < cache.length) cache[nargs] = mh; return mh; } private static MethodHandle buildArrayProducer(Class<?> arrayType) { Class<?> elemType = arrayType.getComponentType(); if (elemType.isPrimitive()) return LazyStatics.COPY_AS_PRIMITIVE_ARRAY.bindTo(Wrapper.forPrimitiveType(elemType)); else return LazyStatics.COPY_AS_REFERENCE_ARRAY.bindTo(arrayType); } // List version of varargs maker. private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY); private static List<Object> makeList(Object... args) { return Arrays.asList(args); } private static List<Object> list() { return NO_ARGS_LIST; } private static List<Object> list(Object a0) { return makeList(a0); } private static List<Object> list(Object a0, Object a1) { return makeList(a0, a1); } private static List<Object> list(Object a0, Object a1, Object a2) { return makeList(a0, a1, a2); } private static List<Object> list(Object a0, Object a1, Object a2, Object a3) { return makeList(a0, a1, a2, a3); } private static List<Object> list(Object a0, Object a1, Object a2, Object a3, Object a4) { return makeList(a0, a1, a2, a3, a4); } private static List<Object> list( Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return makeList(a0, a1, a2, a3, a4, a5); } private static List<Object> list( Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { return makeList(a0, a1, a2, a3, a4, a5, a6); } private static List<Object> list( Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { return makeList(a0, a1, a2, a3, a4, a5, a6, a7); } private static List<Object> list( Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8); } private static List<Object> list( Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); } private static MethodHandle[] makeLists() { ArrayList<MethodHandle> mhs = new ArrayList<>(); for (; ; ) { MethodHandle mh = findCollector("list", mhs.size(), List.class); if (mh == null) break; mhs.add(mh); } assert (mhs.size() == 11); // current number of methods return mhs.toArray(new MethodHandle[MAX_ARITY + 1]); } private static final MethodHandle[] LISTS = makeLists(); /** * Return a method handle that takes the indicated number of Object arguments and returns a List. */ public static MethodHandle varargsList(int nargs) { MethodHandle mh = LISTS[nargs]; if (mh != null) return mh; mh = findCollector("list", nargs, List.class); if (mh != null) return LISTS[nargs] = mh; return LISTS[nargs] = buildVarargsList(nargs); } private static MethodHandle buildVarargsList(int nargs) { return MethodHandles.filterReturnValue(varargsArray(nargs), LazyStatics.MAKE_LIST); } // handy shared exception makers (they simplify the common case code) private static InternalError newInternalError(String message, Throwable cause) { return new InternalError(message, cause); } private static InternalError newInternalError(Throwable cause) { return new InternalError(cause); } }
private static List<Object> makeList(Object... args) { return Arrays.asList(args); }
/** * Retrieves the update count for each update statement in the batch update that executed * successfully before this exception occurred. A driver that implements batch updates may or may * not continue to process the remaining commands in a batch when one of the commands fails to * execute properly. If the driver continues processing commands, the array returned by this * method will have as many elements as there are commands in the batch; otherwise, it will * contain an update count for each command that executed successfully before the <code> * BatchUpdateException</code> was thrown. * * <p>This method should be used when {@code Statement.executeLargeBatch} is invoked and the * returned update count may exceed {@link Integer#MAX_VALUE}. * * <p> * * @return an array of <code>long</code> containing the update counts for the updates that were * executed successfully before this error occurred. Or, if the driver continues to process * commands after an error, one of the following for every command in the batch: * <OL> * <LI>an update count * <LI><code>Statement.SUCCESS_NO_INFO</code> to indicate that the command executed * successfully but the number of rows affected is unknown * <LI><code>Statement.EXECUTE_FAILED</code> to indicate that the command failed to execute * successfully * </OL> * * @since 1.8 */ public long[] getLargeUpdateCounts() { return (longUpdateCounts == null) ? null : Arrays.copyOf(longUpdateCounts, longUpdateCounts.length); }
@Override public List<Era> eras() { return Arrays.<Era>asList(HijrahEra.values()); }
/** * Constructs a MessageToken from an InputStream. Bytes will be read on demand and the thread * might block if there are not enough bytes to complete the token. Please note there is no * accurate way to find out the size of a token, but we try our best to make sure there is enough * bytes to construct one. * * @param tokenId the token id that should be contained in this token as it is read. * @param context the Kerberos context associated with this token * @param is the InputStream from which to read * @param prop the MessageProp structure in which the properties of the token should be stored. * @throws GSSException if there is a problem reading from the InputStream or parsing the token */ MessageToken_v2(int tokenId, Krb5Context context, InputStream is, MessageProp prop) throws GSSException { init(tokenId, context); try { if (!confState) { prop.setPrivacy(false); } tokenHeader = new MessageTokenHeader(is, prop, tokenId); // set key_usage if (tokenId == Krb5Token.WRAP_ID_v2) { key_usage = (!initiator ? KG_USAGE_INITIATOR_SEAL : KG_USAGE_ACCEPTOR_SEAL); } else if (tokenId == Krb5Token.MIC_ID_v2) { key_usage = (!initiator ? KG_USAGE_INITIATOR_SIGN : KG_USAGE_ACCEPTOR_SIGN); } int minSize = 0; // minimal size for token data if (tokenId == Krb5Token.WRAP_ID_v2 && prop.getPrivacy()) { minSize = CONFOUNDER_SIZE + TOKEN_HEADER_SIZE + cipherHelper.getChecksumLength(); } else { minSize = cipherHelper.getChecksumLength(); } // Read token data if (tokenId == Krb5Token.MIC_ID_v2) { // The only case we can precisely predict the token data length tokenDataLen = minSize; tokenData = new byte[minSize]; readFully(is, tokenData); } else { tokenDataLen = is.available(); if (tokenDataLen >= minSize) { // read in one shot tokenData = new byte[tokenDataLen]; readFully(is, tokenData); } else { byte[] tmp = new byte[minSize]; readFully(is, tmp); // Hope while blocked in the read above, more data would // come and is.available() below contains the whole token. int more = is.available(); tokenDataLen = minSize + more; tokenData = Arrays.copyOf(tmp, tokenDataLen); readFully(is, tokenData, minSize, more); } } if (tokenId == Krb5Token.WRAP_ID_v2) { rotate(); } if (tokenId == Krb5Token.MIC_ID_v2 || (tokenId == Krb5Token.WRAP_ID_v2 && !prop.getPrivacy())) { // Read checksum int chkLen = cipherHelper.getChecksumLength(); checksum = new byte[chkLen]; System.arraycopy(tokenData, tokenDataLen - chkLen, checksum, 0, chkLen); // validate EC for Wrap tokens without confidentiality if (tokenId == Krb5Token.WRAP_ID_v2 && !prop.getPrivacy()) { if (chkLen != ec) { throw new GSSException( GSSException.DEFECTIVE_TOKEN, -1, getTokenName(tokenId) + ":" + "EC incorrect!"); } } } } catch (IOException e) { throw new GSSException( GSSException.DEFECTIVE_TOKEN, -1, getTokenName(tokenId) + ":" + e.getMessage()); } }
private static Object[] fillNewTypedArray( Object[] example, Integer len, Object[] /*not ...*/ args) { Object[] a = Arrays.copyOf(example, len); fillWithArguments(a, 0, args); return a; }
byte[] getData() { return Arrays.copyOf(data, data.length); }
private static Object[] copyAsReferenceArray(Class<? extends Object[]> arrayType, Object... a) { return Arrays.copyOf(a, a.length, arrayType); }
/** * Gets the valid offsets during this transition. * * <p>A gap will return an empty list, while an overlap will return both offsets. * * @return the list of valid offsets */ List<ZoneOffset> getValidOffsets() { if (isGap()) { return Collections.emptyList(); } return Arrays.asList(getOffsetBefore(), getOffsetAfter()); }
static byte[] genPad(byte b, int count) { byte[] padding = new byte[count]; Arrays.fill(padding, b); return padding; }