summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2016-07-20 17:36:54 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2016-07-20 21:13:39 +0200
commite619b033350a3378d650db4c3e5b1bfc83b73d81 (patch)
tree44abc925a9e9fc4a77a75a1983c42654c7cf8f89
parent5ddb0bbe36e7caa44c9442b059d103f7f4e75331 (diff)
downloadscala-e619b033350a3378d650db4c3e5b1bfc83b73d81.tar.gz
scala-e619b033350a3378d650db4c3e5b1bfc83b73d81.tar.bz2
scala-e619b033350a3378d650db4c3e5b1bfc83b73d81.zip
Upgrade asm to 5.1
The constructor of scala.tools.asm.Handle now takes an additional boolean parameter to denote whether the owner is an interface.
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala3
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala34
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala16
-rw-r--r--src/partest-extras/scala/tools/partest/ASMConverters.scala6
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--test/files/run/classfile-format-51.scala2
-rw-r--r--test/files/run/noInlineUnknownIndy/Test.scala7
-rw-r--r--versions.properties2
9 files changed, 47 insertions, 32 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index 55fe47bde6..acedf83016 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -1334,11 +1334,13 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
val isStaticMethod = lambdaTarget.hasFlag(Flags.STATIC)
def asmType(sym: Symbol) = classBTypeFromSymbol(sym).toASMType
+ val isInterface = lambdaTarget.owner.isTrait
val implMethodHandle =
- new asm.Handle(if (lambdaTarget.hasFlag(Flags.STATIC)) asm.Opcodes.H_INVOKESTATIC else if (lambdaTarget.owner.isTrait) asm.Opcodes.H_INVOKEINTERFACE else asm.Opcodes.H_INVOKEVIRTUAL,
+ new asm.Handle(if (lambdaTarget.hasFlag(Flags.STATIC)) asm.Opcodes.H_INVOKESTATIC else if (isInterface) asm.Opcodes.H_INVOKEINTERFACE else asm.Opcodes.H_INVOKEVIRTUAL,
classBTypeFromSymbol(lambdaTarget.owner).internalName,
lambdaTarget.name.toString,
- methodBTypeFromSymbol(lambdaTarget).descriptor)
+ methodBTypeFromSymbol(lambdaTarget).descriptor,
+ /* itf = */ isInterface)
val receiver = if (isStaticMethod) Nil else lambdaTarget.owner :: Nil
val (capturedParams, lambdaParams) = lambdaTarget.paramss.head.splitAt(lambdaTarget.paramss.head.length - arity)
// Requires https://github.com/scala/scala-java8-compat on the runtime classpath
@@ -1351,7 +1353,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
val flags = java.lang.invoke.LambdaMetafactory.FLAG_SERIALIZABLE | java.lang.invoke.LambdaMetafactory.FLAG_MARKERS
val ScalaSerializable = classBTypeFromSymbol(definitions.SerializableClass).toASMType
- bc.jmethod.visitInvokeDynamicInsn(samName, invokedType, lambdaMetaFactoryBootstrapHandle,
+ bc.jmethod.visitInvokeDynamicInsn(samName, invokedType, lambdaMetaFactoryAltMetafactoryHandle,
/* samMethodType = */ samMethodType,
/* implMethod = */ implMethodHandle,
/* instantiatedMethodType = */ constrainedType,
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
index 1a4590e7d1..383347a0d3 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
@@ -157,7 +157,8 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
def staticHandleFromSymbol(sym: Symbol): asm.Handle = {
val owner = if (sym.owner.isModuleClass) sym.owner.linkedClassOfClass else sym.owner
val descriptor = methodBTypeFromMethodType(sym.info, isConstructor = false).descriptor
- new asm.Handle(asm.Opcodes.H_INVOKESTATIC, classBTypeFromSymbol(owner).internalName, sym.name.encoded, descriptor)
+ val ownerBType = classBTypeFromSymbol(owner)
+ new asm.Handle(asm.Opcodes.H_INVOKESTATIC, ownerBType.internalName, sym.name.encoded, descriptor, /* itf = */ ownerBType.isInterface.get)
}
/**
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
index d65380aa1f..c2010d2828 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
@@ -248,7 +248,22 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes: BTFS) {
})
}
- lazy val lambdaMetaFactoryBootstrapHandle =
+ lazy val lambdaMetaFactoryMetafactoryHandle =
+ new asm.Handle(asm.Opcodes.H_INVOKESTATIC,
+ coreBTypes.jliLambdaMetafactoryRef.internalName, sn.Metafactory.toString,
+ MethodBType(
+ List(
+ coreBTypes.jliMethodHandlesLookupRef,
+ coreBTypes.StringRef,
+ coreBTypes.jliMethodTypeRef,
+ coreBTypes.jliMethodTypeRef,
+ coreBTypes.jliMethodHandleRef,
+ coreBTypes.jliMethodTypeRef),
+ coreBTypes.jliCallSiteRef
+ ).descriptor,
+ /* itf = */ coreBTypes.jliLambdaMetafactoryRef.isInterface.get)
+
+ lazy val lambdaMetaFactoryAltMetafactoryHandle =
new asm.Handle(asm.Opcodes.H_INVOKESTATIC,
coreBTypes.jliLambdaMetafactoryRef.internalName, sn.AltMetafactory.toString,
MethodBType(
@@ -258,7 +273,8 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes: BTFS) {
coreBTypes.jliMethodTypeRef,
ArrayBType(ObjectRef)),
coreBTypes.jliCallSiteRef
- ).descriptor)
+ ).descriptor,
+ /* itf = */ coreBTypes.jliLambdaMetafactoryRef.isInterface.get)
lazy val lambdaDeserializeBootstrapHandle =
new scala.tools.asm.Handle(scala.tools.asm.Opcodes.H_INVOKESTATIC,
@@ -270,7 +286,8 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes: BTFS) {
coreBTypes.jliMethodTypeRef
),
coreBTypes.jliCallSiteRef
- ).descriptor)
+ ).descriptor,
+ /* itf = */ coreBTypes.srLambdaDeserialize.isInterface.get)
}
/**
@@ -299,6 +316,7 @@ trait CoreBTypesProxyGlobalIndependent[BTS <: BTypes] {
def juHashMapRef : ClassBType
def juMapRef : ClassBType
def jliCallSiteRef : ClassBType
+ def jliLambdaMetafactoryRef : ClassBType
def jliMethodTypeRef : ClassBType
def jliSerializedLambdaRef : ClassBType
def jliMethodHandleRef : ClassBType
@@ -322,8 +340,9 @@ trait CoreBTypesProxyGlobalIndependent[BTS <: BTypes] {
def srRefConstructors : Map[InternalName, MethodNameAndType]
def tupleClassConstructors : Map[InternalName, MethodNameAndType]
- def lambdaMetaFactoryBootstrapHandle : asm.Handle
- def lambdaDeserializeBootstrapHandle : asm.Handle
+ def lambdaMetaFactoryMetafactoryHandle : asm.Handle
+ def lambdaMetaFactoryAltMetafactoryHandle : asm.Handle
+ def lambdaDeserializeBootstrapHandle : asm.Handle
}
/**
@@ -405,6 +424,7 @@ final class CoreBTypesProxy[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes:
def String_valueOf: Symbol = _coreBTypes.String_valueOf
- def lambdaMetaFactoryBootstrapHandle = _coreBTypes.lambdaMetaFactoryBootstrapHandle
- def lambdaDeserializeBootstrapHandle = _coreBTypes.lambdaDeserializeBootstrapHandle
+ def lambdaMetaFactoryMetafactoryHandle : asm.Handle = _coreBTypes.lambdaMetaFactoryMetafactoryHandle
+ def lambdaMetaFactoryAltMetafactoryHandle : asm.Handle = _coreBTypes.lambdaMetaFactoryAltMetafactoryHandle
+ def lambdaDeserializeBootstrapHandle : asm.Handle = _coreBTypes.lambdaDeserializeBootstrapHandle
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
index 5248183337..b088b5ee48 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
@@ -413,22 +413,8 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
final case class LambdaMetaFactoryCall(indy: InvokeDynamicInsnNode, samMethodType: Type, implMethod: Handle, instantiatedMethodType: Type)
object LambdaMetaFactoryCall {
- private val lambdaMetaFactoryInternalName: InternalName = "java/lang/invoke/LambdaMetafactory"
-
- private val metafactoryHandle = {
- val metafactoryMethodName: String = "metafactory"
- val metafactoryDesc: String = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"
- new Handle(Opcodes.H_INVOKESTATIC, lambdaMetaFactoryInternalName, metafactoryMethodName, metafactoryDesc)
- }
-
- private val altMetafactoryHandle = {
- val altMetafactoryMethodName: String = "altMetafactory"
- val altMetafactoryDesc: String = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;"
- new Handle(Opcodes.H_INVOKESTATIC, lambdaMetaFactoryInternalName, altMetafactoryMethodName, altMetafactoryDesc)
- }
-
def unapply(insn: AbstractInsnNode): Option[(InvokeDynamicInsnNode, Type, Handle, Type)] = insn match {
- case indy: InvokeDynamicInsnNode if indy.bsm == metafactoryHandle || indy.bsm == altMetafactoryHandle =>
+ case indy: InvokeDynamicInsnNode if indy.bsm == coreBTypes.lambdaMetaFactoryMetafactoryHandle || indy.bsm == coreBTypes.lambdaMetaFactoryAltMetafactoryHandle =>
indy.bsmArgs match {
case Array(samMethodType: Type, implMethod: Handle, instantiatedMethodType: Type, _@_*) =>
// LambdaMetaFactory performs a number of automatic adaptations when invoking the lambda
diff --git a/src/partest-extras/scala/tools/partest/ASMConverters.scala b/src/partest-extras/scala/tools/partest/ASMConverters.scala
index a3d849a9c1..445d3c89c2 100644
--- a/src/partest-extras/scala/tools/partest/ASMConverters.scala
+++ b/src/partest-extras/scala/tools/partest/ASMConverters.scala
@@ -94,7 +94,7 @@ object ASMConverters {
case class FrameEntry (`type`: Int, local: List[Any], stack: List[Any]) extends Instruction { def opcode: Int = -1 }
case class LineNumber (line: Int, start: Label) extends Instruction { def opcode: Int = -1 }
- case class MethodHandle(tag: Int, owner: String, name: String, desc: String)
+ case class MethodHandle(tag: Int, owner: String, name: String, desc: String, itf: Boolean)
case class ExceptionHandler(start: Label, end: Label, handler: Label, desc: Option[String])
case class LocalVariable(name: String, desc: String, signature: Option[String], start: Label, end: Label, index: Int)
@@ -147,7 +147,7 @@ object ASMConverters {
case _ => a // can be: Class, method Type, primitive constant
})(collection.breakOut)
- private def convertMethodHandle(h: asm.Handle): MethodHandle = MethodHandle(h.getTag, h.getOwner, h.getName, h.getDesc)
+ private def convertMethodHandle(h: asm.Handle): MethodHandle = MethodHandle(h.getTag, h.getOwner, h.getName, h.getDesc, h.isInterface)
private def convertHandlers(method: t.MethodNode): List[ExceptionHandler] = {
method.tryCatchBlocks.asScala.map(h => ExceptionHandler(applyLabel(h.start), applyLabel(h.end), applyLabel(h.handler), Option(h.`type`)))(collection.breakOut)
@@ -227,7 +227,7 @@ object ASMConverters {
case x => x.asInstanceOf[Object]
}
- def unconvertMethodHandle(h: MethodHandle): asm.Handle = new asm.Handle(h.tag, h.owner, h.name, h.desc)
+ def unconvertMethodHandle(h: MethodHandle): asm.Handle = new asm.Handle(h.tag, h.owner, h.name, h.desc, h.itf)
def unconvertBsmArgs(a: List[Object]): Array[Object] = a.map({
case h: MethodHandle => unconvertMethodHandle(h)
case o => o
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 4f5a545c95..11b5db9793 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -1171,6 +1171,7 @@ trait StdNames {
final val Invoke: TermName = newTermName("invoke")
final val InvokeExact: TermName = newTermName("invokeExact")
+ final val Metafactory: TermName = newTermName("metafactory")
final val AltMetafactory: TermName = newTermName("altMetafactory")
final val Bootstrap: TermName = newTermName("bootstrap")
diff --git a/test/files/run/classfile-format-51.scala b/test/files/run/classfile-format-51.scala
index 3a6c4861f1..40eebee198 100644
--- a/test/files/run/classfile-format-51.scala
+++ b/test/files/run/classfile-format-51.scala
@@ -80,7 +80,7 @@ object Test extends DirectTest {
val test = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "test", s"()Ljava/lang/String;", null, null)
test.visitCode()
- val bootstrapHandle = new Handle(H_INVOKESTATIC, invokerClassName, bootstrapMethodName, bootStrapMethodType)
+ val bootstrapHandle = new Handle(H_INVOKESTATIC, invokerClassName, bootstrapMethodName, bootStrapMethodType, /* itf = */ false)
test.visitInvokeDynamicInsn("invoke", targetMethodType, bootstrapHandle)
test.visitInsn(ARETURN)
test.visitMaxs(1, 1)
diff --git a/test/files/run/noInlineUnknownIndy/Test.scala b/test/files/run/noInlineUnknownIndy/Test.scala
index c6d227b6f2..a666146f15 100644
--- a/test/files/run/noInlineUnknownIndy/Test.scala
+++ b/test/files/run/noInlineUnknownIndy/Test.scala
@@ -15,7 +15,12 @@ object Test extends DirectTest {
}
def show(): Unit = {
- val unknownBootstrapMethod = new Handle(Opcodes.H_INVOKESTATIC, "not/java/lang/SomeLambdaMetafactory", "notAMetaFactoryMethod", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;")
+ val unknownBootstrapMethod = new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "not/java/lang/SomeLambdaMetafactory",
+ "notAMetaFactoryMethod",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+ /* itf = */ false)
modifyClassFile(new File(testOutput.toFile, "A_1.class"))((cn: ClassNode) => {
val testMethod = cn.methods.iterator.asScala.find(_.name == "test").head
val indy = testMethod.instructions.iterator.asScala.collect({ case i: InvokeDynamicInsnNode => i }).next()
diff --git a/versions.properties b/versions.properties
index 4d24e0d598..ed90768780 100644
--- a/versions.properties
+++ b/versions.properties
@@ -27,7 +27,7 @@ scala-parser-combinators.version.number=1.0.4
scala-swing.version.number=2.0.0-M2
scala-swing.version.osgi=2.0.0.M2
jline.version=2.14.1
-scala-asm.version=5.0.4-scala-3
+scala-asm.version=5.1.0-scala-1
# external modules, used internally (not shipped)
partest.version.number=1.0.17