< prev index next > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
Print this page
/*
- * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
+ * 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
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);
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);
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);
}
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 {
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;
}
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,
/** 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 >