Commit 7de5b4b4 authored by Kunshan Wang's avatar Kunshan Wang

WIP: load bundle from bootimg

parent 7a1a6da7
...@@ -26,15 +26,23 @@ class UIRTextReader(val defaultIDFactory: IDFactory, val recordSourceInfo: Boole ...@@ -26,15 +26,23 @@ class UIRTextReader(val defaultIDFactory: IDFactory, val recordSourceInfo: Boole
import UIRTextReader._ import UIRTextReader._
def read(ir: java.io.Reader, globalBundle: GlobalBundle): TrantientBundle = { def read(ir: java.io.Reader, globalBundle: GlobalBundle): TrantientBundle = {
read(ir, globalBundle, defaultIDFactory)
}
def read(ir: java.io.Reader, globalBundle: GlobalBundle, idFactory: IDFactory): TrantientBundle = {
logger.debug("Slurping from reader...") logger.debug("Slurping from reader...")
val src = IOHelpers.slurp(ir) val src = IOHelpers.slurp(ir)
read(src, globalBundle) read(src, globalBundle, idFactory)
} }
def read(ir: String, globalBundle: GlobalBundle): TrantientBundle = { def read(ir: String, globalBundle: GlobalBundle): TrantientBundle = {
read(ir, globalBundle, defaultIDFactory)
}
def read(ir: String, globalBundle: GlobalBundle, idFactory : IDFactory): TrantientBundle = {
logger.debug("Creating ANTLRInputStream...") logger.debug("Creating ANTLRInputStream...")
val input = new ANTLRInputStream(ir) val input = new ANTLRInputStream(ir)
read(ir, input, globalBundle) read(ir, input, globalBundle, idFactory)
} }
def parse(source: String, ais: ANTLRInputStream): IrContext = { def parse(source: String, ais: ANTLRInputStream): IrContext = {
......
...@@ -50,6 +50,7 @@ class BundleSerializer(val bundle: GlobalBundle, val whiteList: Set[TopLevel]) { ...@@ -50,6 +50,7 @@ class BundleSerializer(val bundle: GlobalBundle, val whiteList: Set[TopLevel]) {
case func: Function => { case func: Function => {
bundle.funcToVers(func).headOption match { bundle.funcToVers(func).headOption match {
case Some(fv) => { case Some(fv) => {
writeIDNamePair(fv, output)
fv.bbs foreach { bb => fv.bbs foreach { bb =>
writeIDNamePair(bb, output) writeIDNamePair(bb, output)
bb.localVarNs.all foreach { lv => writeIDNamePair(lv, output) } bb.localVarNs.all foreach { lv => writeIDNamePair(lv, output) }
......
...@@ -19,6 +19,7 @@ import uvm.refimpl.nat.NativeLibraryHolder ...@@ -19,6 +19,7 @@ import uvm.refimpl.nat.NativeLibraryHolder
import uvm.staticanalysis.StaticAnalyzer import uvm.staticanalysis.StaticAnalyzer
import uvm.utils.IDFactory import uvm.utils.IDFactory
import uvm.utils.SequentialIDFactory import uvm.utils.SequentialIDFactory
import uvm.refimpl.bootimg.BootImageLoader
object MicroVM { object MicroVM {
val DEFAULT_SOS_SIZE: Word = 2L * 1024L * 1024L; // 2MiB val DEFAULT_SOS_SIZE: Word = 2L * 1024L * 1024L; // 2MiB
...@@ -165,6 +166,14 @@ class MicroVM(vmConf: VMConf) { ...@@ -165,6 +166,14 @@ class MicroVM(vmConf: VMConf) {
val bs = new BundleSerializer(globalBundle, globalBundle.allTopLevels().toSet) val bs = new BundleSerializer(globalBundle, globalBundle.allTopLevels().toSet)
bs.writeUIR(w) bs.writeUIR(w)
} }
/**
* Load from a boot image.
*/
def loadBootImage(file: String): Unit = {
val bil = new BootImageLoader(file)
bil.load()
}
/** /**
* Execute. This is the external pusher of the execution. * Execute. This is the external pusher of the execution.
......
package uvm.refimpl.bootimg
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
import java.io.Reader
import java.nio.charset.StandardCharsets
import java.nio.file.Paths
import java.util.zip.ZipFile
import scala.collection.Map
import scala.collection.mutable.HashMap
import uvm.refimpl.MicroVM
import uvm.utils.WithUtils.tryWithResource
import uvm.utils.MappedIDFactory
class BootImageLoader(file: String)(implicit microVM: MicroVM) {
import BootImageWriter._
val bootImagePath = Paths.get(file)
val zip = new ZipFile(bootImagePath.toFile())
def zipFile(name: String): InputStream = zip.getInputStream(zip.getEntry(name))
def zipFileText(name: String): Reader = new InputStreamReader(zip.getInputStream(zip.getEntry(name)), StandardCharsets.UTF_8)
def zipFileTextBuf(name: String): BufferedReader = new BufferedReader(zipFileText(name))
def load(): Unit = {
loadUIRBundle()
}
private def loadUIRBundle(): Unit = {
val map = loadIDNameMap()
val mappedIDFactory = new MappedIDFactory(map)
tryWithResource(zipFileText(UIRBUNDLE_FILE)) { r =>
val bundle = microVM.irReader.read(r, microVM.globalBundle, mappedIDFactory)
microVM.addBundle(bundle)
}
val maxID = map.values.max
microVM.idFactory.setNextID(maxID+1)
}
private def loadIDNameMap(): Map[String, Int] = {
val map = new HashMap[String, Int]()
val idNameMapTxt = tryWithResource(zipFileTextBuf(IDNAMEMAP_FILE)) { br =>
var finished = false
while (!finished) {
Option(br.readLine()) match {
case None => finished = true
case Some(line) => {
val kv = line.split(",")
val id = kv(0).toInt
val name = kv(1)
map(name) = id
}
}
}
}
map
}
}
\ No newline at end of file
package uvm.utils package uvm.utils
import uvm.Identified import uvm.Identified
import scala.collection.Map
object IDFactory { object IDFactory {
def newClientIDFactory() = new SequentialIDFactory(Identified.FIRST_CLIENT_USABLE_ID) def newClientIDFactory() = new SequentialIDFactory(Identified.FIRST_CLIENT_USABLE_ID)
...@@ -28,7 +29,7 @@ class SequentialIDFactory(initialID: Int) extends IDFactory { ...@@ -28,7 +29,7 @@ class SequentialIDFactory(initialID: Int) extends IDFactory {
id = id + 1 id = id + 1
return myID return myID
} }
def setNextID(nextID: Int): Unit = { def setNextID(nextID: Int): Unit = {
id = nextID id = nextID
} }
...@@ -42,7 +43,7 @@ class MappedIDFactory(nameToID: Map[String, Int]) extends IDFactory { ...@@ -42,7 +43,7 @@ class MappedIDFactory(nameToID: Map[String, Int]) extends IDFactory {
def getID(name: String): Int = { def getID(name: String): Int = {
return nameToID(name) return nameToID(name)
} }
def setNextID(nextID: Int): Unit = { def setNextID(nextID: Int): Unit = {
throw new UnsupportedOperationException("MappedIDFactory cannot set the next ID") throw new UnsupportedOperationException("MappedIDFactory cannot set the next ID")
} }
......
...@@ -18,7 +18,7 @@ class BootImageWriterTest extends UvmBundleTesterBase with ExtraMatchers { ...@@ -18,7 +18,7 @@ class BootImageWriterTest extends UvmBundleTesterBase with ExtraMatchers {
val our = new MagicalOur(microVM.globalBundle) val our = new MagicalOur(microVM.globalBundle)
behavior of "BootImageWriter" behavior of "BootImageWriter"
it should "write everything to files" in { it should "write everything to files" in {
val everything = microVM.globalBundle.allTopLevels() val everything = microVM.globalBundle.allTopLevels()
...@@ -28,4 +28,16 @@ class BootImageWriterTest extends UvmBundleTesterBase with ExtraMatchers { ...@@ -28,4 +28,16 @@ class BootImageWriterTest extends UvmBundleTesterBase with ExtraMatchers {
val biw = new BootImageWriter(tcb, "target/boot-image-writer-test.muref")(microVM) val biw = new BootImageWriter(tcb, "target/boot-image-writer-test.muref")(microVM)
biw.writeFile() biw.writeFile()
} }
it should "write everything to files and read back" in {
val filename = "target/boot-image-read-write-test.muref"
val everything = microVM.globalBundle.allTopLevels()
microVM.makeBootImage(everything.map(_.id), filename)
val anotherMicroVM = MicroVM()
anotherMicroVM.loadBootImage(filename)
microVM.globalBundle.allNs("@gd").id shouldEqual anotherMicroVM.globalBundle.allNs("@gd").id
}
} }
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment