summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2012-11-02 22:00:03 -0700
committerSom Snytt <som.snytt@gmail.com>2012-11-28 12:52:44 -0800
commit2857d43a5a217d45f879878740081d4b91c1b2d8 (patch)
tree842862390dc664175f9e126a7ad977910a1f9816 /src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
parent08e717eaee731456a51adb08f72aa5d9f083a29a (diff)
downloadscala-2857d43a5a217d45f879878740081d4b91c1b2d8.tar.gz
scala-2857d43a5a217d45f879878740081d4b91c1b2d8.tar.bz2
scala-2857d43a5a217d45f879878740081d4b91c1b2d8.zip
Javap for Java 7 (Fixes SI-4936)
Add support for reflective invocation of javap under jdk7, using the quasi-javax.tools API. Under -Ygen-javap, warn if you can't. Since JAVA_HOME is used to locate tools.jar, the script is updated to convert it for cygwin. Update Javap for simpl repl. Also, reduce clutter of JavaxTools as suggested. JavapTool7 evades repl truncating if enabled; the truncating PrintWriter is not line-oriented but string-oriented.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala31
1 files changed, 18 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
index 8c8950d295..941ccd9a2d 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
@@ -9,7 +9,7 @@ package backend.jvm
import java.io.{ DataOutputStream, FileOutputStream, OutputStream, File => JFile }
import scala.tools.nsc.io._
import scala.tools.nsc.util.ScalaClassLoader
-import scala.tools.util.JavapClass
+import scala.tools.util.{ Javap, JavapClass }
import java.util.jar.Attributes.Name
import scala.language.postfixOps
@@ -59,27 +59,32 @@ trait BytecodeWriters {
override def close() = writer.close()
}
+ /** To be mixed-in with the BytecodeWriter that generates
+ * the class file to be disassembled.
+ */
trait JavapBytecodeWriter extends BytecodeWriter {
val baseDir = Directory(settings.Ygenjavap.value).createDirectory()
-
- def emitJavap(bytes: Array[Byte], javapFile: io.File) {
- val pw = javapFile.printWriter()
- val javap = new JavapClass(ScalaClassLoader.appLoader, pw) {
- override def findBytes(path: String): Array[Byte] = bytes
- }
-
- try javap(Seq("-verbose", "dummy")) foreach (_.show())
- finally pw.close()
+ val cl = ScalaClassLoader.appLoader
+
+ def emitJavap(classFile: AbstractFile, javapFile: File) {
+ val pw = javapFile.printWriter()
+ try {
+ val javap = new JavapClass(cl, pw) {
+ override def findBytes(path: String): Array[Byte] = classFile.toByteArray
+ }
+ javap(Seq("-verbose", "-protected", classFile.name)) foreach (_.show())
+ } finally pw.close()
}
abstract override def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], sym: Symbol) {
super.writeClass(label, jclassName, jclassBytes, sym)
- val bytes = getFile(sym, jclassName, ".class").toByteArray
+ val classFile = getFile(sym, jclassName, ".class")
val segments = jclassName.split("[./]")
val javapFile = segments.foldLeft(baseDir: Path)(_ / _) changeExtension "javap" toFile;
-
javapFile.parent.createDirectory()
- emitJavap(bytes, javapFile)
+
+ if (Javap.isAvailable(cl)) emitJavap(classFile, javapFile)
+ else warning("No javap on classpath, skipping javap output.")
}
}