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 static java.lang.invoke.MethodHandleNatives.Constants.*;
29 
30 /**
31  * The JVM interface for the method handles package is all here.
32  * This is an interface internal and private to an implementation of JSR 292.
33  * <em>This class is not part of the JSR 292 standard.</em>
34  * @author jrose
35  */
36 class MethodHandleNatives {
37 
38     // BEGIN Android-removed: Unused implementation code.
39     /*
40     private MethodHandleNatives() { } // static only
41 
42     /// MemberName support
43 
44     static native void init(MemberName self, Object ref);
45     static native void expand(MemberName self);
46     static native MemberName resolve(MemberName self, Class<?> caller) throws LinkageError, ClassNotFoundException;
47     static native int getMembers(Class<?> defc, String matchName, String matchSig,
48             int matchFlags, Class<?> caller, int skip, MemberName[] results);
49 
50     /// Field layout queries parallel to sun.misc.Unsafe:
51     static native long objectFieldOffset(MemberName self);  // e.g., returns vmindex
52     static native long staticFieldOffset(MemberName self);  // e.g., returns vmindex
53     static native Object staticFieldBase(MemberName self);  // e.g., returns clazz
54     static native Object getMemberVMInfo(MemberName self);  // returns {vmindex,vmtarget}
55 
56     /// MethodHandle support
57 
58     /** Fetch MH-related JVM parameter.
59      *  which=0 retrieves MethodHandlePushLimit
60      *  which=1 retrieves stack slot push size (in address units)
61      *
62     static native int getConstant(int which);
63 
64     static final boolean COUNT_GWT;
65 
66     /// CallSite support
67 
68     /** Tell the JVM that we need to change the target of a CallSite. *
69     static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
70     static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
71 
72     private static native void registerNatives();
73     static {
74         registerNatives();
75         COUNT_GWT                   = getConstant(Constants.GC_COUNT_GWT) != 0;
76 
77         // The JVM calls MethodHandleNatives.<clinit>.  Cascade the <clinit> calls as needed:
78         MethodHandleImpl.initStatics();
79     }
80     */
81     // END Android-removed: Unused implementation code.
82 
83     // All compile-time constants go here.
84     // There is an opportunity to check them against the JVM's idea of them.
85     static class Constants {
Constants()86         Constants() { } // static only
87         // BEGIN Android-removed: Unused implementation code.
88         /*
89         // MethodHandleImpl
90         static final int // for getConstant
91                 GC_COUNT_GWT = 4,
92                 GC_LAMBDA_SUPPORT = 5;
93 
94         // MemberName
95         // The JVM uses values of -2 and above for vtable indexes.
96         // Field values are simple positive offsets.
97         // Ref: src/share/vm/oops/methodOop.hpp
98         // This value is negative enough to avoid such numbers,
99         // but not too negative.
100         static final int
101                 MN_IS_METHOD           = 0x00010000, // method (not constructor)
102                 MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
103                 MN_IS_FIELD            = 0x00040000, // field
104                 MN_IS_TYPE             = 0x00080000, // nested type
105                 MN_CALLER_SENSITIVE    = 0x00100000, // @CallerSensitive annotation detected
106                 MN_REFERENCE_KIND_SHIFT = 24, // refKind
107                 MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
108                 // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
109                 MN_SEARCH_SUPERCLASSES = 0x00100000,
110                 MN_SEARCH_INTERFACES   = 0x00200000;
111 
112         /**
113          * Basic types as encoded in the JVM.  These code values are not
114          * intended for use outside this class.  They are used as part of
115          * a private interface between the JVM and this class.
116          *
117         static final int
118             T_BOOLEAN  =  4,
119             T_CHAR     =  5,
120             T_FLOAT    =  6,
121             T_DOUBLE   =  7,
122             T_BYTE     =  8,
123             T_SHORT    =  9,
124             T_INT      = 10,
125             T_LONG     = 11,
126             T_OBJECT   = 12,
127             //T_ARRAY    = 13
128             T_VOID     = 14,
129             //T_ADDRESS  = 15
130             T_ILLEGAL  = 99;
131 
132         /**
133          * Constant pool entry types.
134          *
135         static final byte
136             CONSTANT_Utf8                = 1,
137             CONSTANT_Integer             = 3,
138             CONSTANT_Float               = 4,
139             CONSTANT_Long                = 5,
140             CONSTANT_Double              = 6,
141             CONSTANT_Class               = 7,
142             CONSTANT_String              = 8,
143             CONSTANT_Fieldref            = 9,
144             CONSTANT_Methodref           = 10,
145             CONSTANT_InterfaceMethodref  = 11,
146             CONSTANT_NameAndType         = 12,
147             CONSTANT_MethodHandle        = 15,  // JSR 292
148             CONSTANT_MethodType          = 16,  // JSR 292
149             CONSTANT_InvokeDynamic       = 18,
150             CONSTANT_LIMIT               = 19;   // Limit to tags found in classfiles
151 
152         /**
153          * Access modifier flags.
154          *
155         static final char
156             ACC_PUBLIC                 = 0x0001,
157             ACC_PRIVATE                = 0x0002,
158             ACC_PROTECTED              = 0x0004,
159             ACC_STATIC                 = 0x0008,
160             ACC_FINAL                  = 0x0010,
161             ACC_SYNCHRONIZED           = 0x0020,
162             ACC_VOLATILE               = 0x0040,
163             ACC_TRANSIENT              = 0x0080,
164             ACC_NATIVE                 = 0x0100,
165             ACC_INTERFACE              = 0x0200,
166             ACC_ABSTRACT               = 0x0400,
167             ACC_STRICT                 = 0x0800,
168             ACC_SYNTHETIC              = 0x1000,
169             ACC_ANNOTATION             = 0x2000,
170             ACC_ENUM                   = 0x4000,
171             // aliases:
172             ACC_SUPER                  = ACC_SYNCHRONIZED,
173             ACC_BRIDGE                 = ACC_VOLATILE,
174             ACC_VARARGS                = ACC_TRANSIENT;
175         */
176         // END Android-removed: Unused implementation code.
177 
178         /**
179          * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
180          */
181         static final byte
182             REF_NONE                    = 0,  // null value
183             REF_getField                = 1,
184             REF_getStatic               = 2,
185             REF_putField                = 3,
186             REF_putStatic               = 4,
187             REF_invokeVirtual           = 5,
188             REF_invokeStatic            = 6,
189             REF_invokeSpecial           = 7,
190             REF_newInvokeSpecial        = 8,
191             REF_invokeInterface         = 9,
192             REF_LIMIT                  = 10;
193     }
194 
refKindIsValid(int refKind)195     static boolean refKindIsValid(int refKind) {
196         return (refKind > REF_NONE && refKind < REF_LIMIT);
197     }
refKindIsField(byte refKind)198     static boolean refKindIsField(byte refKind) {
199         assert(refKindIsValid(refKind));
200         return (refKind <= REF_putStatic);
201     }
202     // BEGIN Android-removed: Unused implementation code.
203     /*
204     static boolean refKindIsGetter(byte refKind) {
205         assert(refKindIsValid(refKind));
206         return (refKind <= REF_getStatic);
207     }
208     static boolean refKindIsSetter(byte refKind) {
209         return refKindIsField(refKind) && !refKindIsGetter(refKind);
210     }
211     static boolean refKindIsMethod(byte refKind) {
212         return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
213     }
214     static boolean refKindIsConstructor(byte refKind) {
215         return (refKind == REF_newInvokeSpecial);
216     }
217     static boolean refKindHasReceiver(byte refKind) {
218         assert(refKindIsValid(refKind));
219         return (refKind & 1) != 0;
220     }
221     static boolean refKindIsStatic(byte refKind) {
222         return !refKindHasReceiver(refKind) && (refKind != REF_newInvokeSpecial);
223     }
224     static boolean refKindDoesDispatch(byte refKind) {
225         assert(refKindIsValid(refKind));
226         return (refKind == REF_invokeVirtual ||
227                 refKind == REF_invokeInterface);
228     }
229     static {
230         final int HR_MASK = ((1 << REF_getField) |
231                              (1 << REF_putField) |
232                              (1 << REF_invokeVirtual) |
233                              (1 << REF_invokeSpecial) |
234                              (1 << REF_invokeInterface)
235                             );
236         for (byte refKind = REF_NONE+1; refKind < REF_LIMIT; refKind++) {
237             assert(refKindHasReceiver(refKind) == (((1<<refKind) & HR_MASK) != 0)) : refKind;
238         }
239     }
240     */
241     // END Android-removed: Unused implementation code.
refKindName(byte refKind)242     static String refKindName(byte refKind) {
243         assert(refKindIsValid(refKind));
244         switch (refKind) {
245         case REF_getField:          return "getField";
246         case REF_getStatic:         return "getStatic";
247         case REF_putField:          return "putField";
248         case REF_putStatic:         return "putStatic";
249         case REF_invokeVirtual:     return "invokeVirtual";
250         case REF_invokeStatic:      return "invokeStatic";
251         case REF_invokeSpecial:     return "invokeSpecial";
252         case REF_newInvokeSpecial:  return "newInvokeSpecial";
253         case REF_invokeInterface:   return "invokeInterface";
254         default:                    return "REF_???";
255         }
256     }
257     // BEGIN Android-removed: Unused implementation code.
258     /*
259     private static native int getNamedCon(int which, Object[] name);
260     static boolean verifyConstants() {
261         Object[] box = { null };
262         for (int i = 0; ; i++) {
263             box[0] = null;
264             int vmval = getNamedCon(i, box);
265             if (box[0] == null)  break;
266             String name = (String) box[0];
267             try {
268                 Field con = Constants.class.getDeclaredField(name);
269                 int jval = con.getInt(null);
270                 if (jval == vmval)  continue;
271                 String err = (name+": JVM has "+vmval+" while Java has "+jval);
272                 if (name.equals("CONV_OP_LIMIT")) {
273                     System.err.println("warning: "+err);
274                     continue;
275                 }
276                 throw new InternalError(err);
277             } catch (NoSuchFieldException | IllegalAccessException ex) {
278                 String err = (name+": JVM has "+vmval+" which Java does not define");
279                 // ignore exotic ops the JVM cares about; we just wont issue them
280                 //System.err.println("warning: "+err);
281                 continue;
282             }
283         }
284         return true;
285     }
286     static {
287         assert(verifyConstants());
288     }
289 
290     // Up-calls from the JVM.
291     // These must NOT be public.
292 
293     /**
294      * The JVM is linking an invokedynamic instruction.  Create a reified call site for it.
295      *
296     static MemberName linkCallSite(Object callerObj,
297                                    Object bootstrapMethodObj,
298                                    Object nameObj, Object typeObj,
299                                    Object staticArguments,
300                                    Object[] appendixResult) {
301         MethodHandle bootstrapMethod = (MethodHandle)bootstrapMethodObj;
302         Class<?> caller = (Class<?>)callerObj;
303         String name = nameObj.toString().intern();
304         MethodType type = (MethodType)typeObj;
305         if (!TRACE_METHOD_LINKAGE)
306             return linkCallSiteImpl(caller, bootstrapMethod, name, type,
307                                     staticArguments, appendixResult);
308         return linkCallSiteTracing(caller, bootstrapMethod, name, type,
309                                    staticArguments, appendixResult);
310     }
311     static MemberName linkCallSiteImpl(Class<?> caller,
312                                        MethodHandle bootstrapMethod,
313                                        String name, MethodType type,
314                                        Object staticArguments,
315                                        Object[] appendixResult) {
316         CallSite callSite = CallSite.makeSite(bootstrapMethod,
317                                               name,
318                                               type,
319                                               staticArguments,
320                                               caller);
321         if (callSite instanceof ConstantCallSite) {
322             appendixResult[0] = callSite.dynamicInvoker();
323             return Invokers.linkToTargetMethod(type);
324         } else {
325             appendixResult[0] = callSite;
326             return Invokers.linkToCallSiteMethod(type);
327         }
328     }
329     // Tracing logic:
330     static MemberName linkCallSiteTracing(Class<?> caller,
331                                           MethodHandle bootstrapMethod,
332                                           String name, MethodType type,
333                                           Object staticArguments,
334                                           Object[] appendixResult) {
335         Object bsmReference = bootstrapMethod.internalMemberName();
336         if (bsmReference == null)  bsmReference = bootstrapMethod;
337         Object staticArglist = (staticArguments instanceof Object[] ?
338                                 java.util.Arrays.asList((Object[]) staticArguments) :
339                                 staticArguments);
340         System.out.println("linkCallSite "+caller.getName()+" "+
341                            bsmReference+" "+
342                            name+type+"/"+staticArglist);
343         try {
344             MemberName res = linkCallSiteImpl(caller, bootstrapMethod, name, type,
345                                               staticArguments, appendixResult);
346             System.out.println("linkCallSite => "+res+" + "+appendixResult[0]);
347             return res;
348         } catch (Throwable ex) {
349             System.out.println("linkCallSite => throw "+ex);
350             throw ex;
351         }
352     }
353 
354     /**
355      * The JVM wants a pointer to a MethodType.  Oblige it by finding or creating one.
356      *
357     static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) {
358         return MethodType.makeImpl(rtype, ptypes, true);
359     }
360 
361     /**
362      * The JVM wants to link a call site that requires a dynamic type check.
363      * Name is a type-checking invoker, invokeExact or invoke.
364      * Return a JVM method (MemberName) to handle the invoking.
365      * The method assumes the following arguments on the stack:
366      * 0: the method handle being invoked
367      * 1-N: the arguments to the method handle invocation
368      * N+1: an optional, implicitly added argument (typically the given MethodType)
369      * <p>
370      * The nominal method at such a call site is an instance of
371      * a signature-polymorphic method (see @PolymorphicSignature).
372      * Such method instances are user-visible entities which are
373      * "split" from the generic placeholder method in {@code MethodHandle}.
374      * (Note that the placeholder method is not identical with any of
375      * its instances.  If invoked reflectively, is guaranteed to throw an
376      * {@code UnsupportedOperationException}.)
377      * If the signature-polymorphic method instance is ever reified,
378      * it appears as a "copy" of the original placeholder
379      * (a native final member of {@code MethodHandle}) except
380      * that its type descriptor has shape required by the instance,
381      * and the method instance is <em>not</em> varargs.
382      * The method instance is also marked synthetic, since the
383      * method (by definition) does not appear in Java source code.
384      * <p>
385      * The JVM is allowed to reify this method as instance metadata.
386      * For example, {@code invokeBasic} is always reified.
387      * But the JVM may instead call {@code linkMethod}.
388      * If the result is an * ordered pair of a {@code (method, appendix)},
389      * the method gets all the arguments (0..N inclusive)
390      * plus the appendix (N+1), and uses the appendix to complete the call.
391      * In this way, one reusable method (called a "linker method")
392      * can perform the function of any number of polymorphic instance
393      * methods.
394      * <p>
395      * Linker methods are allowed to be weakly typed, with any or
396      * all references rewritten to {@code Object} and any primitives
397      * (except {@code long}/{@code float}/{@code double})
398      * rewritten to {@code int}.
399      * A linker method is trusted to return a strongly typed result,
400      * according to the specific method type descriptor of the
401      * signature-polymorphic instance it is emulating.
402      * This can involve (as necessary) a dynamic check using
403      * data extracted from the appendix argument.
404      * <p>
405      * The JVM does not inspect the appendix, other than to pass
406      * it verbatim to the linker method at every call.
407      * This means that the JDK runtime has wide latitude
408      * for choosing the shape of each linker method and its
409      * corresponding appendix.
410      * Linker methods should be generated from {@code LambdaForm}s
411      * so that they do not become visible on stack traces.
412      * <p>
413      * The {@code linkMethod} call is free to omit the appendix
414      * (returning null) and instead emulate the required function
415      * completely in the linker method.
416      * As a corner case, if N==255, no appendix is possible.
417      * In this case, the method returned must be custom-generated to
418      * to perform any needed type checking.
419      * <p>
420      * If the JVM does not reify a method at a call site, but instead
421      * calls {@code linkMethod}, the corresponding call represented
422      * in the bytecodes may mention a valid method which is not
423      * representable with a {@code MemberName}.
424      * Therefore, use cases for {@code linkMethod} tend to correspond to
425      * special cases in reflective code such as {@code findVirtual}
426      * or {@code revealDirect}.
427      *
428     static MemberName linkMethod(Class<?> callerClass, int refKind,
429                                  Class<?> defc, String name, Object type,
430                                  Object[] appendixResult) {
431         if (!TRACE_METHOD_LINKAGE)
432             return linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
433         return linkMethodTracing(callerClass, refKind, defc, name, type, appendixResult);
434     }
435     static MemberName linkMethodImpl(Class<?> callerClass, int refKind,
436                                      Class<?> defc, String name, Object type,
437                                      Object[] appendixResult) {
438         try {
439             if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
440                 return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult);
441             }
442         } catch (Throwable ex) {
443             if (ex instanceof LinkageError)
444                 throw (LinkageError) ex;
445             else
446                 throw new LinkageError(ex.getMessage(), ex);
447         }
448         throw new LinkageError("no such method "+defc.getName()+"."+name+type);
449     }
450     private static MethodType fixMethodType(Class<?> callerClass, Object type) {
451         if (type instanceof MethodType)
452             return (MethodType) type;
453         else
454             return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
455     }
456     // Tracing logic:
457     static MemberName linkMethodTracing(Class<?> callerClass, int refKind,
458                                         Class<?> defc, String name, Object type,
459                                         Object[] appendixResult) {
460         System.out.println("linkMethod "+defc.getName()+"."+
461                            name+type+"/"+Integer.toHexString(refKind));
462         try {
463             MemberName res = linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
464             System.out.println("linkMethod => "+res+" + "+appendixResult[0]);
465             return res;
466         } catch (Throwable ex) {
467             System.out.println("linkMethod => throw "+ex);
468             throw ex;
469         }
470     }
471 
472 
473     /**
474      * The JVM is resolving a CONSTANT_MethodHandle CP entry.  And it wants our help.
475      * It will make an up-call to this method.  (Do not change the name or signature.)
476      * The type argument is a Class for field requests and a MethodType for non-fields.
477      * <p>
478      * Recent versions of the JVM may also pass a resolved MemberName for the type.
479      * In that case, the name is ignored and may be null.
480      *
481     static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
482                                                  Class<?> defc, String name, Object type) {
483         try {
484             Lookup lookup = IMPL_LOOKUP.in(callerClass);
485             assert(refKindIsValid(refKind));
486             return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);
487         } catch (IllegalAccessException ex) {
488             Throwable cause = ex.getCause();
489             if (cause instanceof AbstractMethodError) {
490                 throw (AbstractMethodError) cause;
491             } else {
492                 Error err = new IllegalAccessError(ex.getMessage());
493                 throw initCauseFrom(err, ex);
494             }
495         } catch (NoSuchMethodException ex) {
496             Error err = new NoSuchMethodError(ex.getMessage());
497             throw initCauseFrom(err, ex);
498         } catch (NoSuchFieldException ex) {
499             Error err = new NoSuchFieldError(ex.getMessage());
500             throw initCauseFrom(err, ex);
501         } catch (ReflectiveOperationException ex) {
502             Error err = new IncompatibleClassChangeError();
503             throw initCauseFrom(err, ex);
504         }
505     }
506     */
507     // END Android-removed: Unused implementation code.
508 
509     // BEGIN Android-added: Add mapLookupExceptionToError(ex) from OpenJDK 17. http://b/270028670
510     /**
511      * Map a reflective exception to a linkage error.
512      */
mapLookupExceptionToError(ReflectiveOperationException ex)513     static LinkageError mapLookupExceptionToError(ReflectiveOperationException ex) {
514         LinkageError err;
515         if (ex instanceof IllegalAccessException) {
516             Throwable cause = ex.getCause();
517             if (cause instanceof AbstractMethodError) {
518                 return (AbstractMethodError) cause;
519             } else {
520                 err = new IllegalAccessError(ex.getMessage());
521             }
522         } else if (ex instanceof NoSuchMethodException) {
523             err = new NoSuchMethodError(ex.getMessage());
524         } else if (ex instanceof NoSuchFieldException) {
525             err = new NoSuchFieldError(ex.getMessage());
526         } else {
527             err = new IncompatibleClassChangeError();
528         }
529         return initCauseFrom(err, ex);
530     }
531 
532     /**
533      * Use best possible cause for err.initCause(), substituting the
534      * cause for err itself if the cause has the same (or better) type.
535      */
initCauseFrom(E err, Exception ex)536     static <E extends Error> E initCauseFrom(E err, Exception ex) {
537         Throwable th = ex.getCause();
538         @SuppressWarnings("unchecked")
539         final Class<E> Eclass = (Class<E>) err.getClass();
540         if (Eclass.isInstance(th))
541             return Eclass.cast(th);
542         err.initCause(th == null ? ex : th);
543         return err;
544     }
545     // END Android-added: Add mapLookupExceptionToError(ex) from OpenJDK 17. http://b/270028670
546 
547     // BEGIN Android-removed: Unused implementation code.
548     /**
549      * Is this method a caller-sensitive method?
550      * I.e., does it call Reflection.getCallerClass or a similer method
551      * to ask about the identity of its caller?
552      *
553     static boolean isCallerSensitive(MemberName mem) {
554         if (!mem.isInvocable())  return false;  // fields are not caller sensitive
555 
556         return mem.isCallerSensitive() || canBeCalledVirtual(mem);
557     }
558 
559     static boolean canBeCalledVirtual(MemberName mem) {
560         assert(mem.isInvocable());
561         Class<?> defc = mem.getDeclaringClass();
562         switch (mem.getName()) {
563         case "checkMemberAccess":
564             return canBeCalledVirtual(mem, java.lang.SecurityManager.class);
565         case "getContextClassLoader":
566             return canBeCalledVirtual(mem, java.lang.Thread.class);
567         }
568         return false;
569     }
570 
571     static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) {
572         Class<?> symbolicRefClass = symbolicRef.getDeclaringClass();
573         if (symbolicRefClass == definingClass)  return true;
574         if (symbolicRef.isStatic() || symbolicRef.isPrivate())  return false;
575         return (definingClass.isAssignableFrom(symbolicRefClass) ||  // Msym overrides Mdef
576                 symbolicRefClass.isInterface());                     // Mdef implements Msym
577     }
578     */
579     // END Android-removed: Unused implementation code.
580 }
581