Skip to content

Instantly share code, notes, and snippets.

@keynmol
Created February 8, 2021 12:52
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keynmol/c3ceb91c08c50f0b6c56068514c2021a to your computer and use it in GitHub Desktop.
Save keynmol/c3ceb91c08c50f0b6c56068514c2021a to your computer and use it in GitHub Desktop.
A script to dump bytecode in plaintext

This is a simple script to help me see the bytecode when plaing with Scala 3.

All it does is parallelises the calls to javap command that should available if you have JDK installed.

Installation

Just Ammonite - https://ammonite.io/

It's excellent.

usage

For example, running it in watch mode, pointing it at the target folder with classes:

amm -w dump-bytecode.sc --classesFolder $(pwd)/scala3/target/scala-3.0.0-M3/classes --bytecodeFolder $(pwd)/bytecode-scala

WARNING: the script will delete all *.bytecode files (and only them) from the target folder

import $ivy.`org.scala-lang.modules::scala-parallel-collections:1.0.0`
import scala.collection.parallel.CollectionConverters._
import ammonite.ops._
import os.ProcessOutput
def process(classFile: os.Path, bytecodeFile: os.Path): Unit = {
println(s"Processing ${classFile}")
val args =
Seq(
"javap",
"-v",
"-c",
classFile.toNIO.toAbsolutePath().toString()
)
os.proc(args)
.call(
stdout = ProcessOutput.makePathRedirect(bytecodeFile),
stderr = os.Inherit
)
}
@main
def main(classesFolder: os.Path, bytecodeFolder: os.Path) = {
interp.watch(classesFolder)
os.makeDir.all(bytecodeFolder)
os.walk(bytecodeFolder).filter(_.ext == "bytecode").foreach { p =>
os.remove(p)
}
val allClassfiles = os.walk(classesFolder).filter(_.ext == "class")
allClassfiles.zip(allClassfiles.map(_.baseName + ".bytecode")).par.foreach {
case (absPath, filename) =>
val target = bytecodeFolder / filename
process(absPath, target)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment