summaryrefslogtreecommitdiff
path: root/src/scalap
diff options
context:
space:
mode:
authorGilles Dubochet <gilles.dubochet@epfl.ch>2010-03-29 12:40:39 +0000
committerGilles Dubochet <gilles.dubochet@epfl.ch>2010-03-29 12:40:39 +0000
commit83c817f84c7268a1ba729f8e0ef90336906bfc58 (patch)
tree550ce55c9cd94a224375fa368720ece208089330 /src/scalap
parentf500aeb1fda09b3d0c142da1307694ab4dacc883 (diff)
downloadscala-83c817f84c7268a1ba729f8e0ef90336906bfc58.tar.gz
scala-83c817f84c7268a1ba729f8e0ef90336906bfc58.tar.bz2
scala-83c817f84c7268a1ba729f8e0ef90336906bfc58.zip
Fix to the way Scalap decodes ScalaSignature an...
Fix to the way Scalap decodes ScalaSignature annotations. Contributed by ilyas. Already reviewed by dubochet, no review.
Diffstat (limited to 'src/scalap')
-rw-r--r--src/scalap/scala/tools/scalap/Main.scala4
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala25
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala2
3 files changed, 23 insertions, 8 deletions
diff --git a/src/scalap/scala/tools/scalap/Main.scala b/src/scalap/scala/tools/scalap/Main.scala
index 7ac3955d45..ef2a4b438a 100644
--- a/src/scalap/scala/tools/scalap/Main.scala
+++ b/src/scalap/scala/tools/scalap/Main.scala
@@ -119,8 +119,8 @@ object Main {
case None => ""
case Some(Annotation(_, elements)) =>
val bytesElem = elements.find(elem => constant(elem.elementNameIndex) == BYTES_VALUE).get
- val sigString = (bytesElem.elementValue match {case ConstValueIndex(index) => constant(index)}).asInstanceOf[String]
- val bytes = sigString.getBytes("UTF-8")
+ val bytes = ((bytesElem.elementValue match {case ConstValueIndex(index) => constantWrapped(index)})
+ .asInstanceOf[StringBytesPair].bytes)
val length = ByteCodecs.decode(bytes)
val scalaSig = ScalaSigAttributeParsers.parse(ByteCode(bytes.take(length)))
parseScalaSignature(scalaSig, isPackageObject)
diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala
index 8689265be2..01652a50b9 100644
--- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala
@@ -9,8 +9,6 @@ import java.io.IOException
import scala._
import scala.Predef._
-import scalax.rules.Error
-
object ByteCode {
def apply(bytes : Array[Byte]) = new ByteCode(bytes, 0, bytes.length)
@@ -62,11 +60,23 @@ class ByteCode(val bytes : Array[Byte], val pos : Int, val length : Int) {
def toInt = fold(0) { (x, b) => (x << 8) + (b & 0xFF)}
def toLong = fold(0L) { (x, b) => (x << 8) + (b & 0xFF)}
- def toUTF8String = io.Codec toUTF8 (bytes drop pos take length) mkString
+ /**
+ * Transforms array subsequence of the current buffer into the UTF8 String and
+ * stores and array of bytes for the decompiler
+ */
+ def toUTF8StringAndBytes = {
+ val chunk: Array[Byte] = bytes drop pos take length
+ StringBytesPair(io.Codec.toUTF8(chunk).mkString, chunk)
+ }
def byte(i : Int) = bytes(pos) & 0xFF
}
+/**
+ * The wrapper for decode UTF-8 string
+ */
+case class StringBytesPair(string: String, bytes: Array[Byte])
+
/** Provides rules for parsing byte-code.
*/
trait ByteCodeReader extends RulesWithState {
@@ -92,7 +102,7 @@ object ClassFileParser extends ByteCodeReader {
// NOTE currently most constants just evaluate to a string description
// TODO evaluate to useful values
- val utf8String = (u2 >> bytes) ^^ add1 { raw => pool => raw.toUTF8String }
+ val utf8String = (u2 >> bytes) ^^ add1 { raw => pool => raw.toUTF8StringAndBytes }
val intConstant = u4 ^^ add1 { x => pool => x }
val floatConstant = bytes(4) ^^ add1 { raw => pool => "Float: TODO" }
val longConstant = bytes(8) ^^ add2 { raw => pool => raw.toLong }
@@ -177,7 +187,12 @@ case class ClassFile(
def superClass = constant(header.superClassIndex)
def interfaces = header.interfaces.map(constant)
- def constant(index : Int) = header.constants(index)
+ def constant(index : Int) = header.constants(index) match {
+ case StringBytesPair(str, _) => str
+ case z => z
+ }
+
+ def constantWrapped(index: Int) = header.constants(index)
def attribute(name : String) = attributes.find {attrib => constant(attrib.nameIndex) == name }
diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala
index e21a0656e1..e0f95c8bbb 100644
--- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala
@@ -55,7 +55,7 @@ object ScalaSigAttributeParsers extends ByteCodeReader {
val symtab = nat >> entry.times
val scalaSig = nat ~ nat ~ symtab ^~~^ ScalaSig
- val utf8 = read(_ toUTF8String)
+ val utf8 = read(x => x.toUTF8StringAndBytes.string)
val longValue = read(_ toLong)
}