Commit ade25b5d authored by Kunshan Wang's avatar Kunshan Wang

bundle serialiser

parent a5de8215
"""
Generate match cases to match against instructions.
"""
from refimpl2injectablefiles import _refimpl2_root
import injecttools
import os.path, sys
import re
case_class_r = re.compile(r'case class (\w+)\(([^)]*)\)', re.MULTILINE)
param_r = re.compile(r'va[lr]\s+(\w+)\s*:\s*([a-zA-Z0-9\[\]_]+)', re.MULTILINE)
ssavariables_path = os.path.join(_refimpl2_root, "src/main/scala/uvm/ssavariables/ssavariables.scala")
def main():
with open(ssavariables_path) as f:
txt = f.read()
txt = injecttools.extract_lines(txt, "EXTRACT:BEGIN:INSTS", "EXTRACT:END:INSTS")
for name, params in case_class_r.findall(txt):
pns = []
for pn, pt in param_r.findall(params):
pns.append(pn)
print("case {}({}) => ".format(name, ", ".join(pns)))
if __name__=="__main__":
main()
......@@ -27,6 +27,44 @@ private[irbuilder] object IRBuilder {
implicit def childNodeAutoUnboxMany[T <: Identified](nodes: Seq[CN[T]]): Seq[T] = {
nodes.map(_.obj)
}
val validChars = {
val table = new Array[Boolean](256)
for (ch <- 'A' to 'Z') { table(ch) = true }
for (ch <- 'a' to 'z') { table(ch) = true }
for (ch <- '0' to '9') { table(ch) = true }
for (ch <- "_-.") { table(ch) = true }
table
}
val validSymbols = {
val table = new Array[Boolean](256)
for (ch <- 32 to 126) { table(ch) = true }
table('"') = false
table
}
def validateName(name: String): String = {
if (name.startsWith("%")) {
throw new IllegalNameException("Name must be global (starting with '@') when using the IR building API. Found: %s".format(name))
} else if (!name.startsWith("@")) {
throw new IllegalNameException("Name must start with '@'. Found: %s".format(name))
} else {
for (ch <- name.substring(1) if !validChars(ch)) {
throw new IllegalNameException("'%c' is not a valid character for Mu name. Name: %s".format(ch, name))
}
}
name
}
def validateSymbol(sym: String): String = {
for (ch <- sym if !validSymbols(ch)) {
throw new IllegalSymbolException("'%c' is not a valid character for external symbol. Symbol: %s".format(ch, sym))
}
sym
}
}
class IRBuilder(globalBundle: GlobalBundle, idFactory: IDFactory) {
......@@ -64,7 +102,7 @@ class IRBuilder(globalBundle: GlobalBundle, idFactory: IDFactory) {
}
def setName(b: BN, node: CN[IdentifiedSettable], name: String): Unit = {
node.name = Some(name)
node.name = Some(validateName(name))
// NOTE: When the name is set, the TrantientBundle's namespaces still do not index the object by its name,
// because the objects are added before their names are set. But by the time when the TrantientBundle is merged with
// the GlobalBundle, all objects in all namespaces will have been re-added to the GlobalBundle. For this reason,
......@@ -111,7 +149,7 @@ class IRBuilder(globalBundle: GlobalBundle, idFactory: IDFactory) {
def newConstDouble(b: BN, ty: CN[Type], value: Double): CN[ConstDouble] = newObj(b.constantNs, ConstDouble(ty, value))
def newConstNull (b: BN, ty: CN[Type]): CN[ConstNull] = newObj(b.constantNs, ConstNull(ty))
def newConstSeq (b: BN, ty: CN[Type], elems: Seq[CN[Constant]]): CN[ConstSeq] = newObj(b.constantNs, ConstSeq(ty, elems))
def newConstExtern(b: BN, ty: CN[Type], symbol: String): CN[ConstExtern] = newObj(b.constantNs, ConstExtern(ty, symbol))
def newConstExtern(b: BN, ty: CN[Type], symbol: String): CN[ConstExtern] = newObj(b.constantNs, ConstExtern(ty, validateSymbol(symbol)))
// format: ON
def newGlobalCell(b: BN, ty: CN[Type]): CN[GlobalCell] = newObj(b.globalCellNs, new GlobalCell(ty))
......
package uvm.ir.irbuilder
import uvm.UvmException
/** Base class for exceptions thrown by the IR builder. */
class IRBuilderException(message: String = null, cause: Throwable = null) extends UvmException(message, cause)
/**
* Thrown if the Mu name provided to setName is illegal
*/
class IllegalNameException(message: String = null, cause: Throwable = null) extends UvmException(message, cause)
/**
* Thrown if the external symbol provided to new_const_extern is illegal
*/
class IllegalSymbolException(message: String = null, cause: Throwable = null) extends UvmException(message, cause)
\ No newline at end of file
package uvm.ir.textoutput
import uvm.UvmException
class BundleSerializerException(message: String = null, cause: Throwable = null) extends UvmException(message, cause)
\ No newline at end of file
package uvm.refimpl
import java.io.Writer
import scala.collection.mutable.HashSet
import uvm._
import uvm.utils.IDFactory
import uvm.ir.irbuilder.IRBuilder
import uvm.ir.irbuilder.IRNode
import uvm.ir.textinput.UIRTextReader
import uvm.ir.textoutput.BundleSerializer
import uvm.refimpl.hail.HailScriptLoader
import uvm.refimpl.itpr._
import uvm.refimpl.mem._
import uvm.refimpl.mem.TypeSizes.Word
import uvm.refimpl.nat.NativeCallHelper
import uvm.refimpl.nat.NativeLibraryHolder
import uvm.staticanalysis.StaticAnalyzer
import uvm.utils.IDFactory
import uvm.ir.irbuilder.IRBuilder
import uvm.ir.irbuilder.IRNode
import uvm.refimpl.nat.NativeLibraryHolder
object MicroVM {
val DEFAULT_SOS_SIZE: Word = 2L * 1024L * 1024L; // 2MiB
......@@ -123,20 +125,12 @@ class MicroVM(vmConf: VMConf) {
/**
* Given a name, get the ID of an identified entity.
*/
def idOf(name: String): Int = try {
globalBundle.allNs(name).id
} catch {
case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has name %s".format(name), e)
}
def idOf(name: String): Int = globalBundle.allNs(name).id
/**
* Given an ID, get the name of an identified entity.
*/
def nameOf(id: Int): String = try {
globalBundle.allNs(id).name.get
} catch {
case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has ID %d".format(id), e)
}
def nameOf(id: Int): String = globalBundle.allNs(id).name.get
/**
* Set the trap handler.
......@@ -151,6 +145,14 @@ class MicroVM(vmConf: VMConf) {
def makeBootImage(whiteList: Seq[Int], outputFile: String): Unit = {
???
}
/**
*
*/
def debugPrintGlobalBundle(w: Writer): Unit = {
val bs = new BundleSerializer(globalBundle, None)
bs.writeUIR(w)
}
/**
* Execute. This is the external pusher of the execution.
......
......@@ -170,9 +170,14 @@ case class ThrowExc(var exc: SSAVariable) extends NewStackAction
/**
* Flags are used in common instructions.
*/
case class Flag(name: String)
case class Flag(name: String) {
if (!name.startsWith("#")) {
throw new UvmException("Flag must start with '#'. Found: '%s'".format(name))
}
}
/// Concrete instructions
/// EXTRACT:BEGIN:INSTS
case class InstBinOp(var op: BinOptr, var opndTy: Type, var op1: SSAVariable, var op2: SSAVariable,
var excClause: Option[ExcClause]) extends HasExcClause
......@@ -271,3 +276,4 @@ case class InstCommInst(var inst: CommInst, var flagList: Seq[Flag], var typeLis
extends HasTypeList with HasArgList with HasExcClause with HasKeepaliveClause {
override def canTerminate: Boolean = excClause.isDefined || inst.isTerminator
}
/// EXTRACT:END:INSTS
\ No newline at end of file
......@@ -54,20 +54,20 @@ object Type {
case TypeInt(length) => "int<%d>".format(length)
case TypeFloat() => "float"
case TypeDouble() => "double"
case TypeRef(ty) => "ref<%s>".format(ty.repr)
case TypeIRef(ty) => "iref<%s>".format(ty.repr)
case TypeWeakRef(ty) => "weakref<%s>".format(ty.repr)
case TypeUPtr(ty) => "uptr<%s>".format(ty.repr)
case TypeUFuncPtr(sig) => "ufuncptr<%s>".format(sig.repr)
case TypeStruct(fieldTys) => "struct<%s>".format(fieldTys.map(_.repr).mkString(" "))
case TypeArray(elemTy, len) => "array<%s %d>".format(elemTy.repr, len)
case TypeHybrid(fieldTys, varPart) => "hybrid<%s %s>".format(fieldTys.map(_.repr).mkString(" "), varPart.repr)
case TypeArray(elemTy, len) => "array<%s %d>".format(elemTy.repr, len)
case TypeVector(elemTy, len) => "vector<%s %d>".format(elemTy.repr, len)
case TypeVoid() => "void"
case TypeRef(ty) => "ref<%s>".format(ty.repr)
case TypeIRef(ty) => "iref<%s>".format(ty.repr)
case TypeWeakRef(ty) => "weakref<%s>".format(ty.repr)
case TypeTagRef64() => "tagref64"
case TypeFuncRef(sig) => "funcref<%s>".format(sig.repr)
case TypeThreadRef() => "threadref"
case TypeStackRef() => "stackref"
case TypeTagRef64() => "tagref64"
case TypeVector(elemTy, len) => "vector<%s %d>".format(elemTy.repr, len)
case TypeUPtr(ty) => "uptr<%s>".format(ty.repr)
case TypeUFuncPtr(sig) => "ufuncptr<%s>".format(sig.repr)
case TypeFrameCursorRef() => "framecursorref"
case TypeIRNodeRef() => "irnoderef"
case _ => "unknown type " + ty.getClass.getName
......
......@@ -12,6 +12,8 @@ import jnr.posix.POSIXFactory
import uvm.refimpl.itpr.MemoryOperations
import java.nio.charset.StandardCharsets
import uvm.refimpl.HowToResume
import java.io.StringWriter
import java.io.OutputStreamWriter
class NativeLibraryHolderTest extends UvmBundleTesterBase {
behavior of "NativeLibraryHolder"
......@@ -23,11 +25,16 @@ class NativeLibraryHolderTest extends UvmBundleTesterBase {
val b = ctx.newBundle()
val int_t = ctx.newTypeInt(b, 32)
ctx.setName(b, int_t, "@int")
val void_t = ctx.newTypeVoid(b)
ctx.setName(b, void_t, "@void")
val voidp_t = ctx.newTypeUPtr(b)
ctx.setName(b, voidp_t, "@voidp")
ctx.setTypeUPtr(voidp_t, void_t)
val size_t = ctx.newTypeInt(b, 64)
ctx.setName(b, size_t, "@size_t")
val ssize_t = ctx.newTypeInt(b, 64)
ctx.setName(b, ssize_t, "@ssize_t")
val write_sig = ctx.newFuncSig(b, Seq(int_t, voidp_t, size_t), Seq(ssize_t))
......@@ -71,6 +78,8 @@ class NativeLibraryHolderTest extends UvmBundleTesterBase {
ctx.loadBundleFromNode(b)
System.err.print("Bundle dump:\n")
microVM.debugPrintGlobalBundle(new OutputStreamWriter(System.err))
val h_hw_g_ir = ctx.handleFromGlobal(hw_g_id)
......
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