예제 #1
0
 /// Queries
 List<MemberName> getMembers(
     Class<?> defc, String matchName, Object matchType, int matchFlags, Class<?> lookupClass) {
   matchFlags &= ALLOWED_FLAGS;
   String matchSig = null;
   if (matchType != null) {
     matchSig = BytecodeDescriptor.unparse(matchType);
     if (matchSig.startsWith("(")) matchFlags &= ~(ALL_KINDS & ~IS_INVOCABLE);
     else matchFlags &= ~(ALL_KINDS & ~IS_FIELD);
   }
   final int BUF_MAX = 0x2000;
   int len1 = matchName == null ? 10 : matchType == null ? 4 : 1;
   MemberName[] buf = newMemberBuffer(len1);
   int totalCount = 0;
   ArrayList<MemberName[]> bufs = null;
   int bufCount = 0;
   for (; ; ) {
     bufCount =
         MethodHandleNatives.getMembers(
             defc, matchName, matchSig, matchFlags, lookupClass, totalCount, buf);
     if (bufCount <= buf.length) {
       if (bufCount < 0) bufCount = 0;
       totalCount += bufCount;
       break;
     }
     // JVM returned to us with an intentional overflow!
     totalCount += buf.length;
     int excess = bufCount - buf.length;
     if (bufs == null) bufs = new ArrayList<MemberName[]>(1);
     bufs.add(buf);
     int len2 = buf.length;
     len2 = Math.max(len2, excess);
     len2 = Math.max(len2, totalCount / 4);
     buf = newMemberBuffer(Math.min(BUF_MAX, len2));
   }
   ArrayList<MemberName> result = new ArrayList<MemberName>(totalCount);
   if (bufs != null) {
     for (MemberName[] buf0 : bufs) {
       Collections.addAll(result, buf0);
     }
   }
   result.addAll(Arrays.asList(buf).subList(0, bufCount));
   // Signature matching is not the same as type matching, since
   // one signature might correspond to several types.
   // So if matchType is a Class or MethodType, refilter the results.
   if (matchType != null && matchType != matchSig) {
     for (Iterator<MemberName> it = result.iterator(); it.hasNext(); ) {
       MemberName m = it.next();
       if (!matchType.equals(m.getType())) it.remove();
     }
   }
   return result;
 }
예제 #2
0
 /**
  * Produce a resolved version of the given member. Super types are searched (for inherited
  * members) if {@code searchSupers} is true. Access checking is performed on behalf of the given
  * {@code lookupClass}. If lookup fails or access is not permitted, a {@linkplain
  * ReflectiveOperationException} is thrown. Otherwise a fresh copy of the given member is
  * returned, with modifier bits filled in.
  */
 public <NoSuchMemberException extends ReflectiveOperationException> MemberName resolveOrFail(
     MemberName m,
     boolean searchSupers,
     Class<?> lookupClass,
     Class<NoSuchMemberException> nsmClass)
     throws IllegalAccessException, NoSuchMemberException {
   MemberName result = resolveOrNull(m, searchSupers, lookupClass);
   if (result != null) return result;
   ReflectiveOperationException ex = m.makeAccessException("no access");
   if (ex instanceof IllegalAccessException) throw (IllegalAccessException) ex;
   throw nsmClass.cast(ex);
 }
예제 #3
0
 /**
  * Produce a resolved version of the given member. Super types are searched (for inherited
  * members) if {@code searchSupers} is true. Access checking is performed on behalf of the given
  * {@code lookupClass}. If lookup fails or access is not permitted, null is returned. Otherwise
  * a fresh copy of the given member is returned, with modifier bits filled in.
  */
 public MemberName resolveOrNull(MemberName m, boolean searchSupers, Class<?> lookupClass) {
   MemberName result = m.clone();
   if (resolveInPlace(result, searchSupers, lookupClass)) return result;
   return null;
 }
예제 #4
0
 boolean resolveInPlace(MemberName m, boolean searchSupers, Class<?> lookupClass) {
   if (m.name == null || m.type == null) { // find unique non-overloaded name
     Class<?> defc = m.getDeclaringClass();
     List<MemberName> choices = null;
     if (m.isMethod())
       choices = getMethods(defc, searchSupers, m.name, (MethodType) m.type, lookupClass);
     else if (m.isConstructor()) choices = getConstructors(defc, lookupClass);
     else if (m.isField())
       choices = getFields(defc, searchSupers, m.name, (Class<?>) m.type, lookupClass);
     // System.out.println("resolving "+m+" to "+choices);
     if (choices == null || choices.size() != 1) return false;
     if (m.name == null) m.name = choices.get(0).name;
     if (m.type == null) m.type = choices.get(0).type;
   }
   MethodHandleNatives.resolve(m, lookupClass);
   if (m.isResolved()) return true;
   int matchFlags = m.flags | (searchSupers ? SEARCH_ALL_SUPERS : 0);
   String matchSig = m.getSignature();
   MemberName[] buf = {m};
   int n =
       MethodHandleNatives.getMembers(
           m.getDeclaringClass(), m.getName(), matchSig, matchFlags, lookupClass, 0, buf);
   if (n != 1) return false;
   return m.isResolved();
 }