提交 33e96c31 编写于 作者: R rfield

8000694: Add generation of lambda implementation code: invokedynamic call,...

8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
Summary: Add lambda implementation code with calling/supporting code elsewhere in the compiler
Reviewed-by: mcimadamore, jjg
上级 504e3bdc
......@@ -127,6 +127,7 @@ public class Symtab {
public final Type cloneableType;
public final Type serializableType;
public final Type methodHandleType;
public final Type methodHandleLookupType;
public final Type methodTypeType;
public final Type nativeHeaderType;
public final Type throwableType;
......@@ -158,6 +159,7 @@ public class Symtab {
public final Type systemType;
public final Type autoCloseableType;
public final Type trustMeType;
public final Type lambdaMetafactory;
public final Type containedByType;
public final Type containerForType;
public final Type documentedType;
......@@ -456,6 +458,7 @@ public class Symtab {
throwableType = enterClass("java.lang.Throwable");
serializableType = enterClass("java.io.Serializable");
methodHandleType = enterClass("java.lang.invoke.MethodHandle");
methodHandleLookupType = enterClass("java.lang.invoke.MethodHandles$Lookup");
methodTypeType = enterClass("java.lang.invoke.MethodType");
errorType = enterClass("java.lang.Error");
illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException");
......@@ -503,10 +506,12 @@ public class Symtab {
autoCloseableType.tsym);
trustMeType = enterClass("java.lang.SafeVarargs");
nativeHeaderType = enterClass("javax.tools.annotation.GenerateNativeHeader");
lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory");
synthesizeEmptyInterfaceIfMissing(autoCloseableType);
synthesizeEmptyInterfaceIfMissing(cloneableType);
synthesizeEmptyInterfaceIfMissing(serializableType);
synthesizeEmptyInterfaceIfMissing(lambdaMetafactory);
synthesizeBoxTypeIfMissing(doubleType);
synthesizeBoxTypeIfMissing(floatType);
synthesizeBoxTypeIfMissing(voidType);
......
......@@ -120,6 +120,16 @@ public class TransTypes extends TreeTranslator {
* @param tree The expression tree.
* @param target The target type.
*/
public JCExpression coerce(Env<AttrContext> env, JCExpression tree, Type target) {
Env<AttrContext> prevEnv = this.env;
try {
this.env = env;
return coerce(tree, target);
}
finally {
this.env = prevEnv;
}
}
JCExpression coerce(JCExpression tree, Type target) {
Type btarget = target.baseType();
if (tree.type.isPrimitive() == target.isPrimitive()) {
......@@ -196,6 +206,20 @@ public class TransTypes extends TreeTranslator {
return _args;
}
public <T extends JCTree> List<T> translateArgs(List<T> _args,
List<Type> parameters,
Type varargsElement,
Env<AttrContext> localEnv) {
Env<AttrContext> prevEnv = env;
try {
env = localEnv;
return translateArgs(_args, parameters, varargsElement);
}
finally {
env = prevEnv;
}
}
/** Add a bridge definition and enter corresponding method symbol in
* local scope of origin.
*
......@@ -451,9 +475,9 @@ public class TransTypes extends TreeTranslator {
result = tree;
}
JCMethodDecl currentMethod = null;
JCTree currentMethod = null;
public void visitMethodDef(JCMethodDecl tree) {
JCMethodDecl previousMethod = currentMethod;
JCTree previousMethod = currentMethod;
try {
currentMethod = tree;
tree.restype = translate(tree.restype, null);
......@@ -519,6 +543,22 @@ public class TransTypes extends TreeTranslator {
result = tree;
}
public void visitLambda(JCLambda tree) {
JCTree prevMethod = currentMethod;
try {
currentMethod = null;
tree.params = translate(tree.params);
tree.body = translate(tree.body, null);
//save non-erased target
tree.targetType = tree.type;
tree.type = erasure(tree.type);
result = tree;
}
finally {
currentMethod = prevMethod;
}
}
public void visitSwitch(JCSwitch tree) {
Type selsuper = types.supertype(tree.selector.type);
boolean enumSwitch = selsuper != null &&
......@@ -570,7 +610,7 @@ public class TransTypes extends TreeTranslator {
}
public void visitReturn(JCReturn tree) {
tree.expr = translate(tree.expr, currentMethod.sym.erasure(types).getReturnType());
tree.expr = translate(tree.expr, currentMethod != null ? types.erasure(currentMethod.type).getReturnType() : null);
result = tree;
}
......@@ -601,6 +641,7 @@ public class TransTypes extends TreeTranslator {
Assert.check(tree.args.length() == argtypes.length());
tree.args = translateArgs(tree.args, argtypes, tree.varargsElement);
tree.type = types.erasure(tree.type);
// Insert casts of method invocation results as needed.
result = retype(tree, mt.getReturnType(), pt);
}
......@@ -614,6 +655,8 @@ public class TransTypes extends TreeTranslator {
tree.args = translateArgs(
tree.args, tree.constructor.erasure(types).getParameterTypes(), tree.varargsElement);
tree.def = translate(tree.def, null);
if (tree.constructorType != null)
tree.constructorType = erasure(tree.constructorType);
tree.type = erasure(tree.type);
result = tree;
}
......@@ -631,16 +674,6 @@ public class TransTypes extends TreeTranslator {
result = tree;
}
@Override
public void visitLambda(JCLambda tree) {
Assert.error("Translation of lambda expression not supported yet");
}
@Override
public void visitReference(JCMemberReference tree) {
Assert.error("Translation of method reference not supported yet");
}
public void visitParens(JCParens tree) {
tree.expr = translate(tree.expr, pt);
tree.type = erasure(tree.type);
......@@ -749,6 +782,14 @@ public class TransTypes extends TreeTranslator {
}
}
public void visitReference(JCMemberReference tree) {
tree.expr = translate(tree.expr, null);
//save non-erased target
tree.targetType = tree.type;
tree.type = erasure(tree.type);
result = tree;
}
public void visitTypeArray(JCArrayTypeTree tree) {
tree.elemtype = translate(tree.elemtype, null);
tree.type = erasure(tree.type);
......
......@@ -271,6 +271,10 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
*/
protected TransTypes transTypes;
/** The lambda translator.
*/
protected LambdaToMethod lambdaToMethod;
/** The syntactic sugar desweetener.
*/
protected Lower lower;
......@@ -369,6 +373,8 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
options = Options.instance(context);
lambdaToMethod = LambdaToMethod.instance(context);
verbose = options.isSet(VERBOSE);
sourceOutput = options.isSet(PRINTSOURCE); // used to be -s
stubOutput = options.isSet("-stubs");
......@@ -524,8 +530,10 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
ATTR(4),
FLOW(5),
TRANSTYPES(6),
LOWER(7),
GENERATE(8);
UNLAMBDA(7),
LOWER(8),
GENERATE(9);
CompileState(int value) {
this.value = value;
}
......@@ -1418,6 +1426,12 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
compileStates.put(env, CompileState.TRANSTYPES);
if (shouldStop(CompileState.UNLAMBDA))
return;
env.tree = lambdaToMethod.translateTopLevelClass(env, env.tree, localMake);
compileStates.put(env, CompileState.UNLAMBDA);
if (shouldStop(CompileState.LOWER))
return;
......
......@@ -170,6 +170,10 @@ public class Names {
public final Name ex;
public final Name package_info;
//lambda-related
public final Name lambda;
public final Name metaFactory;
public final Name.Table table;
public Names(Context context) {
......@@ -298,6 +302,10 @@ public class Names {
deprecated = fromString("deprecated");
ex = fromString("ex");
package_info = fromString("package-info");
//lambda-related
lambda = fromString("lambda");
metaFactory = fromString("metaFactory");
}
protected Name.Table createTable(Options options) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册