summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-11-25 18:50:55 +0000
committerPaul Phillips <paulp@improving.org>2009-11-25 18:50:55 +0000
commit0a1d1a616719022ddaf199db7515207dfc824d3c (patch)
tree49745e4078e4b7577563d10deb273d8fa1e9cd5f /src
parent13b3d06f82c4f893dfc2710203bd64798fc73a99 (diff)
downloadscala-0a1d1a616719022ddaf199db7515207dfc824d3c.tar.gz
scala-0a1d1a616719022ddaf199db7515207dfc824d3c.tar.bz2
scala-0a1d1a616719022ddaf199db7515207dfc824d3c.zip
Removing redundant scalap code.
Diffstat (limited to 'src')
-rw-r--r--src/scalap/scala/tools/scalap/ByteArrayReader.scala60
-rw-r--r--src/scalap/scala/tools/scalap/Classfile.scala115
-rw-r--r--src/scalap/scala/tools/scalap/Classfiles.scala15
-rw-r--r--src/scalap/scala/tools/scalap/JavaWriter.scala14
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala25
5 files changed, 92 insertions, 137 deletions
diff --git a/src/scalap/scala/tools/scalap/ByteArrayReader.scala b/src/scalap/scala/tools/scalap/ByteArrayReader.scala
index 2fde050782..47df499dee 100644
--- a/src/scalap/scala/tools/scalap/ByteArrayReader.scala
+++ b/src/scalap/scala/tools/scalap/ByteArrayReader.scala
@@ -45,23 +45,22 @@ class ByteArrayReader(content: Array[Byte]) {
*/
def nextChar: Char = {
bp += 2
- (((buf(bp - 2) & 0xff) << 8) + (buf(bp - 1) & 0xff)).asInstanceOf[Char]
+ getChar(bp - 2)
}
/** read an integer
*/
def nextInt: Int = {
bp += 4
- ((buf(bp - 4) & 0xff) << 24) +
- ((buf(bp - 3) & 0xff) << 16) +
- ((buf(bp - 2) & 0xff) << 8) +
- (buf(bp - 1) & 0xff)
+ getInt(bp - 4)
}
/** read a long
*/
- def nextLong: Long =
- (nextInt.toLong << 32) + (nextInt.toLong & 0xffffffffL)
+ def nextLong: Long = {
+ bp += 8
+ getLong(bp - 8)
+ }
/** read a float
*/
@@ -71,55 +70,12 @@ class ByteArrayReader(content: Array[Byte]) {
*/
def nextDouble: Double = java.lang.Double.longBitsToDouble(nextLong)
- /** read the next integer number
- */
- def nextNat: Int = {
- var x = 0
- var b: Byte = 0
- do {
- b = buf(bp)
- bp += 1
- x = (x << 7) + (b & 0x7f)
- } while ((b & 0x80) != 0)
- x
- }
-
- /** read the next signed number in big endian format
- */
- def nextNum(n: Int): Long = {
- var x: Long = 0
- var i: Int = 0
- while (i < n) {
- x = (x << 8) + (nextByte & 0xff)
- i += 1
- }
- val leading: Int = 64 - (n * 8)
- x << leading >> leading
- }
-
/** read an UTF8 encoded string
*/
def nextUTF8(len: Int): String = {
- val cs: Array[Char] = new Array(len)
- var i = bp
- var j = 0
+ val cs = scala.io.Codec.toUTF8(buf.slice(bp, bp + len))
bp += len
- while (i < bp) {
- var b: Int = buf(i) & 0xFF
- i += 1
- if (b >= 0xE0) {
- b = ((b & 0x0F) << 12) | (buf(i) & 0x3F) << 6
- i += 1
- b = b | (buf(i) & 0x3F)
- i += 1
- } else if (b >= 0xC0) {
- b = ((b & 0x1F) << 6) | (buf(i) & 0x3F)
- i += 1
- }
- cs(j) = b.asInstanceOf[Char]
- j += 1
- }
- new String(cs, 0, j)
+ new String(cs)
}
/** extract a character at position bp from buf
diff --git a/src/scalap/scala/tools/scalap/Classfile.scala b/src/scalap/scala/tools/scalap/Classfile.scala
index dd7873f6b0..d8e43f4373 100644
--- a/src/scalap/scala/tools/scalap/Classfile.scala
+++ b/src/scalap/scala/tools/scalap/Classfile.scala
@@ -13,10 +13,12 @@ package scala.tools.scalap
class Classfile(in: ByteArrayReader) {
import Classfiles._
+ type UTF8 = Pool#UTF8
+
assert(in.nextInt == JAVA_MAGIC)
val minorVersion = in.nextChar
val majorVersion = in.nextChar
- val pool = readPool
+ val pool = new Pool()
val flags = in.nextChar
val classname = in.nextChar
val superclass = in.nextChar
@@ -58,69 +60,70 @@ class Classfile(in: ByteArrayReader) {
intfs
}
- def readPool = {
- val pool = new Array[PoolEntry](in.nextChar)
- var i = 1
- while (i < pool.length) {
- val tag: Int = in.nextByte
- tag match {
- case CONSTANT_UTF8 =>
- pool(i) = UTF8(in.nextUTF8(in.nextChar))
- case CONSTANT_UNICODE =>
- in.skip(in.nextChar)
- pool(i) = Empty()
- case CONSTANT_CLASS =>
- pool(i) = ClassRef(in.nextChar)
- case CONSTANT_STRING =>
- pool(i) = StringConst(in.nextChar)
- case CONSTANT_FIELDREF =>
- pool(i) = FieldRef(in.nextChar, in.nextChar)
- case CONSTANT_METHODREF =>
- pool(i) = MethodRef(in.nextChar, in.nextChar)
- case CONSTANT_INTFMETHODREF =>
- pool(i) = IntfMethodRef(in.nextChar, in.nextChar)
- case CONSTANT_NAMEANDTYPE =>
- pool(i) = NameAndType(in.nextChar, in.nextChar)
- case CONSTANT_INTEGER =>
- pool(i) = IntegerConst(in.nextInt)
- case CONSTANT_FLOAT =>
- pool(i) = FloatConst(in.nextFloat)
- case CONSTANT_LONG =>
- pool(i) = LongConst(in.nextLong)
- i = i + 1
- pool(i) = Empty()
- case CONSTANT_DOUBLE =>
- pool(i) = DoubleConst(in.nextDouble)
+ class Pool() {
+ sealed abstract class PoolEntry(val tag: Int) {
+ def typeString = constantTagToString(tag)
+ }
+ case class UTF8(str: String) extends PoolEntry(CONSTANT_UTF8) { override def toString = "\"" + str + "\"" }
+ case class ClassRef(classId: Int) extends PoolEntry(CONSTANT_CLASS) { override def toString = "Class(%s)".format(entries(classId)) }
+ case class FieldRef(classId: Int, memberId: Int) extends PoolEntry(CONSTANT_FIELDREF)
+ case class MethodRef(classId: Int, memberId: Int) extends PoolEntry(CONSTANT_METHODREF) {
+ // //Method java/lang/Object."<init>":()V
+ override def toString() = "Method %s.\"%s\"".format(entries(classId), entries(memberId))
+ }
+ case class IntfMethodRef(classId: Int, memberId: Int) extends PoolEntry(CONSTANT_INTFMETHODREF)
+ case class StringConst(strId: Int) extends PoolEntry(CONSTANT_STRING)
+ case class IntegerConst(x: Int) extends PoolEntry(CONSTANT_INTEGER)
+ case class FloatConst(x: Float) extends PoolEntry(CONSTANT_FLOAT)
+ case class LongConst(x: Long) extends PoolEntry(CONSTANT_LONG)
+ case class DoubleConst(x: Double) extends PoolEntry(CONSTANT_DOUBLE)
+ case class NameAndType(nameId: Int, typeId: Int) extends PoolEntry(CONSTANT_NAMEANDTYPE)
+ case object Empty extends PoolEntry(0) { }
+
+ val entries = {
+ val pool = new Array[PoolEntry](in.nextChar)
+ var i = 1
+ while (i < pool.length) {
+ val tag = in.nextByte
+ // Double sized entry
+ if (tag == CONSTANT_LONG || tag == CONSTANT_DOUBLE) {
+ pool(i) = if (tag == CONSTANT_LONG) LongConst(in.nextLong) else DoubleConst(in.nextDouble)
i = i + 1
- pool(i) = Empty()
+ pool(i) = Empty
+ }
+ else pool(i) = tag match {
+ case CONSTANT_UTF8 => UTF8(in.nextUTF8(in.nextChar))
+ case CONSTANT_UNICODE => in.skip(in.nextChar) ; Empty
+ case CONSTANT_CLASS => ClassRef(in.nextChar)
+ case CONSTANT_STRING => StringConst(in.nextChar)
+ case CONSTANT_FIELDREF => FieldRef(in.nextChar, in.nextChar)
+ case CONSTANT_METHODREF => MethodRef(in.nextChar, in.nextChar)
+ case CONSTANT_INTFMETHODREF => IntfMethodRef(in.nextChar, in.nextChar)
+ case CONSTANT_NAMEANDTYPE => NameAndType(in.nextChar, in.nextChar)
+ case CONSTANT_INTEGER => IntegerConst(in.nextInt)
+ case CONSTANT_FLOAT => FloatConst(in.nextFloat)
+ }
+
+ i += 1
}
- i = i + 1
+ pool
}
- pool
- }
- class PoolEntry
- case class UTF8(str: String) extends PoolEntry
- case class ClassRef(classId: Int) extends PoolEntry
- case class FieldRef(classId: Int, memberId: Int) extends PoolEntry
- case class MethodRef(classId: Int, memberId: Int) extends PoolEntry
- case class IntfMethodRef(classId: Int, memberId: Int) extends PoolEntry
- case class StringConst(strId: Int) extends PoolEntry
- case class IntegerConst(x: Int) extends PoolEntry
- case class FloatConst(x: Float) extends PoolEntry
- case class LongConst(x: Long) extends PoolEntry
- case class DoubleConst(x: Double) extends PoolEntry
- case class NameAndType(nameId: Int, typeId: Int) extends PoolEntry
- case class Empty() extends PoolEntry
+ lazy val length = entries.length
+ def apply(x: Int) = entries(x)
+ def stringOf(x: Int) = apply(x).toString
+ override def toString = (
+ for ((x, i) <- entries.zipWithIndex ; if x != null) yield
+ "const #%d = %s\t%s\n".format(i + 1, x.typeString, x)
+ ).mkString
+ }
+ /** **/
case class Member(field: Boolean, flags: Int, name: Int, tpe: Int, attribs: List[Attribute])
case class Attribute(name: Int, data: Array[Byte]) {
-
- override def toString(): String = pool(name) match {
- case UTF8(str: String) => str
+ override def toString = pool(name) match {
+ case pool.UTF8(s) => s
}
-
def reader: ByteArrayReader = new ByteArrayReader(data)
}
-
}
diff --git a/src/scalap/scala/tools/scalap/Classfiles.scala b/src/scalap/scala/tools/scalap/Classfiles.scala
index e21ae76fb0..f5351f0ca5 100644
--- a/src/scalap/scala/tools/scalap/Classfiles.scala
+++ b/src/scalap/scala/tools/scalap/Classfiles.scala
@@ -28,6 +28,21 @@ object Classfiles {
final val CONSTANT_INTFMETHODREF = 11
final val CONSTANT_NAMEANDTYPE = 12
+ final val constantTagToString = Map(
+ CONSTANT_UTF8 -> "UTF8",
+ CONSTANT_UNICODE -> "Unicode",
+ CONSTANT_INTEGER -> "Int",
+ CONSTANT_FLOAT -> "Float",
+ CONSTANT_LONG -> "Long",
+ CONSTANT_DOUBLE -> "Double",
+ CONSTANT_CLASS -> "class",
+ CONSTANT_STRING -> "Asciz",
+ CONSTANT_FIELDREF -> "Field",
+ CONSTANT_METHODREF -> "Method",
+ CONSTANT_INTFMETHODREF -> "InterfaceMethod",
+ CONSTANT_NAMEANDTYPE -> "NameAndType"
+ )
+
final val BAD_ATTR = 0x00000
final val SOURCEFILE_ATTR = 0x00001
final val SYNTHETIC_ATTR = 0x00002
diff --git a/src/scalap/scala/tools/scalap/JavaWriter.scala b/src/scalap/scala/tools/scalap/JavaWriter.scala
index 06fec1a8fb..ac56975fd7 100644
--- a/src/scalap/scala/tools/scalap/JavaWriter.scala
+++ b/src/scalap/scala/tools/scalap/JavaWriter.scala
@@ -92,11 +92,15 @@ class JavaWriter(classfile: Classfile, writer: Writer) extends CodeWriter(writer
}
}
- def getName(n: Int): String = cf.pool(n) match {
- case cf.UTF8(str) => str
- case cf.StringConst(m) => getName(m)
- case cf.ClassRef(m) => getName(m)
- case x => "<error>"
+ def getName(n: Int): String = {
+ import cf.pool._
+
+ cf.pool(n) match {
+ case UTF8(str) => str
+ case StringConst(m) => getName(m)
+ case ClassRef(m) => getName(m)
+ case _ => "<error>"
+ }
}
def getClassName(n: Int): String = nameToClass(getName(n))
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 bc47092f71..37bfa9cfea 100644
--- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala
@@ -62,27 +62,7 @@ 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)}
- // NOTE the UTF8 decoder in the Scala compiler is broken for pos > 0
- // TODO figure out patch and submit
- def toUTF8String = {
- val sb = new StringBuilder(length)
- var i = pos
- val end = pos + length
- while (i < end) {
- var b = bytes(i) & 0xFF
- i += 1
- if (b >= 0xE0) {
- b = ((b & 0x0F) << 12) | (bytes(i) & 0x3F) << 6
- b = b | (bytes(i+1) & 0x3F)
- i += 2
- } else if (b >= 0xC0) {
- b = ((b & 0x1F) << 6) | (bytes(i) & 0x3F)
- i += 1
- }
- sb += b.toChar
- }
- sb.toString
- }
+ def toUTF8String = io.Codec toUTF8 (bytes drop pos take length) mkString
def byte(i : Int) = bytes(pos) & 0xFF
}
@@ -100,9 +80,6 @@ trait ByteCodeReader extends RulesWithState {
val u4 = bytes(4) ^^ (_ toInt) // should map to Long??
def bytes(n : Int) = apply(_ next n)
-
-
-
}
object ClassFileParser extends ByteCodeReader {