926 |
926 |
927 static boolean isStaticallyInvocable(MemberName member) { |
927 static boolean isStaticallyInvocable(MemberName member) { |
928 if (member == null) return false; |
928 if (member == null) return false; |
929 if (member.isConstructor()) return false; |
929 if (member.isConstructor()) return false; |
930 Class<?> cls = member.getDeclaringClass(); |
930 Class<?> cls = member.getDeclaringClass(); |
|
931 // Fast-path non-private members declared by MethodHandles, which is a common |
|
932 // case |
|
933 if (MethodHandle.class.isAssignableFrom(cls) && !member.isPrivate()) { |
|
934 assert(isStaticallyInvocableType(member.getMethodOrFieldType())); |
|
935 return true; |
|
936 } |
931 if (cls.isArray() || cls.isPrimitive()) |
937 if (cls.isArray() || cls.isPrimitive()) |
932 return false; // FIXME |
938 return false; // FIXME |
933 if (cls.isAnonymousClass() || cls.isLocalClass()) |
939 if (cls.isAnonymousClass() || cls.isLocalClass()) |
934 return false; // inner class of some sort |
940 return false; // inner class of some sort |
935 if (cls.getClassLoader() != MethodHandle.class.getClassLoader()) |
941 if (cls.getClassLoader() != MethodHandle.class.getClassLoader()) |
936 return false; // not on BCP |
942 return false; // not on BCP |
937 if (ReflectUtil.isVMAnonymousClass(cls)) // FIXME: switch to supported API once it is added |
943 if (ReflectUtil.isVMAnonymousClass(cls)) // FIXME: switch to supported API once it is added |
938 return false; |
944 return false; |
939 MethodType mtype = member.getMethodOrFieldType(); |
945 if (!isStaticallyInvocableType(member.getMethodOrFieldType())) |
|
946 return false; |
|
947 if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls)) |
|
948 return true; // in java.lang.invoke package |
|
949 if (member.isPublic() && isStaticallyNameable(cls)) |
|
950 return true; |
|
951 return false; |
|
952 } |
|
953 |
|
954 private static boolean isStaticallyInvocableType(MethodType mtype) { |
940 if (!isStaticallyNameable(mtype.returnType())) |
955 if (!isStaticallyNameable(mtype.returnType())) |
941 return false; |
956 return false; |
942 for (Class<?> ptype : mtype.parameterArray()) |
957 for (Class<?> ptype : mtype.parameterArray()) |
943 if (!isStaticallyNameable(ptype)) |
958 if (!isStaticallyNameable(ptype)) |
944 return false; |
959 return false; |
945 if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls)) |
960 return true; |
946 return true; // in java.lang.invoke package |
|
947 if (member.isPublic() && isStaticallyNameable(cls)) |
|
948 return true; |
|
949 return false; |
|
950 } |
961 } |
951 |
962 |
952 static boolean isStaticallyNameable(Class<?> cls) { |
963 static boolean isStaticallyNameable(Class<?> cls) { |
953 if (cls == Object.class) |
964 if (cls == Object.class) |
954 return true; |
965 return true; |
|
966 if (MethodHandle.class.isAssignableFrom(cls)) { |
|
967 assert(!ReflectUtil.isVMAnonymousClass(cls)); |
|
968 return true; |
|
969 } |
955 while (cls.isArray()) |
970 while (cls.isArray()) |
956 cls = cls.getComponentType(); |
971 cls = cls.getComponentType(); |
957 if (cls.isPrimitive()) |
972 if (cls.isPrimitive()) |
958 return true; // int[].class, for example |
973 return true; // int[].class, for example |
959 if (ReflectUtil.isVMAnonymousClass(cls)) // FIXME: switch to supported API once it is added |
974 if (ReflectUtil.isVMAnonymousClass(cls)) // FIXME: switch to supported API once it is added |