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