/** * Sole factory method to find or create an interned method type. * * @param rtype desired return type * @param ptypes desired parameter types * @param trusted whether the ptypes can be used without cloning * @return the unique method type of the desired structure */ /*trusted*/ static MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) { if (ptypes.length == 0) { ptypes = NO_PTYPES; trusted = true; } MethodType mt1 = new MethodType(rtype, ptypes); MethodType mt0; synchronized (internTable) { mt0 = internTable.get(mt1); if (mt0 != null) return mt0; } if (!trusted) // defensively copy the array passed in by the user mt1 = new MethodType(rtype, ptypes.clone()); // promote the object to the Real Thing, and reprobe MethodTypeForm form = MethodTypeForm.findForm(mt1); mt1.form = form; if (form.erasedType == mt1) { // This is a principal (erased) type; show it to the JVM. MethodHandleNatives.init(mt1); } synchronized (internTable) { mt0 = internTable.get(mt1); if (mt0 != null) return mt0; internTable.put(mt1, mt1); } return mt1; }
private static MethodType unwrapWithNoPrims(MethodType wt) { assert (!wt.hasPrimitives()); MethodType uwt = wt.wrapAlt; if (uwt == null) { // fill in lazily uwt = MethodTypeForm.canonicalize(wt, MethodTypeForm.UNWRAP, MethodTypeForm.UNWRAP); if (uwt == null) uwt = wt; // type has no wrappers or prims at all wt.wrapAlt = uwt; } return uwt; }
private static MethodType wrapWithPrims(MethodType pt) { assert (pt.hasPrimitives()); MethodType wt = pt.wrapAlt; if (wt == null) { // fill in lazily wt = MethodTypeForm.canonicalize(pt, MethodTypeForm.WRAP, MethodTypeForm.WRAP); assert (wt != null); pt.wrapAlt = wt; } return wt; }
/** * Reports the number of JVM stack slots required to receive a return value from a method of this * type. If the {@link #returnType() return type} is void, it will be zero, else if the return * type is long or double, it will be two, else one. * * <p>This method is included for the benfit of applications that must generate bytecodes that * process method handles and invokedynamic. * * @return the number of JVM stack slots (0, 1, or 2) for this type's return value Will be removed * for PFD. */ /*non-public*/ int returnSlotCount() { return form.returnSlotCount(); }
/** * Reports the number of JVM stack slots which carry all parameters including and after the given * position, which must be in the range of 0 to {@code parameterCount} inclusive. Successive * parameters are more shallowly stacked, and parameters are indexed in the bytecodes according to * their trailing edge. Thus, to obtain the depth in the outgoing call stack of parameter {@code * N}, obtain the {@code parameterSlotDepth} of its trailing edge at position {@code N+1}. * * <p>Parameters of type {@code long} and {@code double} occupy two stack slots (for historical * reasons) and all others occupy one. Therefore, the number returned is the number of arguments * <em>including</em> and <em>after</em> the given parameter, <em>plus</em> the number of long or * double arguments at or after after the argument for the given parameter. * * <p>This method is included for the benfit of applications that must generate bytecodes that * process method handles and invokedynamic. * * @param num an index (zero-based, inclusive) within the parameter types * @return the index of the (shallowest) JVM stack slot transmitting the given parameter * @throws IllegalArgumentException if {@code num} is negative or greater than {@code * parameterCount()} */ /*non-public*/ int parameterSlotDepth(int num) { if (num < 0 || num > ptypes.length) parameterType(num); // force a range check return form.parameterToArgSlot(num - 1); }
/** * Reports the number of JVM stack slots required to invoke a method of this type. Note that (for * historical reasons) the JVM requires a second stack slot to pass long and double arguments. So * this method returns {@link #parameterCount() parameterCount} plus the number of long and double * parameters (if any). * * <p>This method is included for the benfit of applications that must generate bytecodes that * process method handles and invokedynamic. * * @return the number of JVM stack slots for this type's parameters */ /*non-public*/ int parameterSlotCount() { return form.parameterSlotCount(); }
/** * Erases all reference types to {@code Object}. Convenience method for {@link * #methodType(java.lang.Class, java.lang.Class[]) methodType}. All primitive types (including * {@code void}) will remain unchanged. * * @return a version of the original type with all reference types replaced */ public MethodType erase() { return form.erasedType(); }
/** * Reports if this type contains a primitive argument or return value. The return type {@code * void} counts as a primitive. * * @return true if any of the types are primitives */ public boolean hasPrimitives() { return form.hasPrimitives(); }