summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
diff options
context:
space:
mode:
authorGilles Dubochet <gilles.dubochet@epfl.ch>2010-04-29 17:01:22 +0000
committerGilles Dubochet <gilles.dubochet@epfl.ch>2010-04-29 17:01:22 +0000
commit5b937bacd38c34718e16989f3752e1f582ae2698 (patch)
tree6b14bd7647a353d9f39f3973a6e0e3444b738066 /src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
parent8eb1d0c6ac940438b5f81d832dd3d0ab26de1ff5 (diff)
downloadscala-5b937bacd38c34718e16989f3752e1f582ae2698.tar.gz
scala-5b937bacd38c34718e16989f3752e1f582ae2698.tar.bz2
scala-5b937bacd38c34718e16989f3752e1f582ae2698.zip
Closes #3310 (very large Scala class is compile...
Closes #3310 (very large Scala class is compiled to invalid classfile because Scala signature can't fit into constant pool). Review by dragos.
Diffstat (limited to 'src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index fc635874a6..7cd32ff81e 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -377,6 +377,26 @@ abstract class ClassfileParser {
value
}
+ def getBytes(indices: List[Int]): Array[Byte] = {
+ assert(!indices.isEmpty)
+ var value = values(indices.head).asInstanceOf[Array[Byte]]
+ if (value eq null) {
+ val bytesBuffer = ArrayBuffer.empty[Byte]
+ for (index <- indices) {
+ if (index <= 0 || ConstantPool.this.len <= index) errorBadIndex(index)
+ val start = starts(index)
+ if (in.buf(start).toInt != CONSTANT_UTF8) errorBadTag(start)
+ val len = in.getChar(start + 1)
+ bytesBuffer ++= (in.buf, start + 3, len)
+ }
+ val bytes = bytesBuffer.toArray
+ val decodedLength = reflect.generic.ByteCodecs.decode(bytes)
+ value = bytes.take(decodedLength)
+ values(indices.head) = value
+ }
+ value
+ }
+
/** Throws an exception signaling a bad constant index. */
private def errorBadIndex(index: Int) =
throw new RuntimeException("bad constant pool index: " + index + " at pos: " + in.bp)
@@ -923,6 +943,24 @@ abstract class ClassfileParser {
Some(ScalaSigBytes(pool.getBytes(in.nextChar)))
}
+ def parseScalaLongSigBytes: Option[ScalaSigBytes] = try {
+ val tag = in.nextByte.toChar
+ assert(tag == ARRAY_TAG)
+ val stringCount = in.nextChar
+ val entries =
+ for (i <- 0 until stringCount) yield {
+ val stag = in.nextByte.toChar
+ assert(stag == STRING_TAG)
+ in.nextChar.toInt
+ }
+ Some(ScalaSigBytes(pool.getBytes(entries.toList)))
+ }
+ catch {
+ case e: Throwable =>
+ e.printStackTrace
+ throw e
+ }
+
/** Parse and return a single annotation. If it is malformed,
* return None.
*/
@@ -941,6 +979,11 @@ abstract class ClassfileParser {
case Some(c) => nvpairs += ((name, c))
case None => hasError = true
}
+ else if ((attrType == definitions.ScalaLongSignatureAnnotation.tpe) && (name == nme.bytes))
+ parseScalaLongSigBytes match {
+ case Some(c) => nvpairs += ((name, c))
+ case None => hasError = true
+ }
else
parseAnnotArg match {
case Some(c) => nvpairs += ((name, c))
@@ -981,6 +1024,8 @@ abstract class ClassfileParser {
parseAnnotation(in.nextChar) match {
case Some(scalaSig) if (scalaSig.atp == definitions.ScalaSignatureAnnotation.tpe) =>
scalaSigAnnot = Some(scalaSig)
+ case Some(scalaSig) if (scalaSig.atp == definitions.ScalaLongSignatureAnnotation.tpe) =>
+ scalaSigAnnot = Some(scalaSig)
case Some(annot) =>
sym.addAnnotation(annot)
case None =>