diff options
author | Gilles Dubochet <gilles.dubochet@epfl.ch> | 2010-04-29 17:01:22 +0000 |
---|---|---|
committer | Gilles Dubochet <gilles.dubochet@epfl.ch> | 2010-04-29 17:01:22 +0000 |
commit | 5b937bacd38c34718e16989f3752e1f582ae2698 (patch) | |
tree | 6b14bd7647a353d9f39f3973a6e0e3444b738066 /src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala | |
parent | 8eb1d0c6ac940438b5f81d832dd3d0ab26de1ff5 (diff) | |
download | scala-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.scala | 45 |
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 => |