< prev index next >

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

Print this page
*** 1,7 ***
  /*
!  * Copyright (c) 2012, 2021, 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
--- 1,7 ---
  /*
!  * 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

*** 67,11 ***
      final Class<?> implClass;                 // Class for referencing the implementation method "class CC"
      final MethodType dynamicMethodType;       // Dynamically checked method type "(Integer)Object"
      final boolean isSerializable;             // Should the returned instance be serializable
      final Class<?>[] altInterfaces;           // Additional interfaces to be implemented
      final MethodType[] altMethods;            // Signatures of additional methods to bridge
! 
  
      /**
       * Meta-factory constructor.
       *
       * @param caller Stacked automatically by VM; represents a lookup context
--- 67,14 ---
      final Class<?> implClass;                 // Class for referencing the implementation method "class CC"
      final MethodType dynamicMethodType;       // Dynamically checked method type "(Integer)Object"
      final boolean isSerializable;             // Should the returned instance be serializable
      final Class<?>[] altInterfaces;           // Additional interfaces to be implemented
      final MethodType[] altMethods;            // Signatures of additional methods to bridge
!     final MethodHandle quotableOpField;       // A getter method handle that is used to retrieve the
+                                               // string representation of the quotable lambda's associated
+                                               // intermediate representation (can be null).
+     final MethodHandleInfo quotableOpFieldInfo;  // Info about the quotable getter method handle (can be null).
  
      /**
       * Meta-factory constructor.
       *
       * @param caller Stacked automatically by VM; represents a lookup context

*** 103,10 ***
--- 106,13 ---
       *                       types must extend {@code Serializable}.
       * @param altInterfaces Additional interfaces which the lambda object
       *                      should implement.
       * @param altMethods Method types for additional signatures to be
       *                   implemented by invoking the implementation method
+      * @param reflectiveField 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.
       * @throws LambdaConversionException If any of the meta-factory protocol
       *         invariants are violated
       * @throws SecurityException If a security manager is present, and it
       *         <a href="MethodHandles.Lookup.html#secmgr">denies access</a>
       *         from {@code caller} to the package of {@code implementation}.

*** 117,11 ***
                                          MethodType interfaceMethodType,
                                          MethodHandle implementation,
                                          MethodType dynamicMethodType,
                                          boolean isSerializable,
                                          Class<?>[] altInterfaces,
!                                         MethodType[] altMethods)
              throws LambdaConversionException {
          if (!caller.hasFullPrivilegeAccess()) {
              throw new LambdaConversionException(String.format(
                      "Invalid caller: %s",
                      caller.lookupClass().getName()));
--- 123,12 ---
                                          MethodType interfaceMethodType,
                                          MethodHandle implementation,
                                          MethodType dynamicMethodType,
                                          boolean isSerializable,
                                          Class<?>[] altInterfaces,
!                                         MethodType[] altMethods,
+                                         MethodHandle reflectiveField)
              throws LambdaConversionException {
          if (!caller.hasFullPrivilegeAccess()) {
              throw new LambdaConversionException(String.format(
                      "Invalid caller: %s",
                      caller.lookupClass().getName()));

*** 178,10 ***
--- 185,11 ---
  
          this.dynamicMethodType = dynamicMethodType;
          this.isSerializable = isSerializable;
          this.altInterfaces = altInterfaces;
          this.altMethods = altMethods;
+         this.quotableOpField = reflectiveField;
  
          if (interfaceMethodName.isEmpty() ||
                  interfaceMethodName.indexOf('.') >= 0 ||
                  interfaceMethodName.indexOf(';') >= 0 ||
                  interfaceMethodName.indexOf('[') >= 0 ||

*** 204,10 ***
--- 212,24 ---
                  throw new LambdaConversionException(String.format(
                          "%s is not an interface",
                          c.getName()));
              }
          }
+ 
+         if (reflectiveField != null) {
+             try {
+                 quotableOpFieldInfo = caller.revealDirect(reflectiveField); // may throw SecurityException
+             } catch (IllegalArgumentException e) {
+                 throw new LambdaConversionException(implementation + " is not direct or cannot be cracked");
+             }
+             if (quotableOpFieldInfo.getReferenceKind() != REF_getField &&
+                     quotableOpFieldInfo.getReferenceKind() != REF_getStatic) {
+                 throw new LambdaConversionException(String.format("Unsupported MethodHandle kind: %s", quotableOpFieldInfo));
+             }
+         } else {
+             quotableOpFieldInfo = null;
+         }
      }
  
      /**
       * Build the CallSite.
       *
< prev index next >