diff options
Diffstat (limited to 'src/scalap')
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) } |