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) { |