diff options
author | Miguel Garcia <miguelalfredo.garcia@epfl.ch> | 2013-03-24 18:39:12 +0100 |
---|---|---|
committer | Miguel Garcia <miguelalfredo.garcia@epfl.ch> | 2013-04-27 10:56:46 +0200 |
commit | 1931f45a9cf6027ef9bb037f63aeb2e926203000 (patch) | |
tree | 986daaee74dde1b60d7d67d2162564bbd6688d53 /src/compiler | |
parent | 38f426d2ae2058b44ac96d5b6618d7552a23c359 (diff) | |
download | scala-1931f45a9cf6027ef9bb037f63aeb2e926203000.tar.gz scala-1931f45a9cf6027ef9bb037f63aeb2e926203000.tar.bz2 scala-1931f45a9cf6027ef9bb037f63aeb2e926203000.zip |
BytecodeWriters.BytecodeWriter doesn't need to fiddle with Symbol
This commit allows a BytecodeWriter to focus on File, Paths, and streams. GenASM now does the conversion from Symbol to File.
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala | 22 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala | 24 |
2 files changed, 26 insertions, 20 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala index e20b75ed13..0df828393d 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala @@ -8,7 +8,6 @@ package backend.jvm import java.io.{ DataOutputStream, FileOutputStream, IOException, OutputStream, File => JFile } import scala.tools.nsc.io._ -import scala.tools.nsc.util.ScalaClassLoader import java.util.jar.Attributes.Name import scala.language.postfixOps @@ -38,7 +37,7 @@ trait BytecodeWriters { for (part <- pathParts.init) dir = ensureDirectory(dir) subdirectoryNamed part ensureDirectory(dir) fileNamed pathParts.last + suffix } - private def getFile(sym: Symbol, clsName: String, suffix: String): AbstractFile = + def getFile(sym: Symbol, clsName: String, suffix: String): AbstractFile = getFile(outputDirectory(sym), clsName, suffix) def factoryNonJarBytecodeWriter(): BytecodeWriter = { @@ -53,7 +52,7 @@ trait BytecodeWriters { } trait BytecodeWriter { - def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], sym: Symbol): Unit + def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], outfile: AbstractFile): Unit def close(): Unit = () } @@ -64,7 +63,9 @@ trait BytecodeWriters { ) val writer = new Jar(jfile).jarWriter(jarMainAttrs: _*) - def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], sym: Symbol) { + def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], outfile: AbstractFile) { + assert(outfile == null, + "The outfile formal param is there just because ClassBytecodeWriter overrides this method and uses it.") val path = jclassName + ".class" val out = writer.newOutputStream(path) @@ -102,8 +103,8 @@ trait BytecodeWriters { finally pw.close() } - abstract override def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], sym: Symbol) { - super.writeClass(label, jclassName, jclassBytes, sym) + abstract override def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], outfile: AbstractFile) { + super.writeClass(label, jclassName, jclassBytes, outfile) val segments = jclassName.split("[./]") val asmpFile = segments.foldLeft(baseDir: Path)(_ / _) changeExtension "asmp" toFile; @@ -114,8 +115,9 @@ trait BytecodeWriters { } trait ClassBytecodeWriter extends BytecodeWriter { - def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], sym: Symbol) { - val outfile = getFile(sym, jclassName, ".class") + def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], outfile: AbstractFile) { + assert(outfile != null, + "Precisely this override requires its invoker to hand out a non-null AbstractFile.") val outstream = new DataOutputStream(outfile.bufferedOutput) try outstream.write(jclassBytes, 0, jclassBytes.length) @@ -127,8 +129,8 @@ trait BytecodeWriters { trait DumpBytecodeWriter extends BytecodeWriter { val baseDir = Directory(settings.Ydumpclasses.value).createDirectory() - abstract override def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], sym: Symbol) { - super.writeClass(label, jclassName, jclassBytes, sym) + abstract override def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], outfile: AbstractFile) { + super.writeClass(label, jclassName, jclassBytes, outfile) val pathName = jclassName val dumpFile = pathName.split("[./]").foldLeft(baseDir: Path) (_ / _) changeExtension "class" toFile; diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 133db77a0c..e9f42ea5ce 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -102,9 +102,10 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { debuglog(s"Created new bytecode generator for ${classes.size} classes.") val bytecodeWriter = initBytecodeWriter(sortedClasses filter isJavaEntryPoint) - val plainCodeGen = new JPlainBuilder(bytecodeWriter) - val mirrorCodeGen = new JMirrorBuilder(bytecodeWriter) - val beanInfoCodeGen = new JBeanInfoBuilder(bytecodeWriter) + val needsOutfile = bytecodeWriter.isInstanceOf[ClassBytecodeWriter] + val plainCodeGen = new JPlainBuilder( bytecodeWriter, needsOutfile) + val mirrorCodeGen = new JMirrorBuilder( bytecodeWriter, needsOutfile) + val beanInfoCodeGen = new JBeanInfoBuilder(bytecodeWriter, needsOutfile) def emitFor(c: IClass) { if (isStaticModule(c.symbol) && isTopLevelModule(c.symbol)) { @@ -397,7 +398,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { } /** basic functionality for class file building */ - abstract class JBuilder(bytecodeWriter: BytecodeWriter) { + abstract class JBuilder(bytecodeWriter: BytecodeWriter, needsOutfile: Boolean) { val EMPTY_STRING_ARRAY = Array.empty[String] @@ -455,7 +456,10 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { def writeIfNotTooBig(label: String, jclassName: String, jclass: asm.ClassWriter, sym: Symbol) { try { val arr = jclass.toByteArray() - bytecodeWriter.writeClass(label, jclassName, arr, sym) + val outF: scala.tools.nsc.io.AbstractFile = { + if(needsOutfile) getFile(sym, jclassName, ".class") else null + } + bytecodeWriter.writeClass(label, jclassName, arr, outF) } catch { case e: java.lang.RuntimeException if(e.getMessage() == "Class file too large!") => // TODO check where ASM throws the equivalent of CodeSizeTooBigException @@ -686,7 +690,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { /** functionality for building plain and mirror classes */ - abstract class JCommonBuilder(bytecodeWriter: BytecodeWriter) extends JBuilder(bytecodeWriter) { + abstract class JCommonBuilder(bytecodeWriter: BytecodeWriter, needsOutfile: Boolean) extends JBuilder(bytecodeWriter, needsOutfile) { def debugLevel = settings.debuginfo.indexOfChoice @@ -1236,8 +1240,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { case class BlockInteval(start: BasicBlock, end: BasicBlock) /** builder of plain classes */ - class JPlainBuilder(bytecodeWriter: BytecodeWriter) - extends JCommonBuilder(bytecodeWriter) + class JPlainBuilder(bytecodeWriter: BytecodeWriter, needsOutfile: Boolean) + extends JCommonBuilder(bytecodeWriter, needsOutfile) with JAndroidBuilder { val MIN_SWITCH_DENSITY = 0.7 @@ -2871,7 +2875,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { /** builder of mirror classes */ - class JMirrorBuilder(bytecodeWriter: BytecodeWriter) extends JCommonBuilder(bytecodeWriter) { + class JMirrorBuilder(bytecodeWriter: BytecodeWriter, needsOutfile: Boolean) extends JCommonBuilder(bytecodeWriter, needsOutfile) { private var cunit: CompilationUnit = _ def getCurrentCUnit(): CompilationUnit = cunit @@ -2923,7 +2927,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { /** builder of bean info classes */ - class JBeanInfoBuilder(bytecodeWriter: BytecodeWriter) extends JBuilder(bytecodeWriter) { + class JBeanInfoBuilder(bytecodeWriter: BytecodeWriter, needsOutfile: Boolean) extends JBuilder(bytecodeWriter, needsOutfile) { /** * Generate a bean info class that describes the given class. |