1 /*
   2  * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import sun.invoke.util.BytecodeDescriptor;
  29 import sun.invoke.util.VerifyAccess;
  30 
  31 import java.lang.reflect.Constructor;
  32 import java.lang.reflect.Field;
  33 import java.lang.reflect.Method;
  34 import java.lang.reflect.Member;
  35 import java.lang.reflect.Modifier;
  36 import java.util.ArrayList;
  37 import java.util.Arrays;
  38 import java.util.Collections;
  39 import java.util.Iterator;
  40 import java.util.List;
  41 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  42 import static java.lang.invoke.MethodHandleStatics.*;
  43 import java.util.Objects;
  44 
  45 /**
  46  * A {@code MemberName} is a compact symbolic datum which fully characterizes
  47  * a method or field reference.
  48  * A member name refers to a field, method, constructor, or member type.
  49  * Every member name has a simple name (a string) and a type (either a Class or MethodType).
  50  * A member name may also have a non-null declaring class, or it may be simply
  51  * a naked name/type pair.
  52  * A member name may also have non-zero modifier flags.
  53  * Finally, a member name may be either resolved or unresolved.
  54  * If it is resolved, the existence of the named
  55  * <p>
  56  * Whether resolved or not, a member name provides no access rights or
  57  * invocation capability to its possessor.  It is merely a compact
  58  * representation of all symbolic information necessary to link to
  59  * and properly use the named member.
  60  * <p>
  61  * When resolved, a member name's internal implementation may include references to JVM metadata.
  62  * This representation is stateless and only descriptive.
  63  * It provides no private information and no capability to use the member.
  64  * <p>
  65  * By contrast, a {@linkplain java.lang.reflect.Method} contains fuller information
  66  * about the internals of a method (except its bytecodes) and also
  67  * allows invocation.  A MemberName is much lighter than a Method,
  68  * since it contains about 7 fields to the 16 of Method (plus its sub-arrays),
  69  * and those seven fields omit much of the information in Method.
  70  * @author jrose
  71  */
  72 /*non-public*/ final class MemberName implements Member, Cloneable {
  73     private Class<?> clazz;       // class in which the method is defined
  74     private String   name;        // may be null if not yet materialized
  75     private Object   type;        // may be null if not yet materialized
  76     private int      flags;       // modifier bits; see reflect.Modifier
  77     //@Injected JVM_Method* vmtarget;
  78     //@Injected int         vmindex;
  79     private Object   resolution;  // if null, this guy is resolved
  80 
  81 
  82     // The JVM uses values of -2 and above for vtable indexes.
  83     // Field values are simple positive offsets.
  84     // Ref: src/share/vm/oops/methodOop.hpp
  85     // This value is negative enough to avoid such numbers,
  86     // but not too negative.
  87     static final int
  88         MN_IS_METHOD           = 0x00010000, // method (not constructor)
  89         MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
  90         MN_IS_FIELD            = 0x00040000, // field
  91         MN_IS_TYPE             = 0x00080000, // nested type
  92         MN_CALLER_SENSITIVE    = 0x00100000, // @CallerSensitive annotation detected
  93         MN_REFERENCE_KIND_SHIFT = 24, // refKind
  94         MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
  95         // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
  96         MN_SEARCH_SUPERCLASSES = 0x00100000,
  97         MN_SEARCH_INTERFACES   = 0x00200000;
  98 
  99     /** Return the declaring class of this member.
 100      *  In the case of a bare name and type, the declaring class will be null.
 101      */
 102     public Class<?> getDeclaringClass() {
 103         return clazz;
 104     }
 105 
 106     /** Utility method producing the class loader of the declaring class. */
 107     public ClassLoader getClassLoader() {
 108         return clazz.getClassLoader();
 109     }
 110 
 111     /** Return the simple name of this member.
 112      *  For a type, it is the same as {@link Class#getSimpleName}.
 113      *  For a method or field, it is the simple name of the member.
 114      *  For a constructor, it is always {@code "&lt;init&gt;"}.
 115      */
 116     public String getName() {
 117         if (name == null) {
 118             expandFromVM();
 119             if (name == null) {
 120                 return null;
 121             }
 122         }
 123         return name;
 124     }
 125 
 126     public MethodType getMethodOrFieldType() {
 127         if (isInvocable())
 128             return getMethodType();
 129         if (isGetter())
 130             return MethodType.methodType(getFieldType());
 131         if (isSetter())
 132             return MethodType.methodType(void.class, getFieldType());
 133         throw new InternalError("not a method or field: "+this);
 134     }
 135 
 136     /** Return the declared type of this member, which
 137      *  must be a method or constructor.
 138      */
 139     public MethodType getMethodType() {
 140         if (type == null) {
 141             expandFromVM();
 142             if (type == null) {
 143                 return null;
 144             }
 145         }
 146         if (!isInvocable()) {
 147             throw newIllegalArgumentException("not invocable, no method type");
 148         }
 149 
 150         {
 151             // Get a snapshot of type which doesn't get changed by racing threads.
 152             final Object type = this.type;
 153             if (type instanceof MethodType) {
 154                 return (MethodType) type;
 155             }
 156         }
 157 
 158         // type is not a MethodType yet.  Convert it thread-safely.
 159         synchronized (this) {
 160             if (type instanceof String) {
 161                 String sig = (String) type;
 162                 MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader());
 163                 type = res;
 164             } else if (type instanceof Object[]) {
 165                 Object[] typeInfo = (Object[]) type;
 166                 Class<?>[] ptypes = (Class<?>[]) typeInfo[1];
 167                 Class<?> rtype = (Class<?>) typeInfo[0];
 168                 MethodType res = MethodType.methodType(rtype, ptypes);
 169                 type = res;
 170             }
 171             // Make sure type is a MethodType for racing threads.
 172             assert type instanceof MethodType : "bad method type " + type;
 173         }
 174         return (MethodType) type;
 175     }
 176 
 177     /** Return the actual type under which this method or constructor must be invoked.
 178      *  For non-static methods or constructors, this is the type with a leading parameter,
 179      *  a reference to declaring class.  For static methods, it is the same as the declared type.
 180      */
 181     public MethodType getInvocationType() {
 182         MethodType itype = getMethodOrFieldType();
 183         if (isConstructor() && getReferenceKind() == REF_newInvokeSpecial)
 184             return itype.changeReturnType(clazz);
 185         if (!isStatic())
 186             return itype.insertParameterTypes(0, clazz);
 187         return itype;
 188     }
 189 
 190     /** Utility method producing the parameter types of the method type. */
 191     public Class<?>[] getParameterTypes() {
 192         return getMethodType().parameterArray();
 193     }
 194 
 195     /** Utility method producing the return type of the method type. */
 196     public Class<?> getReturnType() {
 197         return getMethodType().returnType();
 198     }
 199 
 200     /** Return the declared type of this member, which
 201      *  must be a field or type.
 202      *  If it is a type member, that type itself is returned.
 203      */
 204     public Class<?> getFieldType() {
 205         if (type == null) {
 206             expandFromVM();
 207             if (type == null) {
 208                 return null;
 209             }
 210         }
 211         if (isInvocable()) {
 212             throw newIllegalArgumentException("not a field or nested class, no simple type");
 213         }
 214 
 215         {
 216             // Get a snapshot of type which doesn't get changed by racing threads.
 217             final Object type = this.type;
 218             if (type instanceof Class<?>) {
 219                 return (Class<?>) type;
 220             }
 221         }
 222 
 223         // type is not a Class yet.  Convert it thread-safely.
 224         synchronized (this) {
 225             if (type instanceof String) {
 226                 String sig = (String) type;
 227                 MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader());
 228                 Class<?> res = mtype.returnType();
 229                 type = res;
 230             }
 231             // Make sure type is a Class for racing threads.
 232             assert type instanceof Class<?> : "bad field type " + type;
 233         }
 234         return (Class<?>) type;
 235     }
 236 
 237     /** Utility method to produce either the method type or field type of this member. */
 238     public Object getType() {
 239         return (isInvocable() ? getMethodType() : getFieldType());
 240     }
 241 
 242     /** Utility method to produce the signature of this member,
 243      *  used within the class file format to describe its type.
 244      */
 245     public String getSignature() {
 246         if (type == null) {
 247             expandFromVM();
 248             if (type == null) {
 249                 return null;
 250             }
 251         }
 252         if (isInvocable())
 253             return BytecodeDescriptor.unparse(getMethodType());
 254         else
 255             return BytecodeDescriptor.unparse(getFieldType());
 256     }
 257 
 258     /** Return the modifier flags of this member.
 259      *  @see java.lang.reflect.Modifier
 260      */
 261     public int getModifiers() {
 262         return (flags & RECOGNIZED_MODIFIERS);
 263     }
 264 
 265     /** Return the reference kind of this member, or zero if none.
 266      */
 267     public byte getReferenceKind() {
 268         return (byte) ((flags >>> MN_REFERENCE_KIND_SHIFT) & MN_REFERENCE_KIND_MASK);
 269     }
 270     private boolean referenceKindIsConsistent() {
 271         byte refKind = getReferenceKind();
 272         if (refKind == REF_NONE)  return isType();
 273         if (isField()) {
 274             assert(staticIsConsistent());
 275             assert(MethodHandleNatives.refKindIsField(refKind));
 276         } else if (isConstructor()) {
 277             assert(refKind == REF_newInvokeSpecial || refKind == REF_invokeSpecial);
 278         } else if (isMethod()) {
 279             assert(staticIsConsistent());
 280             assert(MethodHandleNatives.refKindIsMethod(refKind));
 281             if (clazz.isInterface())
 282                 assert(refKind == REF_invokeInterface ||
 283                        refKind == REF_invokeStatic    ||
 284                        refKind == REF_invokeSpecial   ||
 285                        refKind == REF_invokeVirtual && isObjectPublicMethod());
 286         } else {
 287             assert(false);
 288         }
 289         return true;
 290     }
 291     private boolean isObjectPublicMethod() {
 292         if (clazz == Object.class)  return true;
 293         MethodType mtype = getMethodType();
 294         if (name.equals("toString") && mtype.returnType() == String.class && mtype.parameterCount() == 0)
 295             return true;
 296         if (name.equals("hashCode") && mtype.returnType() == int.class && mtype.parameterCount() == 0)
 297             return true;
 298         if (name.equals("equals") && mtype.returnType() == boolean.class && mtype.parameterCount() == 1 && mtype.parameterType(0) == Object.class)
 299             return true;
 300         return false;
 301     }
 302     /*non-public*/ boolean referenceKindIsConsistentWith(int originalRefKind) {
 303         int refKind = getReferenceKind();
 304         if (refKind == originalRefKind)  return true;
 305         switch (originalRefKind) {
 306         case REF_invokeInterface:
 307             // Looking up an interface method, can get (e.g.) Object.hashCode
 308             assert(refKind == REF_invokeVirtual ||
 309                    refKind == REF_invokeSpecial) : this;
 310             return true;
 311         case REF_invokeVirtual:
 312         case REF_newInvokeSpecial:
 313             // Looked up a virtual, can get (e.g.) final String.hashCode.
 314             assert(refKind == REF_invokeSpecial) : this;
 315             return true;
 316         }
 317         assert(false) : this+" != "+MethodHandleNatives.refKindName((byte)originalRefKind);
 318         return true;
 319     }
 320     private boolean staticIsConsistent() {
 321         byte refKind = getReferenceKind();
 322         return MethodHandleNatives.refKindIsStatic(refKind) == isStatic() || getModifiers() == 0;
 323     }
 324     private boolean vminfoIsConsistent() {
 325         byte refKind = getReferenceKind();
 326         assert(isResolved());  // else don't call
 327         Object vminfo = MethodHandleNatives.getMemberVMInfo(this);
 328         assert(vminfo instanceof Object[]);
 329         long vmindex = (Long) ((Object[])vminfo)[0];
 330         Object vmtarget = ((Object[])vminfo)[1];
 331         if (MethodHandleNatives.refKindIsField(refKind)) {
 332             assert(vmindex >= 0) : vmindex + ":" + this;
 333             assert(vmtarget instanceof Class);
 334         } else {
 335             if (MethodHandleNatives.refKindDoesDispatch(refKind))
 336                 assert(vmindex >= 0) : vmindex + ":" + this;
 337             else
 338                 assert(vmindex < 0) : vmindex;
 339             assert(vmtarget instanceof MemberName) : vmtarget + " in " + this;
 340         }
 341         return true;
 342     }
 343 
 344     private MemberName changeReferenceKind(byte refKind, byte oldKind) {
 345         assert(getReferenceKind() == oldKind);
 346         assert(MethodHandleNatives.refKindIsValid(refKind));
 347         flags += (((int)refKind - oldKind) << MN_REFERENCE_KIND_SHIFT);
 348         return this;
 349     }
 350 
 351     private boolean testFlags(int mask, int value) {
 352         return (flags & mask) == value;
 353     }
 354     private boolean testAllFlags(int mask) {
 355         return testFlags(mask, mask);
 356     }
 357     private boolean testAnyFlags(int mask) {
 358         return !testFlags(mask, 0);
 359     }
 360 
 361     /** Utility method to query if this member is a method handle invocation (invoke or invokeExact).
 362      *  Also returns true for the non-public MH.invokeBasic.
 363      */
 364     public boolean isMethodHandleInvoke() {
 365         final int bits = MH_INVOKE_MODS &~ Modifier.PUBLIC;
 366         final int negs = Modifier.STATIC;
 367         if (testFlags(bits | negs, bits) &&
 368             clazz == MethodHandle.class) {
 369             return isMethodHandleInvokeName(name);
 370         }
 371         return false;
 372     }
 373     public static boolean isMethodHandleInvokeName(String name) {
 374         switch (name) {
 375         case "invoke":
 376         case "invokeExact":
 377         case "invokeBasic":  // internal sig-poly method
 378             return true;
 379         default:
 380             return false;
 381         }
 382     }
 383     private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC;
 384 
 385     /** Utility method to query the modifier flags of this member. */
 386     public boolean isStatic() {
 387         return Modifier.isStatic(flags);
 388     }
 389     /** Utility method to query the modifier flags of this member. */
 390     public boolean isPublic() {
 391         return Modifier.isPublic(flags);
 392     }
 393     /** Utility method to query the modifier flags of this member. */
 394     public boolean isPrivate() {
 395         return Modifier.isPrivate(flags);
 396     }
 397     /** Utility method to query the modifier flags of this member. */
 398     public boolean isProtected() {
 399         return Modifier.isProtected(flags);
 400     }
 401     /** Utility method to query the modifier flags of this member. */
 402     public boolean isFinal() {
 403         return Modifier.isFinal(flags);
 404     }
 405     /** Utility method to query whether this member or its defining class is final. */
 406     public boolean canBeStaticallyBound() {
 407         return Modifier.isFinal(flags | clazz.getModifiers());
 408     }
 409     /** Utility method to query the modifier flags of this member. */
 410     public boolean isVolatile() {
 411         return Modifier.isVolatile(flags);
 412     }
 413     /** Utility method to query the modifier flags of this member. */
 414     public boolean isAbstract() {
 415         return Modifier.isAbstract(flags);
 416     }
 417     /** Utility method to query the modifier flags of this member. */
 418     public boolean isNative() {
 419         return Modifier.isNative(flags);
 420     }
 421     // let the rest (native, volatile, transient, etc.) be tested via Modifier.isFoo
 422 
 423     // unofficial modifier flags, used by HotSpot:
 424     static final int BRIDGE    = 0x00000040;
 425     static final int VARARGS   = 0x00000080;
 426     static final int SYNTHETIC = 0x00001000;
 427     static final int ANNOTATION= 0x00002000;
 428     static final int ENUM      = 0x00004000;
 429     /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
 430     public boolean isBridge() {
 431         return testAllFlags(IS_METHOD | BRIDGE);
 432     }
 433     /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
 434     public boolean isVarargs() {
 435         return testAllFlags(VARARGS) && isInvocable();
 436     }
 437     /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
 438     public boolean isSynthetic() {
 439         return testAllFlags(SYNTHETIC);
 440     }
 441 
 442     static final String CONSTRUCTOR_NAME = "<init>";  // the ever-popular
 443 
 444     // modifiers exported by the JVM:
 445     static final int RECOGNIZED_MODIFIERS = 0xFFFF;
 446 
 447     // private flags, not part of RECOGNIZED_MODIFIERS:
 448     static final int
 449             IS_METHOD        = MN_IS_METHOD,        // method (not constructor)
 450             IS_CONSTRUCTOR   = MN_IS_CONSTRUCTOR,   // constructor
 451             IS_FIELD         = MN_IS_FIELD,         // field
 452             IS_TYPE          = MN_IS_TYPE,          // nested type
 453             CALLER_SENSITIVE = MN_CALLER_SENSITIVE; // @CallerSensitive annotation detected
 454 
 455     static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
 456     static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE;
 457     static final int IS_INVOCABLE = IS_METHOD | IS_CONSTRUCTOR;
 458     static final int IS_FIELD_OR_METHOD = IS_METHOD | IS_FIELD;
 459     static final int SEARCH_ALL_SUPERS = MN_SEARCH_SUPERCLASSES | MN_SEARCH_INTERFACES;
 460 
 461     /** Utility method to query whether this member is a method or constructor. */
 462     public boolean isInvocable() {
 463         return testAnyFlags(IS_INVOCABLE);
 464     }
 465     /** Utility method to query whether this member is a method, constructor, or field. */
 466     public boolean isFieldOrMethod() {
 467         return testAnyFlags(IS_FIELD_OR_METHOD);
 468     }
 469     /** Query whether this member is a method. */
 470     public boolean isMethod() {
 471         return testAllFlags(IS_METHOD);
 472     }
 473     /** Query whether this member is a constructor. */
 474     public boolean isConstructor() {
 475         return testAllFlags(IS_CONSTRUCTOR);
 476     }
 477     /** Query whether this member is a field. */
 478     public boolean isField() {
 479         return testAllFlags(IS_FIELD);
 480     }
 481     /** Query whether this member is a type. */
 482     public boolean isType() {
 483         return testAllFlags(IS_TYPE);
 484     }
 485     /** Utility method to query whether this member is neither public, private, nor protected. */
 486     public boolean isPackage() {
 487         return !testAnyFlags(ALL_ACCESS);
 488     }
 489     /** Query whether this member has a CallerSensitive annotation. */
 490     public boolean isCallerSensitive() {
 491         return testAllFlags(CALLER_SENSITIVE);
 492     }
 493 
 494     /** Utility method to query whether this member is accessible from a given lookup class. */
 495     public boolean isAccessibleFrom(Class<?> lookupClass) {
 496         return VerifyAccess.isMemberAccessible(this.getDeclaringClass(), this.getDeclaringClass(), flags,
 497                                                lookupClass, ALL_ACCESS|MethodHandles.Lookup.PACKAGE);
 498     }
 499 
 500     /** Initialize a query.   It is not resolved. */
 501     private void init(Class<?> defClass, String name, Object type, int flags) {
 502         // defining class is allowed to be null (for a naked name/type pair)
 503         //name.toString();  // null check
 504         //type.equals(type);  // null check
 505         // fill in fields:
 506         this.clazz = defClass;
 507         this.name = name;
 508         this.type = type;
 509         this.flags = flags;
 510         assert(testAnyFlags(ALL_KINDS));
 511         assert(this.resolution == null);  // nobody should have touched this yet
 512         //assert(referenceKindIsConsistent());  // do this after resolution
 513     }
 514 
 515     /**
 516      * Calls down to the VM to fill in the fields.  This method is
 517      * synchronized to avoid racing calls.
 518      */
 519     private void expandFromVM() {
 520         if (type != null) {
 521             return;
 522         }
 523         if (!isResolved()) {
 524             return;
 525         }
 526         MethodHandleNatives.expand(this);
 527     }
 528 
 529     // Capturing information from the Core Reflection API:
 530     private static int flagsMods(int flags, int mods, byte refKind) {
 531         assert((flags & RECOGNIZED_MODIFIERS) == 0);
 532         assert((mods & ~RECOGNIZED_MODIFIERS) == 0);
 533         assert((refKind & ~MN_REFERENCE_KIND_MASK) == 0);
 534         return flags | mods | (refKind << MN_REFERENCE_KIND_SHIFT);
 535     }
 536     /** Create a name for the given reflected method.  The resulting name will be in a resolved state. */
 537     public MemberName(Method m) {
 538         this(m, false);
 539     }
 540     @SuppressWarnings("LeakingThisInConstructor")
 541     public MemberName(Method m, boolean wantSpecial) {
 542         Objects.requireNonNull(m);
 543         // fill in vmtarget, vmindex while we have m in hand:
 544         MethodHandleNatives.init(this, m);
 545         if (clazz == null) {  // MHN.init failed
 546             if (m.getDeclaringClass() == MethodHandle.class &&
 547                 isMethodHandleInvokeName(m.getName())) {
 548                 // The JVM did not reify this signature-polymorphic instance.
 549                 // Need a special case here.
 550                 // See comments on MethodHandleNatives.linkMethod.
 551                 MethodType type = MethodType.methodType(m.getReturnType(), m.getParameterTypes());
 552                 int flags = flagsMods(IS_METHOD, m.getModifiers(), REF_invokeVirtual);
 553                 init(MethodHandle.class, m.getName(), type, flags);
 554                 if (isMethodHandleInvoke())
 555                     return;
 556             }
 557             throw new LinkageError(m.toString());
 558         }
 559         assert(isResolved() && this.clazz != null);
 560         this.name = m.getName();
 561         if (this.type == null)
 562             this.type = new Object[] { m.getReturnType(), m.getParameterTypes() };
 563         if (wantSpecial) {
 564             if (isAbstract())
 565                 throw new AbstractMethodError(this.toString());
 566             if (getReferenceKind() == REF_invokeVirtual)
 567                 changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
 568             else if (getReferenceKind() == REF_invokeInterface)
 569                 // invokeSpecial on a default method
 570                 changeReferenceKind(REF_invokeSpecial, REF_invokeInterface);
 571         }
 572     }
 573     public MemberName asSpecial() {
 574         switch (getReferenceKind()) {
 575         case REF_invokeSpecial:     return this;
 576         case REF_invokeVirtual:     return clone().changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
 577         case REF_invokeInterface:   return clone().changeReferenceKind(REF_invokeSpecial, REF_invokeInterface);
 578         case REF_newInvokeSpecial:  return clone().changeReferenceKind(REF_invokeSpecial, REF_newInvokeSpecial);
 579         }
 580         throw new IllegalArgumentException(this.toString());
 581     }
 582     /** If this MN is not REF_newInvokeSpecial, return a clone with that ref. kind.
 583      *  In that case it must already be REF_invokeSpecial.
 584      */
 585     public MemberName asConstructor() {
 586         switch (getReferenceKind()) {
 587         case REF_invokeSpecial:     return clone().changeReferenceKind(REF_newInvokeSpecial, REF_invokeSpecial);
 588         case REF_newInvokeSpecial:  return this;
 589         }
 590         throw new IllegalArgumentException(this.toString());
 591     }
 592     /** If this MN is a REF_invokeSpecial, return a clone with the "normal" kind
 593      *  REF_invokeVirtual; also switch either to REF_invokeInterface if clazz.isInterface.
 594      *  The end result is to get a fully virtualized version of the MN.
 595      *  (Note that resolving in the JVM will sometimes devirtualize, changing
 596      *  REF_invokeVirtual of a final to REF_invokeSpecial, and REF_invokeInterface
 597      *  in some corner cases to either of the previous two; this transform
 598      *  undoes that change under the assumption that it occurred.)
 599      */
 600     public MemberName asNormalOriginal() {
 601         byte normalVirtual = clazz.isInterface() ? REF_invokeInterface : REF_invokeVirtual;
 602         byte refKind = getReferenceKind();
 603         byte newRefKind = refKind;
 604         MemberName result = this;
 605         switch (refKind) {
 606         case REF_invokeInterface:
 607         case REF_invokeVirtual:
 608         case REF_invokeSpecial:
 609             newRefKind = normalVirtual;
 610             break;
 611         }
 612         if (newRefKind == refKind)
 613             return this;
 614         result = clone().changeReferenceKind(newRefKind, refKind);
 615         assert(this.referenceKindIsConsistentWith(result.getReferenceKind()));
 616         return result;
 617     }
 618     /** Create a name for the given reflected constructor.  The resulting name will be in a resolved state. */
 619     @SuppressWarnings("LeakingThisInConstructor")
 620     public MemberName(Constructor<?> ctor) {
 621         Objects.requireNonNull(ctor);
 622         // fill in vmtarget, vmindex while we have ctor in hand:
 623         MethodHandleNatives.init(this, ctor);
 624         assert(isResolved() && this.clazz != null);
 625         this.name = CONSTRUCTOR_NAME;
 626         if (this.type == null)
 627             this.type = new Object[] { void.class, ctor.getParameterTypes() };
 628     }
 629     /** Create a name for the given reflected field.  The resulting name will be in a resolved state.
 630      */
 631     public MemberName(Field fld) {
 632         this(fld, false);
 633     }
 634     @SuppressWarnings("LeakingThisInConstructor")
 635     public MemberName(Field fld, boolean makeSetter) {
 636         Objects.requireNonNull(fld);
 637         // fill in vmtarget, vmindex while we have fld in hand:
 638         MethodHandleNatives.init(this, fld);
 639         assert(isResolved() && this.clazz != null);
 640         this.name = fld.getName();
 641         this.type = fld.getType();
 642         assert((REF_putStatic - REF_getStatic) == (REF_putField - REF_getField));
 643         byte refKind = this.getReferenceKind();
 644         assert(refKind == (isStatic() ? REF_getStatic : REF_getField));
 645         if (makeSetter) {
 646             changeReferenceKind((byte)(refKind + (REF_putStatic - REF_getStatic)), refKind);
 647         }
 648     }
 649     public boolean isGetter() {
 650         return MethodHandleNatives.refKindIsGetter(getReferenceKind());
 651     }
 652     public boolean isSetter() {
 653         return MethodHandleNatives.refKindIsSetter(getReferenceKind());
 654     }
 655     public MemberName asSetter() {
 656         byte refKind = getReferenceKind();
 657         assert(MethodHandleNatives.refKindIsGetter(refKind));
 658         assert((REF_putStatic - REF_getStatic) == (REF_putField - REF_getField));
 659         byte setterRefKind = (byte)(refKind + (REF_putField - REF_getField));
 660         return clone().changeReferenceKind(setterRefKind, refKind);
 661     }
 662     /** Create a name for the given class.  The resulting name will be in a resolved state. */
 663     public MemberName(Class<?> type) {
 664         init(type.getDeclaringClass(), type.getSimpleName(), type,
 665                 flagsMods(IS_TYPE, type.getModifiers(), REF_NONE));
 666         initResolved(true);
 667     }
 668 
 669     /**
 670      * Create a name for a signature-polymorphic invoker.
 671      * This is a placeholder for a signature-polymorphic instance
 672      * (of MH.invokeExact, etc.) that the JVM does not reify.
 673      * See comments on {@link MethodHandleNatives#linkMethod}.
 674      */
 675     static MemberName makeMethodHandleInvoke(String name, MethodType type) {
 676         return makeMethodHandleInvoke(name, type, MH_INVOKE_MODS | SYNTHETIC);
 677     }
 678     static MemberName makeMethodHandleInvoke(String name, MethodType type, int mods) {
 679         MemberName mem = new MemberName(MethodHandle.class, name, type, REF_invokeVirtual);
 680         mem.flags |= mods;  // it's not resolved, but add these modifiers anyway
 681         assert(mem.isMethodHandleInvoke()) : mem;
 682         return mem;
 683     }
 684 
 685     // bare-bones constructor; the JVM will fill it in
 686     MemberName() { }
 687 
 688     // locally useful cloner
 689     @Override protected MemberName clone() {
 690         try {
 691             return (MemberName) super.clone();
 692         } catch (CloneNotSupportedException ex) {
 693             throw newInternalError(ex);
 694         }
 695      }
 696 
 697     /** Get the definition of this member name.
 698      *  This may be in a super-class of the declaring class of this member.
 699      */
 700     public MemberName getDefinition() {
 701         if (!isResolved())  throw new IllegalStateException("must be resolved: "+this);
 702         if (isType())  return this;
 703         MemberName res = this.clone();
 704         res.clazz = null;
 705         res.type = null;
 706         res.name = null;
 707         res.resolution = res;
 708         res.expandFromVM();
 709         assert(res.getName().equals(this.getName()));
 710         return res;
 711     }
 712 
 713     @Override
 714     public int hashCode() {
 715         return Objects.hash(clazz, getReferenceKind(), name, getType());
 716     }
 717     @Override
 718     public boolean equals(Object that) {
 719         return (that instanceof MemberName && this.equals((MemberName)that));
 720     }
 721 
 722     /** Decide if two member names have exactly the same symbolic content.
 723      *  Does not take into account any actual class members, so even if
 724      *  two member names resolve to the same actual member, they may
 725      *  be distinct references.
 726      */
 727     public boolean equals(MemberName that) {
 728         if (this == that)  return true;
 729         if (that == null)  return false;
 730         return this.clazz == that.clazz
 731                 && this.getReferenceKind() == that.getReferenceKind()
 732                 && Objects.equals(this.name, that.name)
 733                 && Objects.equals(this.getType(), that.getType());
 734     }
 735 
 736     // Construction from symbolic parts, for queries:
 737     /** Create a field or type name from the given components:
 738      *  Declaring class, name, type, reference kind.
 739      *  The declaring class may be supplied as null if this is to be a bare name and type.
 740      *  The resulting name will in an unresolved state.
 741      */
 742     public MemberName(Class<?> defClass, String name, Class<?> type, byte refKind) {
 743         init(defClass, name, type, flagsMods(IS_FIELD, 0, refKind));
 744         initResolved(false);
 745     }
 746     /** Create a method or constructor name from the given components:
 747      *  Declaring class, name, type, reference kind.
 748      *  It will be a constructor if and only if the name is {@code "&lt;init&gt;"}.
 749      *  The declaring class may be supplied as null if this is to be a bare name and type.
 750      *  The last argument is optional, a boolean which requests REF_invokeSpecial.
 751      *  The resulting name will in an unresolved state.
 752      */
 753     public MemberName(Class<?> defClass, String name, MethodType type, byte refKind) {
 754         int initFlags = (name != null && name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD);
 755         init(defClass, name, type, flagsMods(initFlags, 0, refKind));
 756         initResolved(false);
 757     }
 758     /** Create a method, constructor, or field name from the given components:
 759      *  Reference kind, declaring class, name, type.
 760      */
 761     public MemberName(byte refKind, Class<?> defClass, String name, Object type) {
 762         int kindFlags;
 763         if (MethodHandleNatives.refKindIsField(refKind)) {
 764             kindFlags = IS_FIELD;
 765             if (!(type instanceof Class))
 766                 throw newIllegalArgumentException("not a field type");
 767         } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
 768             kindFlags = IS_METHOD;
 769             if (!(type instanceof MethodType))
 770                 throw newIllegalArgumentException("not a method type");
 771         } else if (refKind == REF_newInvokeSpecial) {
 772             kindFlags = IS_CONSTRUCTOR;
 773             if (!(type instanceof MethodType) ||
 774                 !CONSTRUCTOR_NAME.equals(name))
 775                 throw newIllegalArgumentException("not a constructor type or name");
 776         } else {
 777             throw newIllegalArgumentException("bad reference kind "+refKind);
 778         }
 779         init(defClass, name, type, flagsMods(kindFlags, 0, refKind));
 780         initResolved(false);
 781     }
 782     /** Query whether this member name is resolved to a non-static, non-final method.
 783      */
 784     public boolean hasReceiverTypeDispatch() {
 785         return MethodHandleNatives.refKindDoesDispatch(getReferenceKind());
 786     }
 787 
 788     /** Query whether this member name is resolved.
 789      *  A resolved member name is one for which the JVM has found
 790      *  a method, constructor, field, or type binding corresponding exactly to the name.
 791      *  (Document?)
 792      */
 793     public boolean isResolved() {
 794         return resolution == null;
 795     }
 796 
 797     private void initResolved(boolean isResolved) {
 798         assert(this.resolution == null);  // not initialized yet!
 799         if (!isResolved)
 800             this.resolution = this;
 801         assert(isResolved() == isResolved);
 802     }
 803 
 804     void checkForTypeAlias() {
 805         if (isInvocable()) {
 806             MethodType type;
 807             if (this.type instanceof MethodType)
 808                 type = (MethodType) this.type;
 809             else
 810                 this.type = type = getMethodType();
 811             if (type.erase() == type)  return;
 812             if (VerifyAccess.isTypeVisible(type, clazz))  return;
 813             throw new LinkageError("bad method type alias: "+type+" not visible from "+clazz);
 814         } else {
 815             Class<?> type;
 816             if (this.type instanceof Class<?>)
 817                 type = (Class<?>) this.type;
 818             else
 819                 this.type = type = getFieldType();
 820             if (VerifyAccess.isTypeVisible(type, clazz))  return;
 821             throw new LinkageError("bad field type alias: "+type+" not visible from "+clazz);
 822         }
 823     }
 824 
 825 
 826     /** Produce a string form of this member name.
 827      *  For types, it is simply the type's own string (as reported by {@code toString}).
 828      *  For fields, it is {@code "DeclaringClass.name/type"}.
 829      *  For methods and constructors, it is {@code "DeclaringClass.name(ptype...)rtype"}.
 830      *  If the declaring class is null, the prefix {@code "DeclaringClass."} is omitted.
 831      *  If the member is unresolved, a prefix {@code "*."} is prepended.
 832      */
 833     @SuppressWarnings("LocalVariableHidesMemberVariable")
 834     @Override
 835     public String toString() {
 836         if (isType())
 837             return type.toString();  // class java.lang.String
 838         // else it is a field, method, or constructor
 839         StringBuilder buf = new StringBuilder();
 840         if (getDeclaringClass() != null) {
 841             buf.append(getName(clazz));
 842             buf.append('.');
 843         }
 844         String name = getName();
 845         buf.append(name == null ? "*" : name);
 846         Object type = getType();
 847         if (!isInvocable()) {
 848             buf.append('/');
 849             buf.append(type == null ? "*" : getName(type));
 850         } else {
 851             buf.append(type == null ? "(*)*" : getName(type));
 852         }
 853         byte refKind = getReferenceKind();
 854         if (refKind != REF_NONE) {
 855             buf.append('/');
 856             buf.append(MethodHandleNatives.refKindName(refKind));
 857         }
 858         //buf.append("#").append(System.identityHashCode(this));
 859         return buf.toString();
 860     }
 861     private static String getName(Object obj) {
 862         if (obj instanceof Class<?>)
 863             return ((Class<?>)obj).getName();
 864         return String.valueOf(obj);
 865     }
 866 
 867     public IllegalAccessException makeAccessException(String message, Object from) {
 868         message = message + ": "+ toString();
 869         if (from != null)  message += ", from " + from;
 870         return new IllegalAccessException(message);
 871     }
 872     private String message() {
 873         if (isResolved())
 874             return "no access";
 875         else if (isConstructor())
 876             return "no such constructor";
 877         else if (isMethod())
 878             return "no such method";
 879         else
 880             return "no such field";
 881     }
 882     public ReflectiveOperationException makeAccessException() {
 883         String message = message() + ": "+ toString();
 884         ReflectiveOperationException ex;
 885         if (isResolved() || !(resolution instanceof NoSuchMethodError ||
 886                               resolution instanceof NoSuchFieldError))
 887             ex = new IllegalAccessException(message);
 888         else if (isConstructor())
 889             ex = new NoSuchMethodException(message);
 890         else if (isMethod())
 891             ex = new NoSuchMethodException(message);
 892         else
 893             ex = new NoSuchFieldException(message);
 894         if (resolution instanceof Throwable)
 895             ex.initCause((Throwable) resolution);
 896         return ex;
 897     }
 898 
 899     /** Actually making a query requires an access check. */
 900     /*non-public*/ static Factory getFactory() {
 901         return Factory.INSTANCE;
 902     }
 903     /** A factory type for resolving member names with the help of the VM.
 904      *  TBD: Define access-safe public constructors for this factory.
 905      */
 906     /*non-public*/ static class Factory {
 907         private Factory() { } // singleton pattern
 908         static Factory INSTANCE = new Factory();
 909 
 910         private static int ALLOWED_FLAGS = ALL_KINDS;
 911 
 912         /// Queries
 913         List<MemberName> getMembers(Class<?> defc,
 914                 String matchName, Object matchType,
 915                 int matchFlags, Class<?> lookupClass) {
 916             matchFlags &= ALLOWED_FLAGS;
 917             String matchSig = null;
 918             if (matchType != null) {
 919                 matchSig = BytecodeDescriptor.unparse(matchType);
 920                 if (matchSig.startsWith("("))
 921                     matchFlags &= ~(ALL_KINDS & ~IS_INVOCABLE);
 922                 else
 923                     matchFlags &= ~(ALL_KINDS & ~IS_FIELD);
 924             }
 925             final int BUF_MAX = 0x2000;
 926             int len1 = matchName == null ? 10 : matchType == null ? 4 : 1;
 927             MemberName[] buf = newMemberBuffer(len1);
 928             int totalCount = 0;
 929             ArrayList<MemberName[]> bufs = null;
 930             int bufCount = 0;
 931             for (;;) {
 932                 bufCount = MethodHandleNatives.getMembers(defc,
 933                         matchName, matchSig, matchFlags,
 934                         lookupClass,
 935                         totalCount, buf);
 936                 if (bufCount <= buf.length) {
 937                     if (bufCount < 0)  bufCount = 0;
 938                     totalCount += bufCount;
 939                     break;
 940                 }
 941                 // JVM returned to us with an intentional overflow!
 942                 totalCount += buf.length;
 943                 int excess = bufCount - buf.length;
 944                 if (bufs == null)  bufs = new ArrayList<>(1);
 945                 bufs.add(buf);
 946                 int len2 = buf.length;
 947                 len2 = Math.max(len2, excess);
 948                 len2 = Math.max(len2, totalCount / 4);
 949                 buf = newMemberBuffer(Math.min(BUF_MAX, len2));
 950             }
 951             ArrayList<MemberName> result = new ArrayList<>(totalCount);
 952             if (bufs != null) {
 953                 for (MemberName[] buf0 : bufs) {
 954                     Collections.addAll(result, buf0);
 955                 }
 956             }
 957             result.addAll(Arrays.asList(buf).subList(0, bufCount));
 958             // Signature matching is not the same as type matching, since
 959             // one signature might correspond to several types.
 960             // So if matchType is a Class or MethodType, refilter the results.
 961             if (matchType != null && matchType != matchSig) {
 962                 for (Iterator<MemberName> it = result.iterator(); it.hasNext();) {
 963                     MemberName m = it.next();
 964                     if (!matchType.equals(m.getType()))
 965                         it.remove();
 966                 }
 967             }
 968             return result;
 969         }
 970         /** Produce a resolved version of the given member.
 971          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
 972          *  Access checking is performed on behalf of the given {@code lookupClass}.
 973          *  If lookup fails or access is not permitted, null is returned.
 974          *  Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
 975          */
 976         private MemberName resolve(byte refKind, MemberName ref, Class<?> lookupClass) {
 977             MemberName m = ref.clone();  // JVM will side-effect the ref
 978             assert(refKind == m.getReferenceKind());
 979             try {
 980                 m = MethodHandleNatives.resolve(m, lookupClass);
 981                 m.checkForTypeAlias();
 982                 m.resolution = null;
 983             } catch (LinkageError ex) {
 984                 // JVM reports that the "bytecode behavior" would get an error
 985                 assert(!m.isResolved());
 986                 m.resolution = ex;
 987                 return m;
 988             }
 989             assert(m.referenceKindIsConsistent());
 990             m.initResolved(true);
 991             assert(m.vminfoIsConsistent());
 992             return m;
 993         }
 994         /** Produce a resolved version of the given member.
 995          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
 996          *  Access checking is performed on behalf of the given {@code lookupClass}.
 997          *  If lookup fails or access is not permitted, a {@linkplain ReflectiveOperationException} is thrown.
 998          *  Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
 999          */
1000         public
1001         <NoSuchMemberException extends ReflectiveOperationException>
1002         MemberName resolveOrFail(byte refKind, MemberName m, Class<?> lookupClass,
1003                                  Class<NoSuchMemberException> nsmClass)
1004                 throws IllegalAccessException, NoSuchMemberException {
1005             MemberName result = resolve(refKind, m, lookupClass);
1006             if (result.isResolved())
1007                 return result;
1008             ReflectiveOperationException ex = result.makeAccessException();
1009             if (ex instanceof IllegalAccessException)  throw (IllegalAccessException) ex;
1010             throw nsmClass.cast(ex);
1011         }
1012         /** Produce a resolved version of the given member.
1013          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1014          *  Access checking is performed on behalf of the given {@code lookupClass}.
1015          *  If lookup fails or access is not permitted, return null.
1016          *  Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
1017          */
1018         public
1019         MemberName resolveOrNull(byte refKind, MemberName m, Class<?> lookupClass) {
1020             MemberName result = resolve(refKind, m, lookupClass);
1021             if (result.isResolved())
1022                 return result;
1023             return null;
1024         }
1025         /** Return a list of all methods defined by the given class.
1026          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1027          *  Access checking is performed on behalf of the given {@code lookupClass}.
1028          *  Inaccessible members are not added to the last.
1029          */
1030         public List<MemberName> getMethods(Class<?> defc, boolean searchSupers,
1031                 Class<?> lookupClass) {
1032             return getMethods(defc, searchSupers, null, null, lookupClass);
1033         }
1034         /** Return a list of matching methods defined by the given class.
1035          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1036          *  Returned methods will match the name (if not null) and the type (if not null).
1037          *  Access checking is performed on behalf of the given {@code lookupClass}.
1038          *  Inaccessible members are not added to the last.
1039          */
1040         public List<MemberName> getMethods(Class<?> defc, boolean searchSupers,
1041                 String name, MethodType type, Class<?> lookupClass) {
1042             int matchFlags = IS_METHOD | (searchSupers ? SEARCH_ALL_SUPERS : 0);
1043             return getMembers(defc, name, type, matchFlags, lookupClass);
1044         }
1045         /** Return a list of all constructors defined by the given class.
1046          *  Access checking is performed on behalf of the given {@code lookupClass}.
1047          *  Inaccessible members are not added to the last.
1048          */
1049         public List<MemberName> getConstructors(Class<?> defc, Class<?> lookupClass) {
1050             return getMembers(defc, null, null, IS_CONSTRUCTOR, lookupClass);
1051         }
1052         /** Return a list of all fields defined by the given class.
1053          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1054          *  Access checking is performed on behalf of the given {@code lookupClass}.
1055          *  Inaccessible members are not added to the last.
1056          */
1057         public List<MemberName> getFields(Class<?> defc, boolean searchSupers,
1058                 Class<?> lookupClass) {
1059             return getFields(defc, searchSupers, null, null, lookupClass);
1060         }
1061         /** Return a list of all fields defined by the given class.
1062          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1063          *  Returned fields will match the name (if not null) and the type (if not null).
1064          *  Access checking is performed on behalf of the given {@code lookupClass}.
1065          *  Inaccessible members are not added to the last.
1066          */
1067         public List<MemberName> getFields(Class<?> defc, boolean searchSupers,
1068                 String name, Class<?> type, Class<?> lookupClass) {
1069             int matchFlags = IS_FIELD | (searchSupers ? SEARCH_ALL_SUPERS : 0);
1070             return getMembers(defc, name, type, matchFlags, lookupClass);
1071         }
1072         /** Return a list of all nested types defined by the given class.
1073          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1074          *  Access checking is performed on behalf of the given {@code lookupClass}.
1075          *  Inaccessible members are not added to the last.
1076          */
1077         public List<MemberName> getNestedTypes(Class<?> defc, boolean searchSupers,
1078                 Class<?> lookupClass) {
1079             int matchFlags = IS_TYPE | (searchSupers ? SEARCH_ALL_SUPERS : 0);
1080             return getMembers(defc, null, null, matchFlags, lookupClass);
1081         }
1082         private static MemberName[] newMemberBuffer(int length) {
1083             MemberName[] buf = new MemberName[length];
1084             // fill the buffer with dummy structs for the JVM to fill in
1085             for (int i = 0; i < length; i++)
1086                 buf[i] = new MemberName();
1087             return buf;
1088         }
1089     }
1090 
1091 //    static {
1092 //        System.out.println("Hello world!  My methods are:");
1093 //        System.out.println(Factory.INSTANCE.getMethods(MemberName.class, true, null));
1094 //    }
1095 }