Skip to content

Commit 28c5f73

Browse files
committed
SI-7556 Fix runtime reflection involving ScalaLongSignature
Scala type information is stored in classfiles in encoded in a String in the ScalaSignature annotation. When it is too big for a single String, it is split into an array of Strings in a different annotation, ScalaLongSignature. The enclosed test, with a class containing 3000 methods, uses the latter. It exposes a bug in the way runtime reflection decodes that data. It must concatentate and *then* decode, rather that the other way around.
1 parent 681f207 commit 28c5f73

File tree

4 files changed

+3019
-9
lines changed

4 files changed

+3019
-9
lines changed

src/reflect/scala/reflect/runtime/JavaMirrors.scala

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -567,15 +567,10 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
567567
loadBytes[Array[String]]("scala.reflect.ScalaLongSignature") match {
568568
case Some(slsig) =>
569569
info(s"unpickling Scala $clazz and $module with long Scala signature")
570-
val byteSegments = slsig map (_.getBytes)
571-
val lens = byteSegments map ByteCodecs.decode
572-
val bytes = Array.ofDim[Byte](lens.sum)
573-
var len = 0
574-
for ((bs, l) <- byteSegments zip lens) {
575-
bs.copyToArray(bytes, len, l)
576-
len += l
577-
}
578-
unpickler.unpickle(bytes, 0, clazz, module, jclazz.getName)
570+
val encoded = slsig flatMap (_.getBytes)
571+
val len = ByteCodecs.decode(encoded)
572+
val decoded = encoded.take(len)
573+
unpickler.unpickle(decoded, 0, clazz, module, jclazz.getName)
579574
case None =>
580575
// class does not have a Scala signature; it's a Java class
581576
info("translating reflection info for Java " + jclazz) //debug

test/files/run/t7556.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class annotations: List(scala.reflect.ScalaLongSignature)
2+
3001 decls via runtime reflection

test/files/run/t7556/Test_2.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import scala.reflect.runtime.universe._
2+
3+
object Test {
4+
def main(args: Array[String]) {
5+
val mc = new MegaClass
6+
val anns = mc.getClass.getAnnotations.map(_.annotationType.getName).toList.sorted
7+
println(s"class annotations: $anns")
8+
val N = typeTag[MegaClass].tpe.declarations.size // was: error reading Scala signature of MegaClass: 65935
9+
println(s"$N decls via runtime reflection")
10+
}
11+
}

0 commit comments

Comments
 (0)