diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2016-12-12 13:05:28 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2016-12-12 22:02:24 +1000 |
commit | 1ff714b83795bff6604ef39604511ed896a49eea (patch) | |
tree | e3bb84fafa393b1121b746778d6fa076c8fa6293 /src/reflect/scala/reflect | |
parent | 3de1c0c56ee530f4e75533fc9e1909fe0cde31b5 (diff) | |
download | scala-1ff714b83795bff6604ef39604511ed896a49eea.tar.gz scala-1ff714b83795bff6604ef39604511ed896a49eea.tar.bz2 scala-1ff714b83795bff6604ef39604511ed896a49eea.zip |
Compiler support for JEP-193 VarHandle polymorphic signatures
VarHandles bring a host of new "polymorphic signature" methods to
the Java 9 standard library. This commit updates the way we detect
such methods to look at the absense/presense of the
`PolymorphicSignature` annotation, so as to include these (and any
future additions.)
When we see applications of such methods, we disable adaptation
of argument and return types.
Tested manually with JDK9-ea:
```
Welcome to Scala 2.12.2-20161208-165912-3de1c0c (Java HotSpot(TM) 64-Bit Server VM, Java 9-ea).
Type in expressions for evaluation. Or try :help.
scala> import java.lang.invoke._, scala.runtime.IntRef
import java.lang.invoke._
import scala.runtime.IntRef
scala> val varHandle = MethodHandles.lookup().in(classOf[IntRef]).findVarHandle(classOf[IntRef], "elem", classOf[Int]);
varHandle: java.lang.invoke.VarHandle = java.lang.invoke.VarHandleInts$FieldInstanceReadWrite@7112ce6
scala> varHandle.getAndSet(ref, 1): Int
res5: Int = 0
scala> varHandle.getAndSet(ref, 1): Int
res6: Int = 1
```
Inspecting bytecode shows the absense of box/unboxing:
```
object Test {
import java.lang.invoke._, scala.runtime.IntRef
val varHandle = MethodHandles.lookup().in(classOf[IntRef]).findVarHandle(classOf[IntRef], "elem", classOf[Int]);
def main(args: Array[String]): Unit = {
val i : Int = varHandle.getAndSet(IntRef.zero, 1)
}
}
```
```
public void main(java.lang.String[]);
Code:
0: aload_0
1: invokevirtual #28 // Method varHandle:()Ljava/lang/invoke/VarHandle;
4: invokestatic #34 // Method scala/runtime/IntRef.zero:()Lscala/runtime/IntRef;
7: iconst_1
8: invokevirtual #40 // Method java/lang/invoke/VarHandle.getAndSet:(Lscala/runtime/IntRef;I)I
11: istore_2
12: return
```
Diffstat (limited to 'src/reflect/scala/reflect')
-rw-r--r-- | src/reflect/scala/reflect/internal/Definitions.scala | 10 | ||||
-rw-r--r-- | src/reflect/scala/reflect/runtime/JavaUniverseForce.scala | 3 |
2 files changed, 9 insertions, 4 deletions
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index fc7e184918..19460af27f 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -537,7 +537,8 @@ trait Definitions extends api.StandardDefinitions { lazy val ScalaSignatureAnnotation = requiredClass[scala.reflect.ScalaSignature] lazy val ScalaLongSignatureAnnotation = requiredClass[scala.reflect.ScalaLongSignature] - lazy val MethodHandle = getClassIfDefined("java.lang.invoke.MethodHandle") + lazy val MethodHandleClass = getClassIfDefined("java.lang.invoke.MethodHandle") + lazy val VarHandleClass = getClassIfDefined("java.lang.invoke.VarHandle") // Option classes lazy val OptionClass: ClassSymbol = requiredClass[Option[_]] @@ -1567,9 +1568,12 @@ trait Definitions extends api.StandardDefinitions { lazy val PartialManifestClass = getTypeMember(ReflectPackage, tpnme.ClassManifest) lazy val ManifestSymbols = Set[Symbol](PartialManifestClass, FullManifestClass, OptManifestClass) + private lazy val PolymorphicSignatureClass = MethodHandleClass.companionModule.info.decl(TypeName("PolymorphicSignature")) - 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) + def isPolymorphicSignature(sym: Symbol) = sym != null && sym.isJavaDefined && { + val owner = sym.safeOwner + (owner == MethodHandleClass || owner == VarHandleClass) && sym.hasAnnotation(PolymorphicSignatureClass) + } lazy val Scala_Java8_CompatPackage = rootMirror.getPackageIfDefined("scala.runtime.java8") } diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index d5d62b2203..95d6662d14 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -323,7 +323,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.QuasiquoteClass_api_unapply definitions.ScalaSignatureAnnotation definitions.ScalaLongSignatureAnnotation - definitions.MethodHandle + definitions.MethodHandleClass + definitions.VarHandleClass definitions.OptionClass definitions.OptionModule definitions.SomeClass |