68 * allows invocation. A MemberName is much lighter than a Method, |
68 * allows invocation. A MemberName is much lighter than a Method, |
69 * since it contains about 7 fields to the 16 of Method (plus its sub-arrays), |
69 * since it contains about 7 fields to the 16 of Method (plus its sub-arrays), |
70 * and those seven fields omit much of the information in Method. |
70 * and those seven fields omit much of the information in Method. |
71 * @author jrose |
71 * @author jrose |
72 */ |
72 */ |
73 /*non-public*/ final class ResolvedMethodName { |
73 /*non-public*/ |
|
74 final class ResolvedMethodName { |
74 //@Injected JVM_Method* vmtarget; |
75 //@Injected JVM_Method* vmtarget; |
75 //@Injected Class<?> vmholder; |
76 //@Injected Class<?> vmholder; |
76 }; |
77 }; |
77 |
78 |
78 /*non-public*/ final class MemberName implements Member, Cloneable { |
79 /*non-public*/ |
|
80 final class MemberName implements Member, Cloneable { |
79 private Class<?> clazz; // class in which the member is defined |
81 private Class<?> clazz; // class in which the member is defined |
80 private String name; // may be null if not yet materialized |
82 private String name; // may be null if not yet materialized |
81 private Object type; // may be null if not yet materialized |
83 private Object type; // may be null if not yet materialized |
82 private int flags; // modifier bits; see reflect.Modifier |
84 private int flags; // modifier bits; see reflect.Modifier |
83 private ResolvedMethodName method; // cached resolved method information |
85 private ResolvedMethodName method; // cached resolved method information |
308 return true; |
310 return true; |
309 if (name.equals("equals") && mtype.returnType() == boolean.class && mtype.parameterCount() == 1 && mtype.parameterType(0) == Object.class) |
311 if (name.equals("equals") && mtype.returnType() == boolean.class && mtype.parameterCount() == 1 && mtype.parameterType(0) == Object.class) |
310 return true; |
312 return true; |
311 return false; |
313 return false; |
312 } |
314 } |
313 /*non-public*/ boolean referenceKindIsConsistentWith(int originalRefKind) { |
315 |
|
316 /*non-public*/ |
|
317 boolean referenceKindIsConsistentWith(int originalRefKind) { |
314 int refKind = getReferenceKind(); |
318 int refKind = getReferenceKind(); |
315 if (refKind == originalRefKind) return true; |
319 if (refKind == originalRefKind) return true; |
316 switch (originalRefKind) { |
320 switch (originalRefKind) { |
317 case REF_invokeInterface: |
321 case REF_invokeInterface: |
318 // Looking up an interface method, can get (e.g.) Object.hashCode |
322 // Looking up an interface method, can get (e.g.) Object.hashCode |
975 ex.initCause((Throwable) resolution); |
979 ex.initCause((Throwable) resolution); |
976 return ex; |
980 return ex; |
977 } |
981 } |
978 |
982 |
979 /** Actually making a query requires an access check. */ |
983 /** Actually making a query requires an access check. */ |
980 /*non-public*/ static Factory getFactory() { |
984 /*non-public*/ |
|
985 static Factory getFactory() { |
981 return Factory.INSTANCE; |
986 return Factory.INSTANCE; |
982 } |
987 } |
983 /** A factory type for resolving member names with the help of the VM. |
988 /** A factory type for resolving member names with the help of the VM. |
984 * TBD: Define access-safe public constructors for this factory. |
989 * TBD: Define access-safe public constructors for this factory. |
985 */ |
990 */ |
986 /*non-public*/ static class Factory { |
991 /*non-public*/ |
|
992 static class Factory { |
987 private Factory() { } // singleton pattern |
993 private Factory() { } // singleton pattern |
988 static Factory INSTANCE = new Factory(); |
994 static Factory INSTANCE = new Factory(); |
989 |
995 |
990 private static int ALLOWED_FLAGS = ALL_KINDS; |
996 private static int ALLOWED_FLAGS = ALL_KINDS; |
991 |
997 |
1096 * Super types are searched (for inherited members) if {@code searchSupers} is true. |
1102 * Super types are searched (for inherited members) if {@code searchSupers} is true. |
1097 * Access checking is performed on behalf of the given {@code lookupClass}. |
1103 * Access checking is performed on behalf of the given {@code lookupClass}. |
1098 * If lookup fails or access is not permitted, a {@linkplain ReflectiveOperationException} is thrown. |
1104 * If lookup fails or access is not permitted, a {@linkplain ReflectiveOperationException} is thrown. |
1099 * Otherwise a fresh copy of the given member is returned, with modifier bits filled in. |
1105 * Otherwise a fresh copy of the given member is returned, with modifier bits filled in. |
1100 */ |
1106 */ |
1101 public |
1107 public <NoSuchMemberException extends ReflectiveOperationException> |
1102 <NoSuchMemberException extends ReflectiveOperationException> |
1108 MemberName resolveOrFail(byte refKind, MemberName m, Class<?> lookupClass, |
1103 MemberName resolveOrFail(byte refKind, MemberName m, Class<?> lookupClass, |
|
1104 Class<NoSuchMemberException> nsmClass) |
1109 Class<NoSuchMemberException> nsmClass) |
1105 throws IllegalAccessException, NoSuchMemberException { |
1110 throws IllegalAccessException, NoSuchMemberException { |
1106 MemberName result = resolve(refKind, m, lookupClass, false); |
1111 MemberName result = resolve(refKind, m, lookupClass, false); |
1107 if (result.isResolved()) |
1112 if (result.isResolved()) |
1108 return result; |
1113 return result; |
1114 * Super types are searched (for inherited members) if {@code searchSupers} is true. |
1119 * Super types are searched (for inherited members) if {@code searchSupers} is true. |
1115 * Access checking is performed on behalf of the given {@code lookupClass}. |
1120 * Access checking is performed on behalf of the given {@code lookupClass}. |
1116 * If lookup fails or access is not permitted, return null. |
1121 * If lookup fails or access is not permitted, return null. |
1117 * Otherwise a fresh copy of the given member is returned, with modifier bits filled in. |
1122 * Otherwise a fresh copy of the given member is returned, with modifier bits filled in. |
1118 */ |
1123 */ |
1119 public |
1124 public MemberName resolveOrNull(byte refKind, MemberName m, Class<?> lookupClass) { |
1120 MemberName resolveOrNull(byte refKind, MemberName m, Class<?> lookupClass) { |
|
1121 MemberName result = resolve(refKind, m, lookupClass, true); |
1125 MemberName result = resolve(refKind, m, lookupClass, true); |
1122 if (result != null && result.isResolved()) |
1126 if (result != null && result.isResolved()) |
1123 return result; |
1127 return result; |
1124 return null; |
1128 return null; |
1125 } |
1129 } |