98 public static final int FLAG_SERIALIZABLE = 1 << 0; |
98 public static final int FLAG_SERIALIZABLE = 1 << 0; |
99 |
99 |
100 /** Flag for alternate metafactories indicating the lambda object has multiple targets */ |
100 /** Flag for alternate metafactories indicating the lambda object has multiple targets */ |
101 public static final int FLAG_MARKERS = 1 << 1; |
101 public static final int FLAG_MARKERS = 1 << 1; |
102 |
102 |
103 /** Flag for alternate metafactories indicating the lambda object requires multiple bridges */ |
|
104 public static final int FLAG_BRIDGES = 1 << 2; |
|
105 |
|
106 private class KlassInfo { |
103 private class KlassInfo { |
107 |
104 |
108 /** |
105 /** |
109 * list of methods to append |
106 * list of methods to append |
110 */ |
107 */ |
322 |
319 |
323 //build a sam instance using an indy call to the meta-factory |
320 //build a sam instance using an indy call to the meta-factory |
324 int refKind = referenceKind(sym); |
321 int refKind = referenceKind(sym); |
325 |
322 |
326 //convert to an invokedynamic call |
323 //convert to an invokedynamic call |
327 result = makeMetaFactoryIndyCall(context, refKind, sym, indy_args); |
324 result = makeMetaFactoryIndyCall(tree, context.needsAltMetafactory(), context.isSerializable(), refKind, sym, indy_args); |
328 } |
325 } |
329 |
326 |
330 private JCIdent makeThis(Type type, Symbol owner) { |
327 private JCIdent makeThis(Type type, Symbol owner) { |
331 VarSymbol _this = new VarSymbol(PARAMETER | FINAL | SYNTHETIC, |
328 VarSymbol _this = new VarSymbol(PARAMETER | FINAL | SYNTHETIC, |
332 names._this, |
329 names._this, |
383 |
380 |
384 List<JCExpression> indy_args = init==null? List.<JCExpression>nil() : translate(List.of(init), localContext.prev); |
381 List<JCExpression> indy_args = init==null? List.<JCExpression>nil() : translate(List.of(init), localContext.prev); |
385 |
382 |
386 |
383 |
387 //build a sam instance using an indy call to the meta-factory |
384 //build a sam instance using an indy call to the meta-factory |
388 result = makeMetaFactoryIndyCall(localContext, localContext.referenceKind(), refSym, indy_args); |
385 result = makeMetaFactoryIndyCall(tree, localContext.needsAltMetafactory(), localContext.isSerializable(), localContext.referenceKind(), refSym, indy_args); |
389 } |
386 } |
390 |
387 |
391 /** |
388 /** |
392 * Translate identifiers within a lambda to the mapped identifier |
389 * Translate identifiers within a lambda to the mapped identifier |
393 * @param tree |
390 * @param tree |
909 } |
906 } |
910 |
907 |
911 /** |
908 /** |
912 * Generate an indy method call to the meta factory |
909 * Generate an indy method call to the meta factory |
913 */ |
910 */ |
914 private JCExpression makeMetaFactoryIndyCall(TranslationContext<?> context, |
911 private JCExpression makeMetaFactoryIndyCall(JCFunctionalExpression tree, boolean needsAltMetafactory, |
915 int refKind, Symbol refSym, List<JCExpression> indy_args) { |
912 boolean isSerializable, int refKind, Symbol refSym, List<JCExpression> indy_args) { |
916 JCFunctionalExpression tree = context.tree; |
|
917 //determine the static bsm args |
913 //determine the static bsm args |
918 Type mtype = types.erasure(tree.getDescriptorType(types)); |
914 Type mtype = types.erasure(tree.descriptorType); |
919 MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym); |
915 MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym); |
920 List<Object> staticArgs = List.<Object>of( |
916 List<Object> staticArgs = List.<Object>of( |
921 new Pool.MethodHandle(ClassFile.REF_invokeInterface, |
917 new Pool.MethodHandle(ClassFile.REF_invokeInterface, |
922 types.findDescriptorSymbol(tree.type.tsym), types), |
918 types.findDescriptorSymbol(tree.type.tsym), types), |
923 new Pool.MethodHandle(refKind, refSym, types), |
919 new Pool.MethodHandle(refKind, refSym, types), |
936 MethodType indyType = new MethodType(indy_args_types.toList(), |
932 MethodType indyType = new MethodType(indy_args_types.toList(), |
937 tree.type, |
933 tree.type, |
938 List.<Type>nil(), |
934 List.<Type>nil(), |
939 syms.methodClass); |
935 syms.methodClass); |
940 |
936 |
941 Name metafactoryName = context.needsAltMetafactory() ? |
937 Name metafactoryName = needsAltMetafactory ? |
942 names.altMetaFactory : names.metaFactory; |
938 names.altMetaFactory : names.metaFactory; |
943 |
939 |
944 if (context.needsAltMetafactory()) { |
940 if (needsAltMetafactory) { |
945 ListBuffer<Object> markers = ListBuffer.lb(); |
941 ListBuffer<Object> markers = ListBuffer.lb(); |
946 for (Type t : tree.targets.tail) { |
942 for (Symbol t : tree.targets.tail) { |
947 if (t.tsym != syms.serializableType.tsym) { |
943 if (t != syms.serializableType.tsym) { |
948 markers.append(t.tsym); |
944 markers.append(t); |
949 } |
945 } |
950 } |
946 } |
951 int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0; |
947 int flags = isSerializable? FLAG_SERIALIZABLE : 0; |
952 boolean hasMarkers = markers.nonEmpty(); |
948 boolean hasMarkers = markers.nonEmpty(); |
953 boolean hasBridges = context.bridges.nonEmpty(); |
949 flags |= hasMarkers ? FLAG_MARKERS : 0; |
954 if (hasMarkers) { |
|
955 flags |= FLAG_MARKERS; |
|
956 } |
|
957 if (hasBridges) { |
|
958 flags |= FLAG_BRIDGES; |
|
959 } |
|
960 staticArgs = staticArgs.append(flags); |
950 staticArgs = staticArgs.append(flags); |
961 if (hasMarkers) { |
951 if (hasMarkers) { |
962 staticArgs = staticArgs.append(markers.length()); |
952 staticArgs = staticArgs.append(markers.length()); |
963 staticArgs = staticArgs.appendList(markers.toList()); |
953 staticArgs = staticArgs.appendList(markers.toList()); |
964 } |
954 } |
965 if (hasBridges) { |
955 if (isSerializable) { |
966 staticArgs = staticArgs.append(context.bridges.length() - 1); |
|
967 for (Symbol s : context.bridges) { |
|
968 Type s_erasure = s.erasure(types); |
|
969 if (!types.isSameType(s_erasure, samSym.erasure(types))) { |
|
970 staticArgs = staticArgs.append(s.erasure(types)); |
|
971 } |
|
972 } |
|
973 } |
|
974 if (context.isSerializable()) { |
|
975 addDeserializationCase(refKind, refSym, tree.type, samSym, |
956 addDeserializationCase(refKind, refSym, tree.type, samSym, |
976 tree, staticArgs, indyType); |
957 tree, staticArgs, indyType); |
977 } |
958 } |
978 } |
959 } |
979 |
960 |
1316 JCNewClass nc = makeNewClass(classType, make.Idents(params)); |
1297 JCNewClass nc = makeNewClass(classType, make.Idents(params)); |
1317 nc.pos = tree.pos; |
1298 nc.pos = tree.pos; |
1318 |
1299 |
1319 // Make lambda holding the new-class call |
1300 // Make lambda holding the new-class call |
1320 JCLambda slam = make.Lambda(params, nc); |
1301 JCLambda slam = make.Lambda(params, nc); |
|
1302 slam.descriptorType = tree.descriptorType; |
1321 slam.targets = tree.targets; |
1303 slam.targets = tree.targets; |
1322 slam.type = tree.type; |
1304 slam.type = tree.type; |
1323 slam.pos = tree.pos; |
1305 slam.pos = tree.pos; |
1324 |
1306 |
1325 // Now it is a lambda, process as such |
1307 // Now it is a lambda, process as such |
1650 int depth; |
1632 int depth; |
1651 |
1633 |
1652 /** the enclosing translation context (set for nested lambdas/mref) */ |
1634 /** the enclosing translation context (set for nested lambdas/mref) */ |
1653 TranslationContext<?> prev; |
1635 TranslationContext<?> prev; |
1654 |
1636 |
1655 /** list of methods to be bridged by the meta-factory */ |
|
1656 List<Symbol> bridges; |
|
1657 |
|
1658 TranslationContext(T tree) { |
1637 TranslationContext(T tree) { |
1659 this.tree = tree; |
1638 this.tree = tree; |
1660 this.owner = owner(); |
1639 this.owner = owner(); |
1661 this.depth = frameStack.size() - 1; |
1640 this.depth = frameStack.size() - 1; |
1662 this.prev = context(); |
1641 this.prev = context(); |
1663 ClassSymbol csym = |
|
1664 types.makeFunctionalInterfaceClass(attrEnv, names.empty, tree.targets, ABSTRACT | INTERFACE); |
|
1665 this.bridges = types.functionalInterfaceBridges(csym); |
|
1666 } |
1642 } |
1667 |
1643 |
1668 /** does this functional expression need to be created using alternate metafactory? */ |
1644 /** does this functional expression need to be created using alternate metafactory? */ |
1669 boolean needsAltMetafactory() { |
1645 boolean needsAltMetafactory() { |
1670 return tree.targets.length() > 1 || |
1646 return (tree.targets.length() > 1 || |
1671 isSerializable() || |
1647 isSerializable()); |
1672 bridges.length() > 1; |
|
1673 } |
1648 } |
1674 |
1649 |
1675 /** does this functional expression require serialization support? */ |
1650 /** does this functional expression require serialization support? */ |
1676 boolean isSerializable() { |
1651 boolean isSerializable() { |
1677 for (Type target : tree.targets) { |
1652 for (Symbol target : tree.targets) { |
1678 if (types.asSuper(target, syms.serializableType.tsym) != null) { |
1653 if (types.asSuper(target.type, syms.serializableType.tsym) != null) { |
1679 return true; |
1654 return true; |
1680 } |
1655 } |
1681 } |
1656 } |
1682 return false; |
1657 return false; |
1683 } |
1658 } |
1856 generatedLambdaSig(), |
1831 generatedLambdaSig(), |
1857 TreeInfo.types(syntheticParams)); |
1832 TreeInfo.types(syntheticParams)); |
1858 } |
1833 } |
1859 |
1834 |
1860 Type generatedLambdaSig() { |
1835 Type generatedLambdaSig() { |
1861 return types.erasure(tree.getDescriptorType(types)); |
1836 return types.erasure(tree.descriptorType); |
1862 } |
1837 } |
1863 } |
1838 } |
1864 |
1839 |
1865 /** |
1840 /** |
1866 * This class retains all the useful information about a method reference; |
1841 * This class retains all the useful information about a method reference; |