diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2015-03-09 14:20:17 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2015-04-21 16:51:00 +1000 |
commit | 7be7786a67323b5c138eab650c9bf0d23924a688 (patch) | |
tree | 73452d2cd5ef1dd75b6535f038bcbcae40483098 /src/reflect | |
parent | 555f8f09c90b7014f153488e442f2d107b18b6e5 (diff) | |
download | scala-7be7786a67323b5c138eab650c9bf0d23924a688.tar.gz scala-7be7786a67323b5c138eab650c9bf0d23924a688.tar.bz2 scala-7be7786a67323b5c138eab650c9bf0d23924a688.zip |
SI-8359 Emit invokedynamic for lambdas
Suitable lambdas are identified in Delambdafy and marked with
such with a tree annotation that includes the
data needed by the backend to emit an invokedynamic instruction.
GenBCode to rewrite instantiation of such anonymous
function classes with an invokedynamic instruction. At this
stage, I don't plan to merge the support for this into GenASM.
Between these points, the lambda capture is represented as an
application of a dummy factory symbol:
```
<dummy>(captures...) : FunctionN
```
Demo:
```
% wget http://central.maven.org/maven2/org/scala-lang/modules/scala-java8-compat_2.11/0.3.0/scala-java8-compat_2.11-0.3.0.jar
% qscala -classpath scala-java8-compat_2.11-0.3.0.jar -Ydelambdafy:method -target:jvm-1.8 -Ybackend:GenBCode
Welcome to Scala version 2.11.6-20150309-144147-c91c978c81 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25).
Type in expressions to have them evaluated.
Type :help for more information.
scala> (() => "").getClass
res0: Class[_ <: () => String] = class $$Lambda$1/871790326
```
I have also corrected an error in a previous commit. The newly added
symbol test, `isDelambdafyTarget`, needs to check for the `ARTIFACT`
flag, as that is what is added to the method by `Uncurry`.
Diffstat (limited to 'src/reflect')
-rw-r--r-- | src/reflect/scala/reflect/internal/Definitions.scala | 4 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 2 |
2 files changed, 5 insertions, 1 deletions
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 756ed870ca..98fd8e2361 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -1513,6 +1513,10 @@ trait Definitions extends api.StandardDefinitions { def isPolymorphicSignature(sym: Symbol) = PolySigMethods(sym) private lazy val PolySigMethods: Set[Symbol] = Set[Symbol](MethodHandle.info.decl(sn.Invoke), MethodHandle.info.decl(sn.InvokeExact)).filter(_.exists) + + lazy val Scala_Java8_CompatPackage = rootMirror.getPackageIfDefined("scala.compat.java8") + lazy val Scala_Java8_CompatPackage_JFunction = (0 to MaxTupleArity).toArray map (i => getMemberIfDefined(Scala_Java8_CompatPackage.moduleClass, TypeName("JFunction" + i))) + lazy val Scala_Java8_CompatPackage_JProcedure = (0 to MaxTupleArity).toArray map (i => getMemberIfDefined(Scala_Java8_CompatPackage.moduleClass, TypeName("JProcedure" + i))) } } } diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 4a39712ad7..a96948cb69 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -794,7 +794,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME) final def isDelambdafyFunction = isSynthetic && (name containsName tpnme.DELAMBDAFY_LAMBDA_CLASS_NAME) - final def isDelambdafyTarget = isSynthetic && isMethod && (name containsName tpnme.ANON_FUN_NAME) + final def isDelambdafyTarget = isArtifact && isMethod && (name containsName tpnme.ANON_FUN_NAME) final def isDefinedInPackage = effectiveOwner.isPackageClass final def needsFlatClasses = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass |