diff options
author | luajalla <lu-a-jalla@ya.ru> | 2011-12-05 22:44:12 +0200 |
---|---|---|
committer | luajalla <lu-a-jalla@ya.ru> | 2011-12-05 22:44:12 +0200 |
commit | 7eb45e79b827dac8520f61ef500ec50020fa2a92 (patch) | |
tree | cadb2dd1ad0d9374f61da224552afbd4823a7c25 /src | |
parent | 51f5831b0c0d14c28938a6f537b93f183217d942 (diff) | |
download | scala-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')
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) |