jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
changeset 26471 1de6be0c6945
parent 26470 1586df597397
child 26472 71b6a6f208c0
equal deleted inserted replaced
26470:1586df597397 26471:1de6be0c6945
   805                                                 MethodHandle.class, Object[].class);
   805                                                 MethodHandle.class, Object[].class);
   806         mh = throwException(type);
   806         mh = throwException(type);
   807         mh = mh.bindTo(new UnsupportedOperationException("cannot reflectively invoke MethodHandle"));
   807         mh = mh.bindTo(new UnsupportedOperationException("cannot reflectively invoke MethodHandle"));
   808         if (!method.getInvocationType().equals(mh.type()))
   808         if (!method.getInvocationType().equals(mh.type()))
   809             throw new InternalError(method.toString());
   809             throw new InternalError(method.toString());
   810         mh = mh.withInternalMemberName(method);
   810         mh = mh.withInternalMemberName(method, false);
   811         mh = mh.asVarargsCollector(Object[].class);
   811         mh = mh.asVarargsCollector(Object[].class);
   812         assert(method.isVarargs());
   812         assert(method.isVarargs());
   813         FAKE_METHOD_HANDLE_INVOKE[idx] = mh;
   813         FAKE_METHOD_HANDLE_INVOKE[idx] = mh;
   814         return mh;
   814         return mh;
   815     }
   815     }
   842             }
   842             }
   843             // For simplicity, convert mh to a varargs-like method.
   843             // For simplicity, convert mh to a varargs-like method.
   844             MethodHandle vamh = prepareForInvoker(mh);
   844             MethodHandle vamh = prepareForInvoker(mh);
   845             // Cache the result of makeInjectedInvoker once per argument class.
   845             // Cache the result of makeInjectedInvoker once per argument class.
   846             MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass);
   846             MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass);
   847             return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName(), hostClass);
   847             return restoreToType(bccInvoker.bindTo(vamh), mh, hostClass);
   848         }
   848         }
   849 
   849 
   850         private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
   850         private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
   851             Class<?> bcc = UNSAFE.defineAnonymousClass(hostClass, T_BYTES, null);
   851             Class<?> bcc = UNSAFE.defineAnonymousClass(hostClass, T_BYTES, null);
   852             if (hostClass.getClassLoader() != bcc.getClassLoader())
   852             if (hostClass.getClassLoader() != bcc.getClassLoader())
   897             vamh.internalForm().compileToBytecode();  // eliminate LFI stack frames
   897             vamh.internalForm().compileToBytecode();  // eliminate LFI stack frames
   898             return vamh;
   898             return vamh;
   899         }
   899         }
   900 
   900 
   901         // Undo the adapter effect of prepareForInvoker:
   901         // Undo the adapter effect of prepareForInvoker:
   902         private static MethodHandle restoreToType(MethodHandle vamh, MethodType type,
   902         private static MethodHandle restoreToType(MethodHandle vamh,
   903                                                   MemberName member,
   903                                                   MethodHandle original,
   904                                                   Class<?> hostClass) {
   904                                                   Class<?> hostClass) {
       
   905             MethodType type = original.type();
   905             MethodHandle mh = vamh.asCollector(Object[].class, type.parameterCount());
   906             MethodHandle mh = vamh.asCollector(Object[].class, type.parameterCount());
       
   907             MemberName member = original.internalMemberName();
   906             mh = mh.asType(type);
   908             mh = mh.asType(type);
   907             mh = new WrappedMember(mh, type, member, hostClass);
   909             mh = new WrappedMember(mh, type, member, original.isInvokeSpecial(), hostClass);
   908             return mh;
   910             return mh;
   909         }
   911         }
   910 
   912 
   911         private static final MethodHandle MH_checkCallerClass;
   913         private static final MethodHandle MH_checkCallerClass;
   912         static {
   914         static {
   972     /** This subclass allows a wrapped method handle to be re-associated with an arbitrary member name. */
   974     /** This subclass allows a wrapped method handle to be re-associated with an arbitrary member name. */
   973     static class WrappedMember extends MethodHandle {
   975     static class WrappedMember extends MethodHandle {
   974         private final MethodHandle target;
   976         private final MethodHandle target;
   975         private final MemberName member;
   977         private final MemberName member;
   976         private final Class<?> callerClass;
   978         private final Class<?> callerClass;
   977 
   979         private final boolean isInvokeSpecial;
   978         private WrappedMember(MethodHandle target, MethodType type, MemberName member, Class<?> callerClass) {
   980 
       
   981         private WrappedMember(MethodHandle target, MethodType type,
       
   982                               MemberName member, boolean isInvokeSpecial,
       
   983                               Class<?> callerClass) {
   979             super(type, reinvokerForm(target));
   984             super(type, reinvokerForm(target));
   980             this.target = target;
   985             this.target = target;
   981             this.member = member;
   986             this.member = member;
   982             this.callerClass = callerClass;
   987             this.callerClass = callerClass;
       
   988             this.isInvokeSpecial = isInvokeSpecial;
   983         }
   989         }
   984 
   990 
   985         @Override
   991         @Override
   986         MethodHandle reinvokerTarget() {
   992         MethodHandle reinvokerTarget() {
   987             return target;
   993             return target;
  1000         Class<?> internalCallerClass() {
  1006         Class<?> internalCallerClass() {
  1001             return callerClass;
  1007             return callerClass;
  1002         }
  1008         }
  1003         @Override
  1009         @Override
  1004         boolean isInvokeSpecial() {
  1010         boolean isInvokeSpecial() {
  1005             return target.isInvokeSpecial();
  1011             return isInvokeSpecial;
  1006         }
  1012         }
  1007 
  1013 
  1008         @Override
  1014         @Override
  1009         MethodHandle copyWith(MethodType mt, LambdaForm lf) {
  1015         MethodHandle copyWith(MethodType mt, LambdaForm lf) {
  1010             throw newIllegalArgumentException("do not use this");
  1016             throw newIllegalArgumentException("do not use this");
  1011         }
  1017         }
  1012     }
  1018     }
  1013 
  1019 
  1014     static MethodHandle makeWrappedMember(MethodHandle target, MemberName member) {
  1020     static MethodHandle makeWrappedMember(MethodHandle target, MemberName member, boolean isInvokeSpecial) {
  1015         if (member.equals(target.internalMemberName()))
  1021         if (member.equals(target.internalMemberName()) && isInvokeSpecial == target.isInvokeSpecial())
  1016             return target;
  1022             return target;
  1017         return new WrappedMember(target, target.type(), member, null);
  1023         return new WrappedMember(target, target.type(), member, isInvokeSpecial, null);
  1018     }
  1024     }
  1019 
  1025 
  1020     /// Collection of multiple arguments.
  1026     /// Collection of multiple arguments.
  1021 
  1027 
  1022     private static MethodHandle findCollector(String name, int nargs, Class<?> rtype, Class<?>... ptypes) {
  1028     private static MethodHandle findCollector(String name, int nargs, Class<?> rtype, Class<?>... ptypes) {