diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/ByteCode.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/util/ShowPickled.scala | 26 | ||||
-rw-r--r-- | src/scalap/scala/tools/scalap/Classfile.scala | 1 | ||||
-rw-r--r-- | src/scalap/scala/tools/scalap/Decode.scala | 12 | ||||
-rwxr-xr-x | tools/abspath | 9 | ||||
-rwxr-xr-x | tools/cpof | 30 | ||||
-rwxr-xr-x | tools/diffPickled | 51 | ||||
-rwxr-xr-x | tools/packcp | 5 | ||||
-rwxr-xr-x | tools/quickcp | 5 | ||||
-rwxr-xr-x | tools/showPickled | 32 | ||||
-rwxr-xr-x | tools/starrcp | 5 | ||||
-rwxr-xr-x | tools/strapcp | 5 |
12 files changed, 182 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala b/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala index dc4e173fff..4b8e0ae60c 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala @@ -29,6 +29,16 @@ object ByteCode { method.invoke(module, _: String).asInstanceOf[Option[Map[String, String]]] } + /** Scala sig bytes. + */ + def scalaSigBytesForPath(path: String) = + for { + module <- DECODER + method <- decoderMethod("scalaSigBytes", classOf[String]) + names <- method.invoke(module, path).asInstanceOf[Option[Array[Byte]]] + } + yield names + /** Attempts to retrieve case parameter names for given class name. */ def caseParamNamesForPath(path: String) = diff --git a/src/compiler/scala/tools/nsc/util/ShowPickled.scala b/src/compiler/scala/tools/nsc/util/ShowPickled.scala index f99f63dcda..20ae9c7eeb 100644 --- a/src/compiler/scala/tools/nsc/util/ShowPickled.scala +++ b/src/compiler/scala/tools/nsc/util/ShowPickled.scala @@ -14,6 +14,7 @@ import java.lang.Double.longBitsToDouble import symtab.{Flags, Names} import symtab.classfile.{PickleBuffer, PickleFormat} +import interpreter.ByteCode.scalaSigBytesForPath object ShowPickled extends Names { @@ -193,17 +194,26 @@ object ShowPickled extends Names { for (i <- 0 until index.length) printEntry(i) } - def main(args: Array[String]) { - val file = new File(args(0)) + def fromBytes(what: String, data: => Array[Byte]): Boolean = { try { - val stream = new FileInputStream(file) - val data = new Array[Byte](stream.available()) - stream.read(data) val pickle = new PickleBuffer(data, 0, data.length) + Console.println(what + ": ") printFile(pickle, Console.out) - } catch { - case ex: IOException => - Console.println("cannot read " + file + ": " + ex.getMessage()) + true + } + catch { + case _: Exception => false + } + } + + def fromFile(path: String) = fromBytes(path, io.File(path).toByteArray) + def fromName(name: String) = fromBytes(name, scalaSigBytesForPath(name) getOrElse Array()) + + def main(args: Array[String]) { + args foreach { arg => + val res = fromFile(arg) || fromName(arg) + if (!res) + Console.println("Cannot read " + arg) } } } diff --git a/src/scalap/scala/tools/scalap/Classfile.scala b/src/scalap/scala/tools/scalap/Classfile.scala index 44f687bd85..c4f273c5aa 100644 --- a/src/scalap/scala/tools/scalap/Classfile.scala +++ b/src/scalap/scala/tools/scalap/Classfile.scala @@ -26,6 +26,7 @@ class Classfile(in: ByteArrayReader) { val fields = readMembers(true) val methods = readMembers(false) val attribs = readAttribs + def scalaSigAttribute = attribs find (_.toString == Main.SCALA_SIG) def readAttribs = { val n = in.nextChar diff --git a/src/scalap/scala/tools/scalap/Decode.scala b/src/scalap/scala/tools/scalap/Decode.scala index 04d72c015b..6e55558249 100644 --- a/src/scalap/scala/tools/scalap/Decode.scala +++ b/src/scalap/scala/tools/scalap/Decode.scala @@ -10,7 +10,8 @@ package scala.tools.scalap import scala.tools.scalap.scalax.rules.scalasig._ -import scala.tools.nsc.util.ScalaClassLoader.getSystemLoader +import scala.tools.nsc.util.ScalaClassLoader.{ getSystemLoader, findBytesForClassName } +import Main.SCALA_SIG /** Temporary decoder. This would be better off in the scala.tools.nsc * but right now the compiler won't acknowledge scala.tools.scalap @@ -23,6 +24,15 @@ object Decode { case _ => NoSymbol } + /** Return the classfile bytes representing the scala sig attribute. + */ + def scalaSigBytes(name: String): Option[Array[Byte]] = { + val bytes = findBytesForClassName(name) + val reader = new ByteArrayReader(bytes) + val cf = new Classfile(reader) + cf.scalaSigAttribute map (_.data) + } + /** private[scala] so nobody gets the idea this is a supported interface. */ private[scala] def caseParamNames(path: String): Option[List[String]] = { diff --git a/tools/abspath b/tools/abspath new file mode 100755 index 0000000000..a2d1410b9b --- /dev/null +++ b/tools/abspath @@ -0,0 +1,9 @@ +#!/bin/sh +# +# print the absolute path of each argument + +for relpath in $* ; do + D=`dirname "$relpath"` + B=`basename "$relpath"` + echo "`cd \"$D\" 2>/dev/null && pwd || echo \"$D\"`/$B" +done
\ No newline at end of file diff --git a/tools/cpof b/tools/cpof new file mode 100755 index 0000000000..ab5a42b4fb --- /dev/null +++ b/tools/cpof @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Creates a classpath out of the contents of each directory +# given as an argument. + +if [ $# == 0 ] ; then + echo "Usage: $0 [dir1 dir2 ...]" + exit 1 +fi + +THISDIR=`dirname $0` +ABSCMD="${THISDIR}/abspath" +CPRES="" + +for dir in $* ; do + absdir=`${ABSCMD} $dir` + LS=`ls -1 ${absdir}` + + for x in $LS ; do + ABS=`${ABSCMD} "${absdir}/${x}"` + CPRES="${CPRES}:${ABS}" + done +done + +# shaving the : off the beginning. Applause to /bin/sh for +# keeping us humble about how far we've come. +LEN=$(( ${#CPRES} - 1 )) +result=${CPRES:1:${LEN}} + +echo $result diff --git a/tools/diffPickled b/tools/diffPickled new file mode 100755 index 0000000000..b4a345dc7d --- /dev/null +++ b/tools/diffPickled @@ -0,0 +1,51 @@ +#!/bin/sh +# +# Shows the difference in pickler output between two variations on a class. +# +# If quick and strap are built normally you can run +# +# diffPickled foo.bar.Baz +# +# to see any differences between them in that class. + +USAGE="Usage: $0 classpath1 classpath2 class" +TOOLSDIR=`dirname $0` +BUILDDIR="${TOOLSDIR}/../build" +QUICKDIR="${BUILDDIR}/quick" +STRAPDIR="${BUILDDIR}/strap" + +CP1="" +CP2="" +CLASS="" + +if [ $# == 1 ] ; then + if [ -e ${QUICKDIR} ] && [ -e ${STRAPDIR} ] ; then + CP1=`${TOOLSDIR}/quickcp` + CP2=`${TOOLSDIR}/strapcp` + CLASS=$1 + else + echo $USAGE + echo "(If only one argument is given, $QUICKDIR and $STRAPDIR must exist.)" + exit 1 + fi +elif [ $# == 3 ] ; then + CP1=$1 + CP2=$2 + CLASS=$3 +else + echo $USAGE + exit 1 +fi + +TMPDIR="/tmp/scala_pickle_diff${RANDOM}" + +if mkdir -m 0700 "$TMPDIR" 2>/dev/null ; then + ${TOOLSDIR}/showPickled -cp $CP1 $CLASS > "${TMPDIR}/out1.txt" + ${TOOLSDIR}/showPickled -cp $CP2 $CLASS > "${TMPDIR}/out2.txt" + diff "${TMPDIR}/out1.txt" "${TMPDIR}/out2.txt" + rm -rf ${TMPDIR} +else + echo "Failed to create temporary directory ${TMPDIR}." + exit 1 +fi + diff --git a/tools/packcp b/tools/packcp new file mode 100755 index 0000000000..42bce9e266 --- /dev/null +++ b/tools/packcp @@ -0,0 +1,5 @@ +#!/bin/sh +# + +THISDIR=`dirname $0` +${THISDIR}/cpof ${THISDIR}/../build/pack/lib diff --git a/tools/quickcp b/tools/quickcp new file mode 100755 index 0000000000..9d7ff8dfb0 --- /dev/null +++ b/tools/quickcp @@ -0,0 +1,5 @@ +#!/bin/sh +# + +THISDIR=`dirname $0` +${THISDIR}/cpof ${THISDIR}/../build/quick/classes diff --git a/tools/showPickled b/tools/showPickled new file mode 100755 index 0000000000..67d86355ba --- /dev/null +++ b/tools/showPickled @@ -0,0 +1,32 @@ +#!/bin/sh +# +# Shows the pickled scala data in a classfile. + +if [ $# == 0 ] ; then + echo "Usage: $0 [-cp classpath] class class [...]" + exit 1 +fi + +TOOLSDIR=`dirname $0` +CPOF="$TOOLSDIR/cpof" + +PACK="$TOOLSDIR/../build/pack/lib" +QUICK="$TOOLSDIR/../build/quick/classes" +STARR="$TOOLSDIR/../lib" +CP="" + +if [ -f "${PACK}/scala-library.jar" ] ; then + CP=`${TOOLSDIR}/packcp` +elif [ -d "${QUICK}/library" ] ; then + CP=`${TOOLSDIR}/quickcp` +else + CP=`${TOOLSDIR}/starrcp` +fi + +if [ "$1" == "-cp" ] ; then + shift + CP="${1}:${CP}" + shift +fi + +java -cp "$CP" scala.tools.nsc.util.ShowPickled $* diff --git a/tools/starrcp b/tools/starrcp new file mode 100755 index 0000000000..6add5665b5 --- /dev/null +++ b/tools/starrcp @@ -0,0 +1,5 @@ +#!/bin/sh +# + +THISDIR=`dirname $0` +${THISDIR}/cpof ${THISDIR}/../lib
\ No newline at end of file diff --git a/tools/strapcp b/tools/strapcp new file mode 100755 index 0000000000..87e6ef720e --- /dev/null +++ b/tools/strapcp @@ -0,0 +1,5 @@ +#!/bin/sh +# + +THISDIR=`dirname $0` +${THISDIR}/cpof ${THISDIR}/../build/strap/classes |