< prev index next >

src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java

Print this page
@@ -1,7 +1,7 @@
  /*
-  * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
+  * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Oracle designates this

@@ -249,10 +249,14 @@
       * Flag for alternate metafactories indicating the lambda object requires
       * additional methods that invoke the {@code implementation}
       */
      public static final int FLAG_BRIDGES = 1 << 2;
  
+     /** Flag for {@link #altMetafactory} indicating the lambda object
+      * must be a {@code Quotable} object, inspectable using code reflection. */
+     public static final int FLAG_QUOTABLE = 1 << 3;
+ 
      private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
      private static final MethodType[] EMPTY_MT_ARRAY = new MethodType[0];
  
      // LambdaMetafactory bootstrap methods are startup sensitive, and may be
      // special cased in java.lang.invoke.BootstrapMethodInvoker to ensure

@@ -334,11 +338,12 @@
                                               Objects.requireNonNull(interfaceMethodType),
                                               Objects.requireNonNull(implementation),
                                               Objects.requireNonNull(dynamicMethodType),
                                               false,
                                               EMPTY_CLASS_ARRAY,
-                                              EMPTY_MT_ARRAY);
+                                              EMPTY_MT_ARRAY,
+                                  null);
          mf.validateMetafactoryArgs();
          return mf.buildCallSite();
      }
  
      /**

@@ -380,10 +385,11 @@
       *                          int flags,
       *                          int altInterfaceCount,        // IF flags has MARKERS set
       *                          Class... altInterfaces,       // IF flags has MARKERS set
       *                          int altMethodCount,           // IF flags has BRIDGES set
       *                          MethodType... altMethods      // IF flags has BRIDGES set
+      *                          MethodHandle quotableField    // IF flags has QUOTABLE set
       *                          )
       * }</pre>
       *
       * <p>Arguments that appear in the argument list for
       * {@link #metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)}

@@ -403,10 +409,14 @@
       *     the function object should implement, and is present if and only if
       *     the {@code FLAG_BRIDGES} flag is set.</li>
       *     <li>{@code altMethods} is a variable-length list of additional
       *     methods signatures to implement, whose length equals {@code altMethodCount},
       *     and is present if and only if the {@code FLAG_BRIDGES} flag is set.</li>
+      *     <li>{@code quotableField} is a
+      *     {@linkplain MethodHandles.Lookup#findGetter(Class, String, Class) getter} method handle
+      *     that is used to retrieve the string representation of the quotable lambda's associated
+      *     intermediate representation.</li>
       * </ul>
       *
       * <p>Each class named by {@code altInterfaces} is subject to the same
       * restrictions as {@code Rd}, the return type of {@code factoryType},
       * as described {@link LambdaMetafactory above}.  Each {@code MethodType}

@@ -417,10 +427,13 @@
       * will implement {@code Serializable}, and will have a {@code writeReplace}
       * method that returns an appropriate {@link SerializedLambda}.  The
       * {@code caller} class must have an appropriate {@code $deserializeLambda$}
       * method, as described in {@link SerializedLambda}.
       *
+      * <p>When FLAG_QUOTABLE is set in {@code flags}, the function objects
+      * will implement {@code Quotable}.
+      *
       * <p>When the target of the {@code CallSite} returned from this method is
       * invoked, the resulting function objects are instances of a class with
       * the following properties:
       * <ul>
       *     <li>The class implements the interface named by the return type

@@ -485,10 +498,11 @@
          MethodHandle implementation = extractArg(args, argIndex++, MethodHandle.class);
          MethodType dynamicMethodType = extractArg(args, argIndex++, MethodType.class);
          int flags = extractArg(args, argIndex++, Integer.class);
          Class<?>[] altInterfaces = EMPTY_CLASS_ARRAY;
          MethodType[] altMethods = EMPTY_MT_ARRAY;
+         MethodHandle quotableField = null;
          if ((flags & FLAG_MARKERS) != 0) {
              int altInterfaceCount = extractArg(args, argIndex++, Integer.class);
              if (altInterfaceCount < 0) {
                  throw new IllegalArgumentException("negative argument count");
              }

@@ -505,10 +519,15 @@
              if (altMethodCount > 0) {
                  altMethods = extractArgs(args, argIndex, MethodType.class, altMethodCount);
                  argIndex += altMethodCount;
              }
          }
+         if ((flags & FLAG_QUOTABLE) != 0) {
+             quotableField = extractArg(args, argIndex++, MethodHandle.class);
+             altInterfaces = Arrays.copyOf(altInterfaces, altInterfaces.length + 1);
+             altInterfaces[altInterfaces.length-1] = InnerClassLambdaMetafactory.CodeReflectionSupport.QUOTABLE_CLASS;
+         }
          if (argIndex < args.length) {
              throw new IllegalArgumentException("too many arguments");
          }
  
          boolean isSerializable = ((flags & FLAG_SERIALIZABLE) != 0);

@@ -529,11 +548,12 @@
                                                    interfaceMethodType,
                                                    implementation,
                                                    dynamicMethodType,
                                                    isSerializable,
                                                    altInterfaces,
-                                                   altMethods);
+                                                   altMethods,
+                                                   quotableField);
          mf.validateMetafactoryArgs();
          return mf.buildCallSite();
      }
  
      private static <T> T extractArg(Object[] args, int index, Class<T> type) {
< prev index next >