Пример #1
0
 // Factory methods:
 static DirectMethodHandle make(byte refKind, Class<?> receiver, MemberName member) {
   MethodType mtype = member.getMethodOrFieldType();
   if (!member.isStatic()) {
     if (!member.getDeclaringClass().isAssignableFrom(receiver) || member.isConstructor())
       throw new InternalError(member.toString());
     mtype = mtype.insertParameterTypes(0, receiver);
   }
   if (!member.isField()) {
     if (refKind == REF_invokeSpecial) {
       member = member.asSpecial();
       LambdaForm lform = preparedLambdaForm(member);
       return new Special(mtype, lform, member);
     } else {
       LambdaForm lform = preparedLambdaForm(member);
       return new DirectMethodHandle(mtype, lform, member);
     }
   } else {
     LambdaForm lform = preparedFieldLambdaForm(member);
     if (member.isStatic()) {
       long offset = MethodHandleNatives.staticFieldOffset(member);
       Object base = MethodHandleNatives.staticFieldBase(member);
       return new StaticAccessor(mtype, lform, member, base, offset);
     } else {
       long offset = MethodHandleNatives.objectFieldOffset(member);
       assert (offset == (int) offset);
       return new Accessor(mtype, lform, member, (int) offset);
     }
   }
 }
Пример #2
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();
 }
Пример #3
0
 /**
  * Create a name for the given reflected method. The resulting name will be in a resolved state.
  */
 public MemberName(Method m) {
   Object[] typeInfo = {m.getReturnType(), m.getParameterTypes()};
   init(m.getDeclaringClass(), m.getName(), typeInfo, flagsMods(IS_METHOD, m.getModifiers()));
   // fill in vmtarget, vmindex while we have m in hand:
   MethodHandleNatives.init(this, m);
   assert (isResolved());
 }
Пример #4
0
 /**
  * Create a name for the given reflected field. The resulting name will be in a resolved state.
  */
 public MemberName(Field fld) {
   init(
       fld.getDeclaringClass(),
       fld.getName(),
       fld.getType(),
       flagsMods(IS_FIELD, fld.getModifiers()));
   // fill in vmtarget, vmindex while we have fld in hand:
   MethodHandleNatives.init(this, fld);
   assert (isResolved());
 }
Пример #5
0
 /**
  * Create a name for the given reflected constructor. The resulting name will be in a resolved
  * state.
  */
 public MemberName(Constructor ctor) {
   Object[] typeInfo = {void.class, ctor.getParameterTypes()};
   init(
       ctor.getDeclaringClass(),
       CONSTRUCTOR_NAME,
       typeInfo,
       flagsMods(IS_CONSTRUCTOR, ctor.getModifiers()));
   // fill in vmtarget, vmindex while we have ctor in hand:
   MethodHandleNatives.init(this, ctor);
   assert (isResolved());
 }
Пример #6
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;
 }
Пример #7
0
 private void expandFromVM() {
   if (!isResolved()) return;
   if (type instanceof Object[]) type = null; // don't saddle JVM w/ typeInfo
   MethodHandleNatives.expand(this);
 }