changeset 49699:43acbccddc7d datum

More extractor bootstraps
author briangoetz
date Wed, 04 Apr 2018 15:33:06 -0400
parents 4b1e008bd652
children 829d99f94b43
files src/java.base/share/classes/java/lang/compiler/Extractor.java src/java.base/share/classes/java/lang/compiler/_pattern.java
diffstat 2 files changed, 106 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/compiler/Extractor.java	Wed Apr 04 13:44:50 2018 -0400
+++ b/src/java.base/share/classes/java/lang/compiler/Extractor.java	Wed Apr 04 15:33:06 2018 -0400
@@ -24,10 +24,19 @@
  */
 package java.lang.compiler;
 
+import java.lang.invoke.CallSite;
+import java.lang.invoke.ConstantCallSite;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
 
+import sun.invoke.util.BytecodeName;
+
+import static java.lang.invoke.MethodHandleInfo.REF_invokeInterface;
+import static java.lang.invoke.MethodHandleInfo.REF_invokeStatic;
+import static java.lang.invoke.MethodHandleInfo.REF_invokeVirtual;
+import static java.lang.invoke.MethodHandleInfo.REF_newInvokeSpecial;
+
 /**
  * Supporting type for implementation of pattern matching.  An {@linkplain Extractor}
  * is a constant bundle of method handles that describe a particular pattern, and
@@ -303,11 +312,11 @@
      * @param components the {@code component} method handles
      * @return the {@linkplain Extractor}
      */
-    public static Extractor ofCarrier(MethodHandles.Lookup lookup, String constantName, Class<Extractor> constantType,
-                                      MethodType descriptor,
-                                      MethodHandle carrierFactory,
-                                      MethodHandle digester,
-                                      MethodHandle... components) {
+    public static Extractor makeCarrierExtractor(MethodHandles.Lookup lookup, String constantName, Class<Extractor> constantType,
+                                                 MethodType descriptor,
+                                                 MethodHandle carrierFactory,
+                                                 MethodHandle digester,
+                                                 MethodHandle... components) {
         return ofCarrier(descriptor, carrierFactory, digester, components);
     }
 
@@ -329,16 +338,90 @@
      * @param components the {@code component} method handles
      * @return the {@linkplain Extractor}
      */
-    public static Extractor ofCarrierPartial(MethodHandles.Lookup lookup, String constantName, Class<Extractor> constantType,
-                                             MethodType descriptor,
-                                             MethodHandle carrierFactory,
-                                             MethodHandle digester,
-                                             MethodHandle predicate,
-                                             MethodHandle... components) {
+    public static Extractor makeCarrierPartialExtractor(MethodHandles.Lookup lookup, String constantName, Class<Extractor> constantType,
+                                                        MethodType descriptor,
+                                                        MethodHandle carrierFactory,
+                                                        MethodHandle digester,
+                                                        MethodHandle predicate,
+                                                        MethodHandle... components) {
         return ofCarrierPartial(descriptor, carrierFactory, digester, predicate, components);
     }
 
     /**
+     * Invokedynamic bootstrap for creating lazy extractors
+     *
+     * @param lookup ignored
+     * @param invocationName ignored
+     * @param invocationType ignored
+     * @param descriptor the extractor descriptor
+     * @param components the extractor components
+     * @return the extractor factory
+     * @throws Throwable if something went wrong
+     */
+
+    public static CallSite makeLazyExtractor(MethodHandles.Lookup lookup, String invocationName, MethodType invocationType,
+                                             MethodType descriptor, MethodHandle... components) throws Throwable {
+        return new ConstantCallSite(MethodHandles.constant(Extractor.class, ofLazy(descriptor, components)));
+    }
+
+    /**
+     * Condy bootstrap for creating lazy extractors
+     *
+     * @param lookup ignored
+     * @param constantName ignored
+     * @param constantType ignored
+     * @param descriptor the extractor descriptor
+     * @param components the extractor components
+     * @return the extractor factory
+     * @throws Throwable if something went wrong
+     */
+
+    public static Extractor makeLazyExtractor(MethodHandles.Lookup lookup, String constantName, Class<Extractor> constantType,
+                                              MethodType descriptor, MethodHandle... components) throws Throwable {
+        return ofLazy(descriptor, components);
+    }
+
+
+    /**
+     * Condy bootstrap for finding extractors
+     *
+     * @param lookup the lookup context
+     * @param constantName ignored
+     * @param constantType ignored
+     * @param owner the class containing the extractor
+     * @param descriptor the extractor descriptor
+     * @param name the extractor name
+     * @param refKind the kind of method
+     * @return the extractor
+     * @throws Throwable if something went wrong
+     */
+    public static Extractor findExtractor(MethodHandles.Lookup lookup, String constantName, Class<Extractor> constantType,
+                                          Class<?> owner, MethodType descriptor, String name, int refKind) throws Throwable {
+        String dd = descriptor.toMethodDescriptorString();
+        dd = dd.substring(0, dd.indexOf(')') + 1);
+        String patternMethodName
+                = BytecodeName.toBytecodeName(String.format("$pattern$%s$%s",
+                                                            (refKind == REF_newInvokeSpecial ? owner.getSimpleName() : name),
+                                                            dd));
+        MethodType factoryDesc = MethodType.methodType(Extractor.class);
+        MethodHandle mh;
+        switch (refKind) {
+            case REF_invokeStatic:
+            case REF_newInvokeSpecial:
+                mh = lookup.findStatic(owner, patternMethodName, factoryDesc);
+                break;
+            case REF_invokeVirtual:
+            case REF_invokeInterface:
+                mh = lookup.findVirtual(owner, patternMethodName, factoryDesc);
+                break;
+            default:
+                throw new IllegalAccessException(Integer.toString(refKind));
+        }
+
+        return (Extractor) mh.invoke();
+    }
+
+    /**
      * Bootstrap for extracting the {@code tryMatch} method handle from a {@linkplain Extractor}
      *
      * @param lookup ignored
@@ -347,6 +430,8 @@
      * @param extractor the {@linkplain Extractor}
      * @return the {@code tryMatch} method handle
      */
+
+
     public static MethodHandle extractorTryMatch(MethodHandles.Lookup lookup, String constantName, Class<MethodHandle> constantType,
                                                  Extractor extractor) {
         return extractor.tryMatch();
@@ -367,6 +452,4 @@
         return extractor.component(i);
     }
 
-    // @@@ Condy bootstraps for finding an extractor based on owner, descriptor, refKind
 }
-
--- a/src/java.base/share/classes/java/lang/compiler/_pattern.java	Wed Apr 04 13:44:50 2018 -0400
+++ b/src/java.base/share/classes/java/lang/compiler/_pattern.java	Wed Apr 04 15:33:06 2018 -0400
@@ -80,6 +80,16 @@
     }
 
     /**
+     * Construct a PatternDecl for a type test pattern
+     * @param clazz The type to test against
+     * @param <T> the type of a successful target
+     * @return the PatternDecl
+     */
+    static<T> _pattern<T> ofType(Class<T> clazz) {
+        return of(o -> clazz.isAssignableFrom(o.getClass()), clazz::cast);
+    }
+
+    /**
      * Construct a PatternDecl for a constant
      * @param constant the constant
      * @param <T> the type of the constant