Navigation Menu

Skip to content

Commit

Permalink
BytecodeWriters can do without the FJBG dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
magarciaEPFL committed May 8, 2012
1 parent 73fb63f commit afa60fc
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 23 deletions.
39 changes: 19 additions & 20 deletions src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
Expand Up @@ -6,7 +6,6 @@
package scala.tools.nsc
package backend.jvm

import ch.epfl.lamp.fjbg._
import java.io.{ DataOutputStream, FileOutputStream, OutputStream, File => JFile }
import scala.tools.nsc.io._
import scala.tools.nsc.util.ScalaClassLoader
Expand All @@ -26,19 +25,19 @@ trait BytecodeWriters {
private def outputDirectory(sym: Symbol): AbstractFile = (
settings.outputDirs.outputDirFor(beforeFlatten(sym.sourceFile))
)
private def getFile(base: AbstractFile, cls: JClass, suffix: String): AbstractFile = {
private def getFile(base: AbstractFile, /*cls.getName()*/ clsName: String, suffix: String): AbstractFile = {
var dir = base
val pathParts = cls.getName().split("[./]").toList
val pathParts = clsName.split("[./]").toList
for (part <- pathParts.init) {
dir = dir.subdirectoryNamed(part)
}
dir.fileNamed(pathParts.last + suffix)
}
private def getFile(sym: Symbol, cls: JClass, suffix: String): AbstractFile =
getFile(outputDirectory(sym), cls, suffix)
private def getFile(sym: Symbol, clsName: String, suffix: String): AbstractFile =
getFile(outputDirectory(sym), clsName, suffix)

trait BytecodeWriter {
def writeClass(label: String, jclass: JClass, sym: Symbol): Unit
def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], sym: Symbol): Unit
def close(): Unit = ()
}

Expand All @@ -49,11 +48,11 @@ trait BytecodeWriters {
)
val writer = new Jar(jfile).jarWriter(jarMainAttrs: _*)

def writeClass(label: String, jclass: JClass, sym: Symbol) {
val path = jclass.getName + ".class"
def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], sym: Symbol) {
val path = jclassName + ".class"
val out = writer.newOutputStream(path)

try jclass writeTo out
try out.write(jclassBytes, 0, jclassBytes.length)
finally out.flush()

informProgress("added " + label + path + " to jar")
Expand All @@ -73,11 +72,11 @@ trait BytecodeWriters {
try javap(Seq("-verbose", "dummy")) foreach (_.show())
finally pw.close()
}
abstract override def writeClass(label: String, jclass: JClass, sym: Symbol) {
super.writeClass(label, jclass, sym)
abstract override def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], sym: Symbol) {
super.writeClass(label, jclassName, jclassBytes, sym)

val bytes = getFile(sym, jclass, ".class").toByteArray
val segments = jclass.getName().split("[./]")
val bytes = getFile(sym, jclassName, ".class").toByteArray
val segments = jclassName.split("[./]")
val javapFile = segments.foldLeft(baseDir: Path)(_ / _) changeExtension "javap" toFile;

javapFile.parent.createDirectory()
Expand All @@ -86,11 +85,11 @@ trait BytecodeWriters {
}

trait ClassBytecodeWriter extends BytecodeWriter {
def writeClass(label: String, jclass: JClass, sym: Symbol) {
val outfile = getFile(sym, jclass, ".class")
def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], sym: Symbol) {
val outfile = getFile(sym, jclassName, ".class")
val outstream = new DataOutputStream(outfile.bufferedOutput)

try jclass writeTo outstream
try outstream.write(jclassBytes, 0, jclassBytes.length)
finally outstream.close()
informProgress("wrote '" + label + "' to " + outfile)
}
Expand All @@ -99,15 +98,15 @@ trait BytecodeWriters {
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)
abstract override def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], sym: Symbol) {
super.writeClass(label, jclassName, jclassBytes, sym)

val pathName = jclass.getName()
val pathName = jclassName
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
try outstream.write(jclassBytes, 0, jclassBytes.length)
finally outstream.close()
}
}
Expand Down
14 changes: 11 additions & 3 deletions src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
Expand Up @@ -6,7 +6,7 @@
package scala.tools.nsc
package backend.jvm

import java.io.{ DataOutputStream, OutputStream }
import java.io.{ByteArrayOutputStream, DataOutputStream, OutputStream }
import java.nio.ByteBuffer
import scala.collection.{ mutable, immutable }
import scala.reflect.internal.pickling.{ PickleFormat, PickleBuffer }
Expand Down Expand Up @@ -345,7 +345,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
*/
def emitClass(jclass: JClass, sym: Symbol) {
addInnerClasses(jclass)
writeClass("" + sym.name, jclass, sym)
writeClass("" + sym.name, jclass.getName(), toByteArray(jclass), sym)
}

/** Returns the ScalaSignature annotation if it must be added to this class,
Expand Down Expand Up @@ -517,6 +517,14 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
}
}

private def toByteArray(jc: JClass): Array[Byte] = {
val bos = new java.io.ByteArrayOutputStream()
val dos = new java.io.DataOutputStream(bos)
jc.writeTo(dos)
dos.close()
bos.toByteArray
}

/**
* Generate a bean info class that describes the given class.
*
Expand Down Expand Up @@ -586,7 +594,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
jcode.emitRETURN()

// write the bean information class file.
writeClass("BeanInfo ", beanInfoClass, c.symbol)
writeClass("BeanInfo ", beanInfoClass.getName(), toByteArray(beanInfoClass), c.symbol)
}

/** Add the given 'throws' attributes to jmethod */
Expand Down

0 comments on commit afa60fc

Please sign in to comment.