@@ -66,7 +66,7 @@ private static class StaticHolders {
6666 static {
6767 try {
6868 SYNTHETIC_PATTERN = LOOKUP .findStatic (PatternBootstraps .class , "syntheticPattern" ,
69- MethodType .methodType (Object .class , Class .class , Object .class ));
69+ MethodType .methodType (Object .class , Method []. class , MethodHandle .class , Object .class ));
7070 }
7171 catch (ReflectiveOperationException e ) {
7272 throw new ExceptionInInitializerError (e );
@@ -111,6 +111,23 @@ public static CallSite invokePattern(MethodHandles.Lookup lookup,
111111 String invocationName ,
112112 MethodType invocationType ,
113113 String mangledName ) {
114+ if (invocationType .parameterCount () == 2 ) {
115+ Class <?> receiverType = invocationType .parameterType (0 );
116+ Class <?> selectorType = invocationType .parameterType (1 );
117+ if ((!invocationType .returnType ().equals (Object .class )))
118+ throw new IllegalArgumentException ("Illegal invocation type " + invocationType );
119+
120+ MethodHandle target = null ;
121+ try {
122+ // Attempt 1: discover the pattern declaration
123+ target = lookup .findStatic (receiverType , mangledName , MethodType .methodType (Object .class , receiverType , selectorType ));
124+
125+ return new ConstantCallSite (target );
126+ } catch (Throwable t ) {
127+ throw new IllegalArgumentException ("Cannot find a pattern" );
128+ }
129+ }
130+
114131 Class <?> selectorType = invocationType .parameterType (0 );
115132 if (invocationType .parameterCount () != 1
116133 || (!invocationType .returnType ().equals (Object .class )))
@@ -137,7 +154,25 @@ public static CallSite invokePattern(MethodHandles.Lookup lookup,
137154 throw new IllegalArgumentException ("\n Unexpected pattern at use site: " + mangledName + "\n Was expecting: " + expectedMangledName );
138155 }
139156
140- target = MethodHandles .insertArguments (StaticHolders .SYNTHETIC_PATTERN , 0 , selectorType ).asType (invocationType );
157+ @ SuppressWarnings ("removal" )
158+ final RecordComponent [] components = AccessController .doPrivileged (
159+ (PrivilegedAction <RecordComponent []>) selectorType ::getRecordComponents );
160+
161+ Method [] accessors = Arrays .stream (components ).map (c -> {
162+ Method accessor = c .getAccessor ();
163+ accessor .setAccessible (true );
164+ return accessor ;
165+ }).toArray (Method []::new );
166+
167+ Class <?>[] ctypes = Arrays .stream (components ).map (c -> c .getType ()).toArray (Class <?>[]::new );
168+
169+ Carriers .CarrierElements carrierElements = Carriers .CarrierFactory .of (ctypes );
170+
171+ MethodHandle initializingConstructor = carrierElements .initializingConstructor ();
172+
173+ MethodHandle carrierCreator = initializingConstructor .asSpreader (Object [].class , ctypes .length );
174+
175+ target = MethodHandles .insertArguments (StaticHolders .SYNTHETIC_PATTERN , 0 , accessors , carrierCreator ).asType (invocationType );
141176
142177 return new ConstantCallSite (target );
143178 }
@@ -153,20 +188,8 @@ public static CallSite invokePattern(MethodHandles.Lookup lookup,
153188 *
154189 * @throws Throwable throws if invocation of synthetic pattern fails
155190 */
156- @ SuppressWarnings ("removal" )
157- private static Object syntheticPattern (Class <?> matchCandidateType , Object matchCandidateInstance ) throws Throwable {
158- final RecordComponent [] components = AccessController .doPrivileged (
159- (PrivilegedAction <RecordComponent []>) matchCandidateType ::getRecordComponents );
160-
161- Class <?>[] ctypes = Arrays .stream (components ).map (c -> c .getType ()).toArray (Class <?>[]::new );
162-
163- Carriers .CarrierElements carrierElements = Carriers .CarrierFactory .of (ctypes );
164-
165- MethodHandle initializingConstructor = carrierElements .initializingConstructor ();
166-
167- Object [] extracted = Arrays .stream (components ).map (c -> {
168- Method accessor = c .getAccessor ();
169- accessor .setAccessible (true );
191+ private static Object syntheticPattern (Method [] accessors , MethodHandle carrierCreator , Object matchCandidateInstance ) throws Throwable {
192+ Object [] extracted = Arrays .stream (accessors ).map (accessor -> {
170193 try {
171194 return accessor .invoke (matchCandidateInstance );
172195 } catch (IllegalAccessException e ) {
@@ -176,9 +199,7 @@ private static Object syntheticPattern(Class<?> matchCandidateType, Object match
176199 }
177200 }).toArray ();
178201
179- MethodHandle spreadedPatternInvoker = initializingConstructor .asSpreader (Object [].class , ctypes .length );
180-
181- Object carrier = spreadedPatternInvoker .invoke (extracted );
202+ Object carrier = carrierCreator .invoke (extracted );
182203
183204 return carrier ;
184205 }
0 commit comments