summaryrefslogtreecommitdiff
path: root/src/compiler/scala
diff options
context:
space:
mode:
authorluajalla <lu-a-jalla@ya.ru>2011-12-05 22:44:12 +0200
committerluajalla <lu-a-jalla@ya.ru>2011-12-05 22:44:12 +0200
commit7eb45e79b827dac8520f61ef500ec50020fa2a92 (patch)
treecadb2dd1ad0d9374f61da224552afbd4823a7c25 /src/compiler/scala
parent51f5831b0c0d14c28938a6f537b93f183217d942 (diff)
downloadscala-7eb45e79b827dac8520f61ef500ec50020fa2a92.tar.gz
scala-7eb45e79b827dac8520f61ef500ec50020fa2a92.tar.bz2
scala-7eb45e79b827dac8520f61ef500ec50020fa2a92.zip
-Ydump-classes: the option to dump the generated bytecode
-Ydump-classes option is intended to dump the compiler generated bytecode to the .class files in given directory. It can be pretty useful for reflective compilation that utilizes in-memory classloaders, for example to check the files if compiler produces invalid bytecode. In this case the dump helps to understand what exactly is wrong with the emitted class. The option format is -Ydump-classes <dir>.
Diffstat (limited to 'src/compiler/scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala20
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala7
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala1
3 files changed, 25 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
index 70aa8ff54e..865bacffaa 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
@@ -7,7 +7,7 @@ package scala.tools.nsc
package backend.jvm
import ch.epfl.lamp.fjbg._
-import java.io.{ DataOutputStream, OutputStream, File => JFile }
+import java.io.{ DataOutputStream, FileOutputStream, OutputStream, File => JFile }
import scala.tools.nsc.io._
import scala.tools.nsc.util.ScalaClassLoader
import scala.tools.util.JavapClass
@@ -85,7 +85,7 @@ trait BytecodeWriters {
emitJavap(bytes, javapFile)
}
}
-
+
trait ClassBytecodeWriter extends BytecodeWriter {
def writeClass(label: String, jclass: JClass, sym: Symbol) {
val outfile = getFile(sym, jclass, ".class")
@@ -96,4 +96,20 @@ trait BytecodeWriters {
informProgress("wrote '" + label + "' to " + outfile)
}
}
+
+ trait DumpBytecodeWriter extends BytecodeWriter {
+ val baseDir = Directory(settings.Ydumpclasses.value).createDirectory()
+
+ abstract override def writeClass(label: String, jclass: JClass, sym: Symbol) {
+ super.writeClass(label, jclass, sym)
+
+ val pathName = jclass.getName()
+ var dumpFile = pathName.split("[./]").foldLeft(baseDir: Path) (_ / _) changeExtension "class" toFile;
+ dumpFile.parent.createDirectory()
+ val outstream = new DataOutputStream(new FileOutputStream(dumpFile.path))
+
+ try jclass writeTo outstream
+ finally outstream.close()
+ }
+ }
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 3fe5b83515..e55ceaa133 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -129,7 +129,12 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
new DirectToJarfileWriter(f.file)
case _ =>
- if (settings.Ygenjavap.isDefault) new ClassBytecodeWriter { }
+ if (settings.Ygenjavap.isDefault) {
+ if(settings.Ydumpclasses.isDefault)
+ new ClassBytecodeWriter { }
+ else
+ new ClassBytecodeWriter with DumpBytecodeWriter { }
+ }
else new ClassBytecodeWriter with JavapBytecodeWriter { }
}
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index 6be15e4e98..7fcfb6fc6d 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -139,6 +139,7 @@ trait ScalaSettings extends AbsScalaSettings
val Yshowsyms = BooleanSetting ("-Yshow-syms", "Print the AST symbol hierarchy after each phase.")
val skip = PhasesSetting ("-Yskip", "Skip")
val Ygenjavap = StringSetting ("-Ygen-javap", "dir", "Generate a parallel output directory of .javap files.", "")
+ val Ydumpclasses = StringSetting ("-Ydump-classes", "dir", "Dump the generated bytecode to .class files (useful for reflective compilation that utilizes in-memory classloaders).", "")
val Ynosqueeze = BooleanSetting ("-Yno-squeeze", "Disable creation of compact code in matching.")
val Ystatistics = BooleanSetting ("-Ystatistics", "Print compiler statistics.") .
withPostSetHook(set => util.Statistics.enabled = set.value)