< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java

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

*** 136,10 ***
--- 136,13 ---
      public static final int FLAG_MARKERS = 1 << 1;
  
      /** Flag for alternate metafactories indicating the lambda object requires multiple bridges */
      public static final int FLAG_BRIDGES = 1 << 2;
  
+     /** Flag for alternate metafactories indicating the lambda object is intended to be quotable */
+     public static final int FLAG_QUOTABLE = 1 << 3;
+ 
      // <editor-fold defaultstate="collapsed" desc="Instantiating">
      protected static final Context.Key<LambdaToMethod> unlambdaKey = new Context.Key<>();
  
      public static LambdaToMethod instance(Context context) {
          LambdaToMethod instance = context.get(unlambdaKey);

*** 437,10 ***
--- 440,16 ---
          for (Symbol fv : localContext.getSymbolMap(CAPTURED_OUTER_THIS).keySet()) {
              JCExpression captured_local = make.QualThis(fv.type);
              syntheticInits.append(captured_local);
          }
  
+         if (context.isQuotable()) {
+             for (JCExpression capturedArg : tree.codeReflectionInfo.capturedArgs()) {
+                 syntheticInits.append(capturedArg);
+             }
+         }
+ 
          //then, determine the arguments to the indy call
          List<JCExpression> indy_args = translate(syntheticInits.toList(), localContext.prev);
  
          //convert to an invokedynamic call
          result = makeMetafactoryIndyCall(context, sym.asHandle(), indy_args);

*** 518,10 ***
--- 527,16 ---
                  throw new InternalError("Should not have an invalid kind");
          }
  
          List<JCExpression> indy_args = init==null? List.nil() : translate(List.of(init), localContext.prev);
  
+         if (context.isQuotable()) {
+             for (JCExpression capturedArg : tree.codeReflectionInfo.capturedArgs()) {
+                 indy_args = indy_args.append(capturedArg);
+             }
+         }
+ 
  
          //build a sam instance using an indy call to the meta-factory
          result = makeMetafactoryIndyCall(localContext, refSym.asHandle(), indy_args);
      }
  

*** 919,10 ***
--- 934,11 ---
                  JCExpression expr = (tree.getMode() == ReferenceMode.INVOKE)
                          ? expressionInvoke(rcvr)
                          : expressionNew();
  
                  JCLambda slam = make.Lambda(params.toList(), expr);
+                 slam.codeReflectionInfo = tree.codeReflectionInfo;
                  slam.target = tree.target;
                  slam.type = tree.type;
                  slam.pos = tree.pos;
                  return slam;
              } finally {

*** 1138,16 ***
--- 1154,18 ---
                      types.directSupertypes(tree.target) :
                      List.nil();
              for (Type t : targets) {
                  t = types.erasure(t);
                  if (t.tsym != syms.serializableType.tsym &&
+                     t.tsym != syms.quotableType.tsym &&
                      t.tsym != tree.type.tsym &&
                      t.tsym != syms.objectType.tsym) {
                      markers.append(t);
                  }
              }
              int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0;
+             flags |= context.isQuotable() ? FLAG_QUOTABLE : 0;
              boolean hasMarkers = markers.nonEmpty();
              boolean hasBridges = context.bridges.nonEmpty();
              if (hasMarkers) {
                  flags |= FLAG_MARKERS;
              }

*** 1166,10 ***
--- 1184,14 ---
                      if (!types.isSameType(s_erasure, samSym.erasure(types))) {
                          staticArgs = staticArgs.append(((MethodType)s.erasure(types)));
                      }
                  }
              }
+             if (context.isQuotable()) {
+                 VarSymbol reflectField = (VarSymbol)tree.codeReflectionInfo.quotedField();
+                 staticArgs = staticArgs.append(reflectField.asMethodHandle(true));
+             }
              if (context.isSerializable()) {
                  int prevPos = make.pos;
                  try {
                      make.at(kInfo.clazz);
                      addDeserializationCase(refSym, tree.type, samSym,

*** 1860,20 ***
--- 1882,25 ---
  
              /** does this functional expression need to be created using alternate metafactory? */
              boolean needsAltMetafactory() {
                  return tree.target.isIntersection() ||
                          isSerializable() ||
+                         isQuotable() ||
                          bridges.length() > 1;
              }
  
              /** does this functional expression require serialization support? */
              boolean isSerializable() {
                  if (forceSerializable) {
                      return true;
                  }
                  return types.asSuper(tree.target, syms.serializableType.tsym) != null;
              }
+ 
+             boolean isQuotable() {
+                 return tree.codeReflectionInfo != null;
+             }
  
              /**
               * @return Name of the enclosing method to be folded into synthetic
               * method name
               */
< prev index next >