--- old/src/java.base/share/classes/java/lang/constant/DirectMethodHandleDesc.java 2018-09-28 11:54:09.000000000 -0700 +++ new/src/java.base/share/classes/java/lang/constant/DirectMethodHandleDesc.java 2018-09-28 11:54:08.000000000 -0700 @@ -28,6 +28,8 @@ import java.lang.invoke.MethodHandleInfo; import java.lang.invoke.MethodHandles; +import jdk.internal.vm.annotation.Stable; + import static java.lang.invoke.MethodHandleInfo.REF_getField; import static java.lang.invoke.MethodHandleInfo.REF_getStatic; import static java.lang.invoke.MethodHandleInfo.REF_invokeInterface; @@ -89,6 +91,57 @@ } Kind(int refKind, boolean isInterface) { this.refKind = refKind; this.isInterface = isInterface; } + + /** + * Find the enumeration member with the given {@code refKind} field. + * More precisely, invoke {@code valueOf(refKind, false)}. + * @param refKind refKind of desired member + * @return the matching enumeration member + * @throws IllegalArgumentException if there is no such member + */ + public static Kind valueOf(int refKind) { + return valueOf(refKind, false); + } + + /** + * Find the enumeration member with the given {@code refKind} and + * {@code isInterface} fields. + * If {@code isInterface} is true and there is no such enumeration member, + * return the member, if any, with the same {@code refKind} and a false + * {@code isInterface} field. + * If {@code isInterface} is false and {@code refKind} is {@code REF_invokeInterface} + * return {@code INTERFACE_VIRTUAL}. + * @param refKind refKind of desired member + * @param isInterface whether desired member is for interface methods + * @return the matching enumeration member + * @throws IllegalArgumentException if there is no such member + */ + public static Kind valueOf(int refKind, boolean isInterface) { + int i = tableIndex(refKind, isInterface); + if (i >= 0 && i < TABLE.length) { + Kind kind = TABLE[i]; + if (kind.refKind == refKind && kind.isInterface == isInterface) { + return kind; + } + } + if (isInterface) return valueOf(refKind); + if (refKind == REF_invokeInterface) return INTERFACE_VIRTUAL; + throw new IllegalArgumentException("refKind="+refKind+(isInterface?"&isInterface":"")); + } + private static int tableIndex(int refKind, boolean isInterface) { + if (refKind < 0) return refKind; + return (refKind * 2) + (isInterface ? 1 : 0); + } + private static final @Stable Kind[] TABLE = new Kind[20]; + static { + // Pack the static table. + for (Kind kind : values()) { + int i = tableIndex(kind.refKind, kind.isInterface); + if (i >= TABLE.length || TABLE[i] != null) + throw new AssertionError("TABLE entry for "+kind); + TABLE[i] = kind; + } + } } /** * Return the {@code kind} of the method handle described by this nominal @@ -135,30 +188,4 @@ * @return the method type */ MethodTypeDesc methodType(); - - /** - * Create a {@linkplain DirectMethodHandleDesc} given descriptor strings - * for its components. Suitable for use as a constant bootstrap method - * for representing a {@linkplain DirectMethodHandleDesc} in the constant - * pool of a classfile. - * - * @param bsmKindName The name of an {@code enum} constant from {@link Kind} - * @param memberOwner A field type descriptor for the class declaring the - * method, field, or constructor, as per JVMS 4.3.2 - * @param memberName The name of the method or field, as per JVMS 4.2.2 - * @param memberType A method type descriptor for the method handle being - * described, as per JVMS 4.3.3 - * @return the {@linkplain MethodHandleDesc} - * @jvms 4.2.2 Unqualified Names - * @jvms 4.3.2 Field Descriptors - * @jvms 4.3.3 Method Descriptors - */ - static DirectMethodHandleDesc ofDescriptor(String bsmKindName, - String memberOwner, - String memberName, - String memberType) { - return MethodHandleDesc.of(Kind.valueOf(bsmKindName), - ClassDesc.ofDescriptor(memberOwner), memberName, - MethodTypeDesc.ofDescriptor(memberType)); - } }