...
 
Commits (32)
......@@ -12,3 +12,4 @@ hs_err_pid*.log
/bin/
*.py[co]
classpath.txt
build.properties
......@@ -17,12 +17,12 @@ Specification](https://gitlab.anu.edu.au/mu/mu-spec).
* Install JDK 8. If you use Mac, download from
[Oracle](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html).
* If you use Mac, install [Homebrew](http://brew.sh/).
* Install [Scala](http://scala-lang.org/) 2.11. If you use Mac and Homebrew,
* Install [Scala](http://scala-lang.org/) 2.12. If you use Mac and Homebrew,
`brew install scala`.
* Install [sbt](http://www.scala-sbt.org/) 0.13. If you use Mac and Homebrew,
* Install [sbt](http://www.scala-sbt.org/) 1.0. If you use Mac and Homebrew,
`brew install sbt`.
* Install [Scala IDE](http://scala-ide.org/) 4.x (Eclipse with pre-installed
plugins for Scala).
* Install [Scala IDE](http://scala-ide.org/) 4.6 or later (Eclipse with
pre-installed plugins for Scala).
* Clone this repository:
```bash
......@@ -49,8 +49,8 @@ sbt update genSrc eclipse
The reference implementation is developed and tested with Java VM 8. You need a
JRE to build the Scala/Java part, and a JDK to build the C binding.
You also need [Scala](http://scala-lang.org/) 2.11 and
[sbt](http://www.scala-sbt.org/) 0.13. It is recommended to install them using
You also need [Scala](http://scala-lang.org/) 2.12 and
[sbt](http://www.scala-sbt.org/) 1.0. It is recommended to install them using
the package manager of your operating system or distribution (such as apt-get,
yum, pacman, etc. for GNU/Linux distributions and Homebrew for Mac OS X) if such
packages are available.
......@@ -58,7 +58,7 @@ packages are available.
For Ubuntu users: Ubuntu 15.10 does not provide sbt in its repository. Please
[download sbt](http://www.scala-sbt.org/download.html) from the official sbt web
site, or follow the [official sbt installing guide for
Linux](http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html). If
Linux](http://www.scala-sbt.org/1.x/docs/Installing-sbt-on-Linux.html). If
you experience any "certificate" problems, [this
page](https://github.com/sbt/sbt/issues/2295) provides a solution.
......@@ -69,7 +69,7 @@ compile this project. Or you can do it step by step:
update`.
* To generate the Mu IR parser from the Antlr grammar, invoke `sbt genSrc`. The
generated sources will be in the `target/scala-2.11/src_managed` directory.
generated sources will be in the `target/scala-2.12/src_managed` directory.
* To compile, invoke `sbt compile`. This will also generate the Mu IR parser
using Antlr.
......@@ -93,6 +93,31 @@ need to be built.
See [cbinding/README.md](cbinding/README.md) and
[pythonbinding/README.md](pythonbinding/README.md) for more details.
## How to test
For the impatient: run the `test.sh` script.
Detailed steps:
1. Compile native programs necessary for testing the native interface:
```bash
pushd tests/c-snippets
make
popd
```
2. Set the `TRAVIS` environment variable to `true`:
```bash
export TRAVIS=true
```
This will tell the test cases in `src/test/scala` not to print excessive logs
which would be helpful for identifying problems for individual test cases.
3. Run `sbt test`.
## How to run
For the impatient: Execute the following command and see Mu running a factorial
......@@ -210,8 +235,26 @@ globalSize must be a multiple of 32768 bytes (32K).*
any extra libraries.
- **bootImg**: The path to the boot image. Only useful in the C API. By default,
it does not load any boot image.
- **uPtrHack**: When true, it will allow memory locations of general reference
types to be accessed by `uptr<T>`. By default, such fields can only be
accessed by `iref<T>`, but this hack is necessary for the current
[mu-client-pypy](https://gitlab.anu.edu.au/mu/mu-client-pypy/) project to
work. default: false
Holstein uses the [logback](https://logback.qos.ch/) framework as its logging
backend. Logs can be configured using XML configuration by specifying the
following option:
- **logbackConfig**: The path to the logback XML configuration file.
Example:
```
./tools/runmu.sh --logbackConfig=./logging/logging.xml -- ./target/boot-image-echo.muref Hello world!
```
*Log levels can be: ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF. Case-insensitive.
Alternatively, you can set the log level using the following options. *Log
levels can be: ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF. Case-insensitive.
Setting to WARN should get rid of most logging information, except the serious
ones.* The default log level is DEBUG.
......
enablePlugins(Antlr4Plugin)
lazy val genSrc = taskKey[List[File]]("generate sources")
genSrc <<= (sourceGenerators in Compile) { _.join.map(_.flatten.toList) }
genSrc := (sourceGenerators in Compile) { _.join.map(_.flatten.toList) }.value
lazy val makeClasspathFile = taskKey[Unit]("write the run-time classpath to target/jars.txt as colon-separated list")
......@@ -17,31 +18,33 @@ lazy val root = (project in file(".")).
licenses := Seq("CC BY-SA 4.0" -> url("https://creativecommons.org/licenses/by-sa/4.0/legalcode")),
scalaVersion := "2.11.8",
scalaVersion := "2.12.6",
libraryDependencies ++= Seq(
"org.antlr" % "antlr4" % "4.5.3",
"com.typesafe.scala-logging" %% "scala-logging" % "3.5.0",
"ch.qos.logback" % "logback-classic" % "1.1.7",
"com.github.jnr" % "jnr-ffi" % "2.0.9",
"com.github.jnr" % "jffi" % "1.2.12" classifier "native",
"com.github.jnr" % "jnr-posix" % "3.0.29",
"org.scalatest" %% "scalatest" % "3.0.0" % "test",
"org.antlr" % "antlr4" % "4.7.1",
"com.typesafe.scala-logging" %% "scala-logging" % "3.9.0",
"ch.qos.logback" % "logback-classic" % "1.2.3",
"com.github.jnr" % "jnr-ffi" % "2.1.7",
"com.github.jnr" % "jffi" % "1.2.16" classifier "native",
"com.github.jnr" % "jnr-posix" % "3.0.44",
"org.scalatest" %% "scalatest" % "3.0.5" % "test",
"junit" % "junit" % "4.12" % "test"
),
scalacOptions += "-language:implicitConversions",
testOptions in Test += Tests.Argument("-oF"), // print full stack trace when testing
parallelExecution in Test := false, // disable parallel tests because the refimpl2 is not thread-safe
antlr4Settings,
antlr4PackageName in Antlr4 := Some("uvm.ir.textinput.gen"),
antlr4GenListener in Antlr4 := false,
antlr4GenVisitor in Antlr4 := false,
antlr4Version in Antlr4 := "4.7.1",
makeClasspathFile := {
val cp = (fullClasspath in Runtime).value.files
......
*.so
*.dylib
test_client
test_client2
classpath.txt
......
......@@ -2,10 +2,20 @@ ifndef JAVA_HOME
$(error JAVA_HOME is required. Invoke with 'make JAVA_HOME=/path/to/java/home')
endif
unamem := $(shell uname -m)
ifeq ($(unamem),x86_64)
JDKARCH := amd64
else ifeq ($(unamem),aarch64)
JDKARCH := aarch64
else
$(error Unsupported architecture: $(unamem))
endif
CFLAGS += -std=gnu11 -g -I $(JAVA_HOME)/include
ifndef OS
uname := $(shell uname)
uname := $(shell uname)
ifeq ($(uname),Darwin)
OS = OSX
else ifeq ($(uname),Linux)
......@@ -17,21 +27,29 @@ endif
ifeq ($(OS),OSX)
CFLAGS += -I $(JAVA_HOME)/include/darwin
LDFLAGS += -L $(JAVA_HOME)/jre/lib/server -l jvm -rpath $(JAVA_HOME)/jre/lib/server -install_name '@rpath/libmurefimpl2start.so'
LDFLAGS += -L $(JAVA_HOME)/lib/jli -l jli -rpath $(JAVA_HOME)/lib/jli -install_name '@rpath/libmurefimpl2start.so'
else ifeq ($(OS),LINUX)
CFLAGS += -I $(JAVA_HOME)/include/linux
LDFLAGS += -Wl,--no-as-needed -L $(JAVA_HOME)/jre/lib/amd64/server -l jvm -Wl,-rpath,$(JAVA_HOME)/jre/lib/amd64/server
LDFLAGS += -Wl,--no-as-needed -L $(JAVA_HOME)/jre/lib/$(JDKARCH)/server -l jvm -Wl,-rpath,$(JAVA_HOME)/jre/lib/$(JDKARCH)/server
endif
.PHONY: all
all: libs tests
ifeq ($(OS),OSX)
.PHONY: libs
libs: libmurefimpl2start.so libmurefimpl2start.dylib
else
.PHONY: libs
libs: libmurefimpl2start.so
endif
libmurefimpl2start.so: refimpl2-start.c classpath.h
$(CC) -fPIC -shared $(CFLAGS) -o $@ $< $(LDFLAGS)
libmurefimpl2start.dylib:
ln -s libmurefimpl2start.so libmurefimpl2start.dylib
../classpath.txt: ../build.sbt
cd .. ; sbt makeClasspathFile
......@@ -50,7 +68,7 @@ test_client2: test_client2.c libmurefimpl2start.so
.PHONY: clean veryclean
clean:
rm -f *.so test_client test_client2
rm -f *.so test_client test_client2 *.dylib
veryclean: clean
rm -f classpath.txt classpath.h ../classpath.txt
......@@ -83,7 +83,7 @@ typedef MuGenRefValue MuIBRefValue; // irbuilderref
// Mu IR. If you want to build IR using this C API, use MuCtx->new_ir_builder.
// C-style '\0'-terminated string
typedef char *MuCString;
typedef const char *MuCString;
// Identifiers and names of Mu
typedef uint32_t MuID;
......@@ -408,7 +408,7 @@ struct MuCtx {
// On-stack replacement
void (*pop_frames_to)(MuCtx *ctx, MuFCRefValue cursor);
void (*push_frame )(MuCtx *ctx, MuStackRefValue stack, MuFuncRefValue func);
void (*push_frame )(MuCtx *ctx, MuFCRefValue cursor, MuFuncRefValue func);
// 64-bit tagged reference operations
MuBool (*tr64_is_fp )(MuCtx *ctx, MuTagRef64Value value);
......@@ -798,6 +798,10 @@ struct MuIRBuilder {
#define MU_CI_UVM_META_ENABLE_WATCHPOINT ((MuCommInst)0x25e) /// MUAPIPARSER muname:@uvm.meta.enable_watchpoint
#define MU_CI_UVM_META_DISABLE_WATCHPOINT ((MuCommInst)0x25f) /// MUAPIPARSER muname:@uvm.meta.disable_watchpoint
#define MU_CI_UVM_META_SET_TRAP_HANDLER ((MuCommInst)0x260) /// MUAPIPARSER muname:@uvm.meta.set_trap_handler
#define MU_CI_UVM_META_CONSTANT_BY_ID ((MuCommInst)0x268) /// MUAPIPARSER muname:@uvm.meta.constant_by_id
#define MU_CI_UVM_META_GLOBAL_BY_ID ((MuCommInst)0x269) /// MUAPIPARSER muname:@uvm.meta.global_by_id
#define MU_CI_UVM_META_FUNC_BY_ID ((MuCommInst)0x26a) /// MUAPIPARSER muname:@uvm.meta.func_by_id
#define MU_CI_UVM_META_EXPFUNC_BY_ID ((MuCommInst)0x26b) /// MUAPIPARSER muname:@uvm.meta.expfunc_by_id
#define MU_CI_UVM_IRBUILDER_NEW_IR_BUILDER ((MuCommInst)0x270) /// MUAPIPARSER muname:@uvm.irbuilder.new_ir_builder
#define MU_CI_UVM_IRBUILDER_LOAD ((MuCommInst)0x300) /// MUAPIPARSER muname:@uvm.irbuilder.load
#define MU_CI_UVM_IRBUILDER_ABORT ((MuCommInst)0x301) /// MUAPIPARSER muname:@uvm.irbuilder.abort
......
<!-- This is an example. Make a copy of this file, and modify it for your need. -->
<configuration>
<!-- Set debug="true" to enable debugging for the logback logging framework itself -->
<!-- configuration debug="true" -->
<!-- This appender writes into stdout -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="uvm.refimpl.itpr" level="DEBUG" />
<!-- This appender writes into stderr -->
<appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender">
<target>System.err</target>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Loggers are organised by packages. uvm includes everything in Holstein. -->
<logger name="uvm" level="INFO" />
<logger name="uvm.refimpl.itpr" level="INFO" /> <!-- Set this to DEBUG to print execution traces. -->
<logger name="uvm.refimpl.mem" level="INFO" /> <!-- Set this to DEBUG to print GC logs. -->
<root level="INFO">
<appender-ref ref="STDERR" />
</root>
</configuration>
<!--
vim: ts=2 sw=2 sts=2 et
-->
......@@ -15,7 +15,7 @@ r_param = re.compile(r'\s*(?P<type>\w+\s*\*?)\s*(?P<name>\w+)')
r_define = re.compile(r'^\s*#define\s+(?P<name>\w+)\s*\(\((?P<type>\w+)\)(?P<value>\w+)\)\s*' + rfrag_commpragma + r'\s*$', re.MULTILINE)
r_typedef = re.compile(r'^\s*typedef\s+(?P<expand_to>\w+\s*\*?)\s*(?P<name>\w+)\s*;', re.MULTILINE)
r_typedef = re.compile(r'^\s*typedef\s+(?P<const>const\s+)?(?P<expand_to>\w+\s*\*?)\s*(?P<name>\w+)\s*;', re.MULTILINE)
r_struct_start = re.compile(r'^struct\s+(\w+)\s*\{')
r_struct_end = re.compile(r'^\};')
......@@ -141,7 +141,7 @@ def extract_typedefs(text):
typedefs = {}
typedefs_order = []
for m in r_typedef.finditer(text):
expand_to, name = m.groups()
const_qualifier, expand_to, name = m.groups()
expand_to = expand_to.replace(" ","")
typedefs[name] = expand_to
typedefs_order.append((name, expand_to))
......
......@@ -326,8 +326,14 @@ def gen_comminst_impl(comminst):
lines.append(' val {} = {} != 0'.format(bool_name, cname))
ir_builder_args.append(bool_name)
elif cty in ["MuName", "MuCString"]:
str_name = "_str_" + cname
lines.append(' val {} = loadCString({})'.format(str_name, cname))
if cname in comminst.optionals:
str_name = "_maybestr_" + cname
lines.append(' val {} = loadMaybeCString({})'.format(str_name, cname))
else:
str_name = "_str_" + cname
lines.append(' val {} = loadCString({})'.format(str_name, cname))
ir_builder_args.append(str_name)
else:
ir_builder_args.append(cname)
......@@ -381,7 +387,7 @@ def main():
"comminsts.scala": {
"IRBUILDER_COMMINSTS": comminsts_defs,
},
"internals.scala": {
"TypeInferer.scala": {
"IRBUILDER_RETVALS": comminsts_retvals,
},
"InstructionResultInferer.scala": {
......
......@@ -19,7 +19,7 @@ injectable_files = injecttools.make_injectable_file_set(_refimpl2_root, [
"wrp_MuIRBuilder"]),
("comminsts.scala", "src/main/scala/uvm/comminsts/comminsts.scala",
["IRBUILDER_COMMINSTS"]),
("internals.scala", "src/main/scala/uvm/refimpl/internals.scala",
("TypeInferer.scala", "src/main/scala/uvm/staticanalysis/TypeInferer.scala",
["IRBUILDER_RETVALS"]),
("InstructionResultInferer.scala", "src/main/scala/uvm/staticanalysis/InstructionResultInferer.scala",
["IRBUILDER_RETVAL_NUMS"]),
......
resolvers += "simplytyped" at "http://simplytyped.github.io/repo/releases"
// resolvers += "simplytyped" at "http://simplytyped.github.io/repo/releases"
addSbtPlugin("com.simplytyped" % "sbt-antlr4" % "0.7.10")
addSbtPlugin("com.simplytyped" % "sbt-antlr4" % "0.8.1")
// lazy val root = (project in file(".")).dependsOn(sbtAntlr4Plugin)
// lazy val sbtAntlr4Plugin = uri("https://github.com/ihji/sbt-antlr4.git")
\ No newline at end of file
// lazy val sbtAntlr4Plugin = uri("https://github.com/ihji/sbt-antlr4.git")
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "4.0.0")
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.2")
......@@ -385,6 +385,10 @@ common_instruction_opcodes = {
'@uvm.meta.enable_watchpoint': 0x25e,
'@uvm.meta.disable_watchpoint': 0x25f,
'@uvm.meta.set_trap_handler': 0x260,
'@uvm.meta.constant_by_id': 0x268,
'@uvm.meta.global_by_id': 0x269,
'@uvm.meta.func_by_id': 0x26a,
'@uvm.meta.expfunc_by_id': 0x26b,
'@uvm.irbuilder.new_ir_builder': 0x270,
'@uvm.irbuilder.load': 0x300,
'@uvm.irbuilder.abort': 0x301,
......@@ -466,6 +470,8 @@ common_instruction_opcodes = {
'@uvm.irbuilder.new_newthread': 0x34d,
'@uvm.irbuilder.new_swapstack': 0x34e,
'@uvm.irbuilder.new_comminst': 0x34f,
'@uvm.ext.print_stats': 0xc001,
'@uvm.ext.clear_stats': 0xc002,
}
## GEN:END:CENUMS
......@@ -1594,7 +1600,7 @@ _initialize_methods(MuCtx, [
('cur_inst', CMuID, [MuFCRefValue]),
('dump_keepalives_', None, [MuFCRefValue, ctypes.c_void_p]),
('pop_frames_to', None, [MuFCRefValue]),
('push_frame', None, [MuStackRefValue, MuFuncRefValue]),
('push_frame', None, [MuFCRefValue, MuFuncRefValue]),
('tr64_is_fp', bool, [MuTagRef64Value]),
('tr64_is_int', bool, [MuTagRef64Value]),
('tr64_is_ref', bool, [MuTagRef64Value]),
......
package uvm.clientsupport.text
import java.util
import scala.collection.JavaConversions._
/**
* A Mu IR bundle. This class is more representation-oriented rather than semantic oriented. For example, there are
* "type definitions" rather than "types". Similarly "function definitions" and "function declarations" are separated
* rather than contained in each other.
*/
class Bundle(
cTypeDefs: TraversableOnce[(TypeName, TypeCtor)],
cFuncSigDefs: TraversableOnce[(FuncSigName, FuncSig)],
cConstDefs: TraversableOnce[(GlobalVarName, Const)],
cGlobalCellDefs: TraversableOnce[(GlobalVarName, TypeName)],
cFuncDecls: TraversableOnce[(GlobalVarName, FuncSigName)],
cFuncVers: TraversableOnce[(FuncVerName, PostFuncVer)],
cFuncExpDefs: TraversableOnce[(GlobalVarName, Expose)],
cComments: TraversableOnce[(GlobalName, String)]
) {
private def buildMap[K, V](seq: TraversableOnce[(K, V)]): util.Map[K, V] = {
val map = new util.LinkedHashMap[K, V]
seq foreach { case (k, v) => map.put(k, v) }
map
}
lazy val typeDefs = buildMap(cTypeDefs)
lazy val funcSigDefs = buildMap(cFuncSigDefs)
lazy val constDefs = buildMap(cConstDefs)
lazy val globalCellDefs = buildMap(cGlobalCellDefs)
lazy val funcDecls = buildMap(cFuncDecls)
lazy val funcVers = buildMap(cFuncVers)
lazy val funcExpDefs = buildMap(cFuncExpDefs)
lazy val comments = buildMap(cComments)
override lazy val toString = {
val sb = new StringBuilder
def printBlock[N <: GlobalName, V](block: util.Map[N, V])(fn: (N, V) => Unit): Unit =
if (!block.isEmpty) {
sb append "\n"
block foreach { case (name, value) =>
Option(comments get name) foreach (_ split '\n' map ("// " + _ + "\n") foreach sb.append)
fn(name, value)
}
}
printBlock(typeDefs)((name, ctor) => sb append s".typedef $name = $ctor\n")
printBlock(funcSigDefs)((name, sig) => sb append s".funcsig $name = $sig\n")
printBlock(constDefs)((name, const) => sb append s".const $name <${const.ty}> = $const\n")
printBlock(globalCellDefs)((name, ty) => sb append s".global $name <$ty>\n")
printBlock(funcDecls)((name, sig) => sb append s".funcdecl $name <$sig>\n")
printBlock(funcExpDefs)((name, exp) => sb append s".expose $name = $exp\n")
printBlock(funcVers)((name, ver) =>
sb append s".funcdef ${ver.func} VERSION $name <${ver.sig}> $ver\n\n")
sb.toString
}
}
package uvm.clientsupport.text
import java.util
import scala.collection.JavaConversions
class IList[T](members: TraversableOnce[T]) extends util.AbstractList[T] with Traversable[T] {
def this(membersIterable: java.lang.Iterable[T]) =
this(JavaConversions iterableAsScalaIterable membersIterable)
private val vector = members.toVector
override def get(index: Int): T = vector(index)
override def size: Int = vector.length
override def isEmpty: Boolean = vector.isEmpty
override def toString = vector mkString " "
override def foreach[U](f: (T) => U): Unit = vector foreach f
def apply(idx: Int): T = vector(idx)
}
object IList {
def apply[T](members: T*): IList[T] = new IList(members)
def empty[T]: IList[T] = new IList[T](Nil)
}
This diff is collapsed.
This diff is collapsed.
package uvm.clientsupport.text
sealed abstract class TypeCtor(str: => String) {
override lazy val toString: String = str
}
object TypeCtor {
def Void = Singletons.Void; type Void = Singletons.Void.type
case class Int(bits: scala.Int) extends TypeCtor(s"int<$bits>")
def Float = Singletons.Float; type Float = Singletons.Float.type
def Double = Singletons.Double; type Double = Singletons.Double.type
def ThreadRef = Singletons.ThreadRef; type ThreadRef = Singletons.ThreadRef.type
def StackRef = Singletons.StackRef; type StackRef = Singletons.StackRef.type
def FrameCursorRef = Singletons.FrameCursorRef; type FrameCursorRef = Singletons.FrameCursorRef.type
case class Ref(ty: TypeCtor) extends TypeCtor(s"ref<$ty>")
case class IRef(ty: TypeCtor) extends TypeCtor(s"iref<$ty>")
case class WeakRef(ty: TypeCtor) extends TypeCtor(s"weakref<$ty>")
case class FuncRef(sig: FuncSigName) extends TypeCtor(s"funcref<$sig>")
case class UPtr(ty: TypeCtor) extends TypeCtor(s"uptr<$ty>")
case class UFuncPtr(sig: FuncSigName) extends TypeCtor(s"ufuncptr<$sig>")
def TagRef64 = Singletons.TagRef64; type TagRef64 = Singletons.TagRef64.type
case class Array(ty: TypeCtor, len: scala.Long) extends TypeCtor(s"array<$ty $len>")
case class Vector(ty: TypeCtor, len: scala.Int) extends TypeCtor(s"vector<$ty $len>")
case class Hybrid(fixedTy: TypeCtor, varTy: TypeCtor) extends TypeCtor(s"hybrid<$fixedTy $varTy>")
case class Struct(types: IList[TypeCtor]) extends TypeCtor(s"struct<${types mkString " "}>")
object Singletons {
case object Void extends TypeCtor("void")
case object Float extends TypeCtor("float")
case object Double extends TypeCtor("double")
case object ThreadRef extends TypeCtor("threadref")
case object StackRef extends TypeCtor("stackref")
case object FrameCursorRef extends TypeCtor("framecursorref")
case object TagRef64 extends TypeCtor("tagref64")
}
}
sealed trait MuName {
def name: String
}
sealed trait GlobalName extends MuName {
override lazy val toString = "@" + name
}
sealed trait LocalName extends MuName {
override lazy val toString = "%" + name
}
sealed trait VarName extends MuName
case class TypeName(name: String) extends TypeCtor("@" + name) with GlobalName
case class FuncSigName(name: String) extends GlobalName
case class FuncVerName(name: String) extends GlobalName
case class GlobalVarName(name: String) extends GlobalName with VarName
case class LocalVarName(name: String) extends LocalName with VarName
case class LabelName(name: String) extends LocalName
final class Flag(cName: String) {
val name = cName.toUpperCase.replaceAll("[^A-Z_]", "")
override def toString = "#" + name
}
package uvm.clientsupport.text
sealed abstract class Const(str: => String) {
def ty: TypeName
override def toString = str
}
object Const {
case class Null(ty: TypeName) extends Const("NULL")
case class Int(ty: TypeName, value: scala.Long) extends Const(value.toString)
case class Float(ty: TypeName, value: scala.Float)
extends Const(s"bitsf(0x${Integer.toHexString(java.lang.Float.floatToRawIntBits(value))})")
case class Double(ty: TypeName, value: scala.Double)
extends Const(s"bitsd(0x${java.lang.Long.toHexString(java.lang.Double.doubleToRawLongBits(value))})")
case class Pointer(ty: TypeName, addr: scala.Long) extends Const(addr.toString)
case class List(ty: TypeName, fields: IList[GlobalVarName]) extends Const(s"{$fields}")
}
case class FuncSig(paramTy: IList[TypeName], retTy: IList[TypeName]) {
override def toString = s"($paramTy) -> ($retTy)"
}
case class PreFuncVer(
func: GlobalVarName,
sig: FuncSigName,
params: IList[LocalVarName],
bbs: IList[PreBasicBlock]
) {
override lazy val toString = "(" + params + ") {\n" + (bbs mkString "\n") + "\n}"
}
case class PostFuncVer(func: GlobalVarName, sig: FuncSigName, bbs: IList[PostBasicBlock]) {
override lazy val toString = "{\n" + (bbs mkString "\n") + "\n}"
}
case class Expose(func: GlobalVarName, callConv: Flag, cookie: GlobalVarName) {
override def toString = s"$func $callConv $cookie"
}
trait Context {
def resolve(typeName: TypeName): Option[TypeCtor]
def resolve(funcSigName: FuncSigName): Option[FuncSig]
def typeDef(ctor: TypeCtor): TypeName
def funcSig(args: IList[TypeName], ret: IList[TypeName]): FuncSigName
def constDef(c: Const): GlobalVarName
}
\ No newline at end of file
......@@ -64,6 +64,13 @@ object CommInsts extends SimpleNamespace[CommInst] {
commInst(0x25f, "@uvm.meta.disable_watchPoint")
commInst(0x260, "@uvm.meta.set_trap_handler")
commInst(0x268, "@uvm.meta.constant_by_id")
commInst(0x269, "@uvm.meta.global_by_id")
commInst(0x26a, "@uvm.meta.func_by_id")
commInst(0x26b, "@uvm.meta.expfunc_by_id")
commInst(0x270, "@uvm.irbuilder.new_ir_builder")
// Proprietary extensions specific to this refimpl
commInst(0xc001, "@uvm.ext.print_stats")
......
package uvm.ir.irbuilder
import scala.collection.mutable.ArrayBuffer
import uvm._
import uvm.ir.irbuilder.IRBuilderNode._
import uvm.ssavariables._
import uvm.types._
import uvm.utils.Later
import uvm.utils.Later._
import uvm.ir.irbuilder.IRBuilderNode._
import scala.collection.mutable.ArrayBuffer
/** This class converts the soup of ID-referenced nodes into the refimpl's internal AST. */
class BundleConstructor(idNameMap: Map[MuID, MuName], nodeList: Seq[IRBuilderNode], globalBundle: GlobalBundle) {
......@@ -81,6 +82,7 @@ class BundleConstructor(idNameMap: Map[MuID, MuName], nodeList: Seq[IRBuilderNod
val typeNodes = new ArrayBuffer[IRTypeNode]
val sigNodes = new ArrayBuffer[IRSigNode]
val constNodes = new ArrayBuffer[IRConstNode]
val expFuncNodes = new ArrayBuffer[NodeExpFunc]
val otherTopLevelNodes = new ArrayBuffer[OtherTopLevelNode]
val funcVers = new ArrayBuffer[NodeFuncVer]()
val otherNodes = new ArrayBuffer[IRBuilderNode]
......@@ -89,6 +91,7 @@ class BundleConstructor(idNameMap: Map[MuID, MuName], nodeList: Seq[IRBuilderNod
case n: IRTypeNode => typeNodes += n
case n: IRSigNode => sigNodes += n
case n: IRConstNode => constNodes += n
case n: NodeExpFunc => expFuncNodes += n
case n: OtherTopLevelNode => otherTopLevelNodes += n
case n: NodeFuncVer => funcVers += n
case n => otherNodes += n
......@@ -181,6 +184,10 @@ class BundleConstructor(idNameMap: Map[MuID, MuName], nodeList: Seq[IRBuilderNod
setIDAndMaybeName(muNode, id)
bundle.funcNs.add(muNode)
}
}
// Build ExposedFunc instances after building Function instances.
expFuncNodes foreach {
case NodeExpFunc(id: MuID, func: MuFuncNode, callconv: Flag, cookie: MuConstIntNode) => {
val muNode = new ExposedFunc(func, callconv, resConstInt(cookie))
setIDAndMaybeName(muNode, id)
......
package uvm.ir.textinput
import scala.collection.JavaConversions._
import scala.collection.JavaConverters._
import scala.collection.mutable.ArrayBuffer
import org.antlr.v4.runtime._
......@@ -41,11 +41,11 @@ class UIRTextReader(val defaultIDFactory: IDFactory, val recordSourceInfo: Boole
def read(ir: String, globalBundle: GlobalBundle, idFactory : IDFactory): TrantientBundle = {
logger.debug("Creating ANTLRInputStream...")
val input = new ANTLRInputStream(ir)
val input = CharStreams.fromString(ir)
read(ir, input, globalBundle, idFactory)
}
def parse(source: String, ais: ANTLRInputStream): IrContext = {
def parse(source: String, ais: CharStream): IrContext = {
logger.debug("Creating AccumulativeAntlrErrorListener...")
val ea = new AccumulativeAntlrErrorListener(source)
......@@ -67,11 +67,11 @@ class UIRTextReader(val defaultIDFactory: IDFactory, val recordSourceInfo: Boole
ast
}
def read(source: String, ais: ANTLRInputStream, globalBundle: GlobalBundle): TrantientBundle = {
def read(source: String, ais: CharStream, globalBundle: GlobalBundle): TrantientBundle = {
read(source, ais, globalBundle, defaultIDFactory)
}
def read(source: String, ais: ANTLRInputStream, globalBundle: GlobalBundle, idFactory: IDFactory): TrantientBundle = {
def read(source: String, ais: CharStream, globalBundle: GlobalBundle, idFactory: IDFactory): TrantientBundle = {
val ast = parse(source, ais)
logger.debug("Antlr parsed. Reading UIR AST into a Bundle...")
val instanceReader = new InstanceUIRTextReader(idFactory, source, ast, globalBundle, recordSourceInfo)
......@@ -118,11 +118,11 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
def resFuncByName(name: String): Function = cascadeLookup(name, bundle.funcNs, globalBundle.funcNs)
implicit def convFlag(f: FlagContext): Flag = Flag(f.FLAG().getText)
implicit def convFlagList(a: FlagListContext): Seq[Flag] = a.flag().map(convFlag)
implicit def convFlagList(a: FlagListContext): Seq[Flag] = a.flag().asScala.map(convFlag)
// Resolve global entities from special structures.
implicit def resTypeList(a: TypeListContext): Seq[Type] = a.`type`.map(resTy)
implicit def resFuncSigList(a: FuncSigListContext): Seq[FuncSig] = a.funcSig().map(resSig)
implicit def resTypeList(a: TypeListContext): Seq[Type] = a.`type`.asScala.map(resTy)
implicit def resFuncSigList(a: FuncSigListContext): Seq[FuncSig] = a.funcSig().asScala.map(resSig)
// Resolve special structures
......@@ -189,8 +189,8 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
case t: TypeDoubleContext => TypeDouble()
case t: TypeUPtrContext => TypeUPtr(null).later(phase1) { _.ty = t.ty }
case t: TypeUFuncPtrContext => TypeUFuncPtr(null).later(phase1) { _.sig = t.funcSig }
case t: TypeStructContext => TypeStruct(null).later(phase1) { _.fieldTys = t.fieldTys.map(resTy) }
case t: TypeHybridContext => TypeHybrid(null, null).later(phase1) { tt => tt.fieldTys = t.fieldTys.map(resTy); tt.varTy = t.varTy }
case t: TypeStructContext => TypeStruct(null).later(phase1) { _.fieldTys = t.fieldTys.asScala.map(resTy) }
case t: TypeHybridContext => TypeHybrid(null, null).later(phase1) { tt => tt.fieldTys = t.fieldTys.asScala.map(resTy); tt.varTy = t.varTy }
case t: TypeArrayContext => TypeArray(null, t.length.longValue()).later(phase1) { _.elemTy = t.ty }
case t: TypeVectorContext => TypeVector(null, t.length.longValue()).later(phase1) { _.elemTy = t.ty }
case t: TypeVoidContext => TypeVoid()
......@@ -209,14 +209,14 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
def mkSig(fsc: FuncSigConstructorContext): FuncSig = {
val sig = FuncSig(null, null).later(phase1) { sig =>
sig.retTys = for (t <- fsc.retTys) yield resTy(t)
sig.paramTys = for (t <- fsc.paramTys) yield resTy(t)
sig.retTys = for (t <- fsc.retTys.asScala) yield resTy(t)
sig.paramTys = for (t <- fsc.paramTys.asScala) yield resTy(t)
}
return sig
}
logger.debug("Reading types and sigs...")
ir.topLevelDef.map(_.getChild(0)).foreach {
ir.topLevelDef.asScala.map(_.getChild(0)).foreach {
case td: TypeDefContext => {
val ty = mkType(td.typeConstructor)
val name = td.nam
......@@ -246,7 +246,7 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
case cc: CtorFloatContext => ConstFloat(t, cc.floatLiteral)
case cc: CtorDoubleContext => ConstDouble(t, cc.doubleLiteral)
case cc: CtorListContext => ConstSeq(t, null).later(phase2) {
_.elems = for (gn <- cc.globalVar()) yield resGlobalVar(gn)
_.elems = for (gn <- cc.globalVar().asScala) yield resGlobalVar(gn)
}
case _: CtorNullContext => ConstNull(t)
case cc: CtorExternContext => ConstExtern(t, cc.symbol)
......@@ -287,7 +287,7 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
logger.debug("Reading consts, globals, funcdefs, funcdecls and expfuncs...")
val funcDefs = new ArrayBuffer[(Function, FuncDefContext)]
ir.topLevelDef().map(_.getChild(0)).foreach {
ir.topLevelDef().iterator.asScala.map(_.getChild(0)).foreach {
case cdctx: ConstDefContext => {
val ty = resTy(cdctx.ty)
val con = mkConst(ty, cdctx.constConstructor)
......@@ -385,7 +385,7 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
param
}
bb.norParams = label.bbParam.map { p =>
bb.norParams = label.bbParam.asScala.map { p =>
val param = mkNorParam(p.`type`(), p.name())
val sourceInfo = toSourceInfo(p)
addLocalVar(param, sourceInfo)
......@@ -418,9 +418,9 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
}
}
implicit def resArgList(a: ArgListContext): Seq[SSAVariable] = a.value.map(resVar)
implicit def resArgList(a: ArgListContext): Seq[SSAVariable] = a.value.asScala.map(resVar)
implicit def resKA(ka: KeepaliveClauseContext): Seq[LocalVariable] = ka.value.map(resLocalVar)
implicit def resKA(ka: KeepaliveClauseContext): Seq[LocalVariable] = ka.value.asScala.map(resLocalVar)
def resFuncCallBody(fcb: FuncCallBodyContext): (FuncSig, SSAVariable, Seq[SSAVariable]) =
(fcb.funcSig, fcb.callee, fcb.argList)
......@@ -463,7 +463,7 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
return 0
}
var status = 0
val texts = flagList.flag().map(_.getText)
val texts = flagList.flag().asScala.map(_.getText)
val ordered = Seq("#N", "#Z", "#C", "#V").filter(t => texts.contains(t))
if(ordered != texts ) {
......@@ -515,7 +515,7 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
case ii: InstSwitchContext =>
InstSwitch(ii.`type`, null, null, null).later(phase4) { i =>
i.opnd = ii.opnd; i.defDest = ii.defDest
i.cases = (for ((v, d) <- ii.caseVal.zip(ii.caseDest)) yield (resConst(v), resDestClause(d))).to[ArrayBuffer]
i.cases = (for ((v, d) <- (ii.caseVal.asScala zip ii.caseDest.asScala)) yield (resConst(v), resDestClause(d))).to[ArrayBuffer]
}
case ii: InstCallContext =>
InstCall(null, null, null, null, null).later(phase4) { i =>
......@@ -528,7 +528,7 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
}
case ii: InstRetContext =>
InstRet(ver, null).later(phase4) { i =>
i.retVals = ii.retVals.vals.map(resVar)
i.retVals = ii.retVals.vals.asScala.map(resVar)
}
case ii: InstThrowContext =>
InstThrow(null).later(phase4) { i =>
......@@ -663,7 +663,7 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
val instRess: ArrayBuffer[InstResult] = Option(instDef.instResults) match {
case None => ArrayBuffer()
case Some(r) => (for ((instResDef, index) <- r.results.zipWithIndex) yield {
case Some(r) => (for ((instResDef, index) <- r.results.asScala.zipWithIndex) yield {
val resName = globalize(instResDef.getText, bbName)
val instRes = InstResult(inst, index)
......@@ -681,12 +681,12 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
return inst
}
bb.insts = bbCtx.inst.map(i => mkInst(bb, i)).to[ArrayBuffer]
bb.insts = bbCtx.inst.asScala.map(i => mkInst(bb, i)).to[ArrayBuffer]
return bb
}
val bbs = fDefCtx.funcBody.basicBlock().map(makeBB).to[ArrayBuffer]
val bbs = fDefCtx.funcBody.basicBlock().asScala.map(makeBB).to[ArrayBuffer]
ver.bbs = bbs
......
......@@ -65,6 +65,8 @@ class MicroVM private (val vmConf: VMConf, val allArgs: Option[Seq[String]]) ext
val stats = new VMStats()
val staticAnalyzer = new StaticAnalyzer()
val globalBundle = new GlobalBundle()
val constantPool = new ConstantPool()
......@@ -76,7 +78,7 @@ class MicroVM private (val vmConf: VMConf, val allArgs: Option[Seq[String]]) ext
// BYTES, BYTES_R, REFS, REFS_R: Types for the @uvm.meta.* common instructions.
import InternalTypes._
import staticAnalyzer.predefinedEntities._
for (ty <- Seq(VOID, BYTE, BYTE_ARRAY, BYTES, BYTES_R, REFS, REFS_R)) {
globalBundle.typeNs.add(ty)
}
......@@ -93,6 +95,21 @@ class MicroVM private (val vmConf: VMConf, val allArgs: Option[Seq[String]]) ext
for (ty <- Seq(C_INT, C_CHAR, C_CHARP, C_CHARPP)) {
globalBundle.typeNs.add(ty)
}
// Perform type inference on all preloaded s
staticAnalyzer.typeInferer.inferBundle(globalBundle)
}
/**
* A hack that allows general reference types to be accessed by pointers.
* <p>
* By default (true), memory locations of general reference types can only be accessed via iref.
* This enforcement can be disabled as a workaround for the current mu-client-pypy project.
*/
val enforceRefTypeNoPointerAccess = !vmConf.uPtrHack
if (!enforceRefTypeNoPointerAccess) {
MicroVM.logger.warn("Allowing memory locations of general reference types to be accessed by uptr.")
}
val memoryManager = new MemoryManager(vmConf)
......@@ -114,7 +131,6 @@ class MicroVM private (val vmConf: VMConf, val allArgs: Option[Seq[String]]) ext
val irBuilderRegistry = new IDObjectKeeper[IRBuilder]("IR builder")
val irReader = new UIRTextReader(idFactory, recordSourceInfo = vmConf.sourceInfo)
val hailScriptLoader = new HailScriptLoader(recordSourceInfo = vmConf.sourceInfo)
val staticAnalyzer = new StaticAnalyzer()
val bootImageBuilder = new BootImageBuilder()
......@@ -139,13 +155,16 @@ class MicroVM private (val vmConf: VMConf, val allArgs: Option[Seq[String]]) ext
* Add things from a bundle to the Micro VM.
*/
def addBundle(bundle: TrantientBundle) {
// Make sure all SSA variables have undergone type inference
staticAnalyzer.typeInferer.inferBundle(bundle)
if (vmConf.dumpBundle) {
val dbs = new DebugBundleSerializer(bundle)
dbs.writeUIR(new OutputStreamWriter(System.err))
}
if (vmConf.staticCheck) {
staticAnalyzer.checkBundle(bundle, Some(globalBundle))
staticAnalyzer.bundleChecker.checkBundle(bundle, Some(globalBundle))
}
globalBundle.merge(bundle);
......
This diff is collapsed.
......@@ -8,13 +8,15 @@ package uvm.refimpl
import scala.collection.mutable.ArrayBuffer
import uvm.refimpl.mem.TypeSizes._
import org.slf4j.LoggerFactory
import ch.qos.logback.classic.joran.JoranConfigurator
import ch.qos.logback.classic.LoggerContext
class VMOption[+T](
val name: String,
val desc: String,
val parser: String => T,
val default: T
) {
val default: T) {
def maybeParse(maybeStr: Option[String]): T = {
maybeStr.map(parser).getOrElse(default)
}
......@@ -30,19 +32,19 @@ object VMConfParser {
case 'M' => Some(1024L * 1024L)
case 'G' => Some(1024L * 1024L * 1024L)
case 'T' => Some(1024L * 1024L * 1024L * 1024L)
case _ => None
case _ => None
}
multiplier match {
case Some(m) => str.init.toLong * m
case None => str.toLong
}
case None => str.toLong
}
}
def parseBoolean(str: String): Boolean = {
str.toLowerCase().toBoolean
}
def parseColonSeparatedList(str: String): Seq[String] = {
str.split(":")
}
......@@ -50,131 +52,155 @@ object VMConfParser {
def parseMaybeString(str: String): Option[String] = {
Some(str)
}
val options = new ArrayBuffer[VMOption[Any]]
def opt[T](
name: String,
desc: String,
parser: String => T,
default: T
): VMOption[T] = {
default: T): VMOption[T] = {
val option = new VMOption[T](name, desc, parser, default)
options += option
option
}
val sosSize = opt[Long](
name = "sosSize",
desc = """The size of the small object space in bytes. May have suffix K, M, G or T. 1K = 1024B""",
parser = sizeWithSuffix,
default = VMConf.DEFAULT_CONF.sosSize)
name = "sosSize",
desc = """The size of the small object space in bytes. May have suffix K, M, G or T. 1K = 1024B""",
parser = sizeWithSuffix,
default = VMConf.DEFAULT_CONF.sosSize)
val losSize = opt[Long](
name = "losSize",
desc = """The size of the large object space in bytes. May have suffix K, M, G or T. 1K = 1024B""",
parser = sizeWithSuffix,
default = VMConf.DEFAULT_CONF.losSize)
name = "losSize",
desc = """The size of the large object space in bytes. May have suffix K, M, G or T. 1K = 1024B""",
parser = sizeWithSuffix,
default = VMConf.DEFAULT_CONF.losSize)
val globalSize = opt[Long](
name = "globalSize",
desc = """The size of the large object space in bytes. May have suffix K, M, G or T. 1K = 1024B""",
parser = sizeWithSuffix,
default = VMConf.DEFAULT_CONF.globalSize)
name = "globalSize",
desc = """The size of the large object space in bytes. May have suffix K, M, G or T. 1K = 1024B""",
parser = sizeWithSuffix,
default = VMConf.DEFAULT_CONF.globalSize)
val stackSize = opt[Long](
name = "stackSize",
desc = """The size of each stack in bytes. May have suffix K, M, G or T. 1K = 1024B""",
parser = sizeWithSuffix,
default = VMConf.DEFAULT_CONF.stackSize)
name = "stackSize",
desc = """The size of each stack in bytes. May have suffix K, M, G or T. 1K = 1024B""",
parser = sizeWithSuffix,
default = VMConf.DEFAULT_CONF.stackSize)
val dumpBundle = opt[Boolean](
name = "dumpBundle",
desc = """Dump the bundle when a bundle is loaded.""",
parser = parseBoolean,
default = VMConf.DEFAULT_CONF.dumpBundle)
name = "dumpBundle",
desc = """Dump the bundle when a bundle is loaded.""",
parser = parseBoolean,
default = VMConf.DEFAULT_CONF.dumpBundle)
val staticCheck = opt[Boolean](
name = "staticCheck",
desc = """Run static checker after each bundle is loaded.""",
parser = parseBoolean,
default = VMConf.DEFAULT_CONF.staticCheck)
name = "staticCheck",
desc = """Run static checker after each bundle is loaded.""",
parser = parseBoolean,
default = VMConf.DEFAULT_CONF.staticCheck)
val sourceInfo = opt[Boolean](
name = "sourceInfo",
desc = """Provide line/column info in Mu IR when errors occur. May significantly slow down parsing!!!""",
parser = parseBoolean,
default = VMConf.DEFAULT_CONF.sourceInfo)
name = "sourceInfo",
desc = """Provide line/column info in Mu IR when errors occur. May significantly slow down parsing!!!""",
parser = parseBoolean,
default = VMConf.DEFAULT_CONF.sourceInfo)
val automagicReloc = opt[Boolean](
name = "automagicReloc",
desc = """'Automagic' relocation. Affects boot image building, but not loading.""",
parser = parseBoolean,
default = VMConf.DEFAULT_CONF.automagicReloc)
name = "automagicReloc",
desc = """'Automagic' relocation. Affects boot image building, but not loading.""",
parser = parseBoolean,
default = VMConf.DEFAULT_CONF.automagicReloc)
val extraLibs = opt[Seq[String]](
name = "extraLibs",
desc = """Extra libraries to load when starting the micro VM. This is a colon-separated list of libraries.
name = "extraLibs",
desc = """Extra libraries to load when starting the micro VM. This is a colon-separated list of libraries.
Each is passed to the dlsym function.""",
parser = parseColonSeparatedList,
default = VMConf.DEFAULT_CONF.extraLibs)
parser = parseColonSeparatedList,
default = VMConf.DEFAULT_CONF.extraLibs)
val bootImg = opt[Option[String]](
name = "bootImg",
desc = """The path to the boot image.""",
parser = parseMaybeString,
default = VMConf.DEFAULT_CONF.bootImg)
name = "bootImg",
desc = """The path to the boot image.""",
parser = parseMaybeString,
default = VMConf.DEFAULT_CONF.bootImg)
val logbackConfig = opt[String](
name = "logbackConfig",
desc = """The logback XML configuration file""",
parser = identity,
default = "")
val vmLog = opt[String](
name = "vmLog",
desc = """The log level of the micro VM. Can be ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF""",
parser = identity,
default = "WARN")
name = "vmLog",
desc = """The log level of the micro VM. Can be ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF""",
parser = identity,
default = "WARN")
val gcLog = opt[String](
name = "gcLog",
desc = """The log level of the garbage collector. Can be ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF""",
parser = identity,
default = "ERROR")
name = "gcLog",
desc = """The log level of the garbage collector. Can be ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF""",
parser = identity,
default = "ERROR")
val uPtrHack = opt[Boolean](
name = "uPtrHack",
desc = """Allow memory locations of general reference types to be accessed by uptr""",
parser = parseBoolean,
default = false)
}
object VMConf {
val DEFAULT_CONF = new VMConf()
val ReComment = """^\s*#.*$""".r
val ReBlank = """^\s*$""".r
val ReConf = """^\s*(\w+)=(\S+)\s*$""".r
def apply(confStr: String): VMConf = {
val kvs = confStr.lines map {
case ReComment() => None
case ReBlank() => None
val kvs = confStr.lines.map {
case ReComment() => None
case ReBlank() => None
case ReConf(key, value) => Some((key, value))
} flatten
}.flatten
val map = kvs.toMap
apply(map)
}
def apply(kvMap: Map[String, String]): VMConf = {
kvMap.get("vmLog") foreach { value => setLog("uvm", value) }
kvMap.get("gcLog") foreach { value => setLog("uvm.refimpl.mem", value) }
configureLog(kvMap)
new VMConf(
sosSize = VMConfParser.sosSize(kvMap),
losSize = VMConfParser.losSize(kvMap),
globalSize = VMConfParser.globalSize(kvMap),
stackSize = VMConfParser.stackSize(kvMap),
dumpBundle = VMConfParser.dumpBundle(kvMap),
staticCheck = VMConfParser.staticCheck(kvMap),
sourceInfo = VMConfParser.sourceInfo(kvMap),
automagicReloc = VMConfParser.automagicReloc(kvMap),
extraLibs = VMConfParser.extraLibs(kvMap),
bootImg = VMConfParser.bootImg(kvMap)
)
sosSize = VMConfParser.sosSize(kvMap),
losSize = VMConfParser.losSize(kvMap),
globalSize = VMConfParser.globalSize(kvMap),
stackSize = VMConfParser.stackSize(kvMap),
dumpBundle = VMConfParser.dumpBundle(kvMap),
staticCheck = VMConfParser.staticCheck(kvMap),
sourceInfo = VMConfParser.sourceInfo(kvMap),
automagicReloc = VMConfParser.automagicReloc(kvMap),
extraLibs = VMConfParser.extraLibs(kvMap),
bootImg = VMConfParser.bootImg(kvMap),
uPtrHack = VMConfParser.uPtrHack(kvMap))
}
def configureLog(kvMap: Map[String, String]): Unit = {
kvMap.get("logbackConfig") foreach { filename =>
val context = LoggerFactory.getILoggerFactory().asInstanceOf[LoggerContext]
context.reset()
val configurator = new JoranConfigurator();
configurator.setContext(context);
configurator.doConfigure(filename);
}
kvMap.get("vmLog") foreach { value => setLog("uvm", value) }
kvMap.get("gcLog") foreach { value => setLog("uvm.refimpl.mem", value) }
}
def setLog(name: String, levelStr: String): Unit = {
import ch.qos.logback.classic.{ Level, Logger => LLogger }
import ch.qos.logback.classic.Level._
......@@ -196,5 +222,6 @@ class VMConf(
val sourceInfo: Boolean = false,
val automagicReloc: Boolean = false,
val extraLibs: Seq[String] = Seq(),
val bootImg: Option[String] = None)
val bootImg: Option[String] = None,
val uPtrHack: Boolean = false)
......@@ -14,27 +14,26 @@ import java.util.zip.ZipFile
import scala.collection.Map
import scala.collection.mutable.HashMap
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import uvm.{ MuID, MuName }
import uvm.refimpl.{ Word, WORD_SIZE_BYTES }
import uvm.refimpl.{ WORD_SIZE_BYTES, Word }
import uvm.refimpl.MicroVM
import uvm.refimpl.cmdline.NativeArgv
import uvm.refimpl.itpr.BoxInt
import uvm.refimpl.itpr.BoxPointer
import uvm.refimpl.itpr.HowToResume
import uvm.refimpl.itpr.OpHelper
import uvm.refimpl.mem.HeaderUtils
import uvm.refimpl.mem.TypeSizes
import uvm.refimpl.nat.NativeSupport
import uvm.types.TypeHybrid
import uvm.utils.IOHelpers
import uvm.utils.IOHelpers.forEachLine
import uvm.utils.MappedIDFactory
import uvm.utils.WithUtils.tryWithResource
import scala.collection.mutable.ArrayBuffer
import uvm.refimpl.itpr.HowToResume
import uvm.refimpl.cmdline.NativeArgv
import uvm.refimpl.itpr.BoxInt
import uvm.refimpl.InternalTypePool
import uvm.refimpl.InternalTypes
import uvm.refimpl.itpr.BoxPointer
import uvm.utils.IOHelpers
import com.typesafe.scalalogging.Logger
import org.slf4j.LoggerFactory
import uvm.refimpl.mem.HeaderUtils
object BootImageLoader {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
......@@ -44,8 +43,8 @@ object BootImageLoader {
}
class BootImageLoader(file: String, maybeAllArgs: Option[Seq[String]])(implicit microVM: MicroVM) extends AutoCloseable {
import BootImageLoader._
import BootImageFile._
import BootImageLoader._
private val globalBundle = microVM.globalBundle
private val memoryManager = microVM.memoryManager
......
......@@ -39,7 +39,7 @@ class TransitiveClosure[T](initialElems: Seq[T]) {
}
}
def +=(elem: T): TransitiveClosure[T] = { maybeEnqueue(elem); this }
def ++=(elems: Seq[T]): TransitiveClosure[T] = { elems.foreach(this +=); this }
def ++=(elems: Seq[T]): TransitiveClosure[T] = { elems.foreach(e => this += e); this }
}
object TransitiveClosureBuilder {
......@@ -381,7 +381,7 @@ class TransitiveClosureBuilder(initialSet: Seq[TopLevel], val primordial: Primor
}
override def visitFuncRefField(objRef: Word, iRef: Word, toFunc: Option[Function]): Unit = {
toFunc.foreach(tls+=)
toFunc.foreach(f => tls += f)
}
override def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = {
......
......@@ -11,7 +11,7 @@ class NativeArgv(args: Seq[String]) extends AutoCloseable {
for ((arg, i) <- (args).zipWithIndex) {
argvOffs(i) = argvSB.length
argvSB ++= arg += '\0'
argvSB ++= arg += '\u0000'
}
val cArgvMem = NativeSupport.allocateManual(argvOffs.length * WORD_SIZE_BYTES.toInt)
......
package uvm.refimpl.cmdline
import java.io.BufferedReader
import java.io.InputStreamReader
import java.nio.charset.StandardCharsets
import java.util.zip.ZipFile
import scala.collection.mutable.HashMap
import uvm.{MuID, MuName}
import uvm.refimpl.HowToResume.PassValues
import uvm.refimpl.InternalTypes
import uvm.refimpl.MicroVM
import uvm.refimpl.UvmRuntimeException
import uvm.refimpl.VMConf
import uvm.refimpl.WORD_SIZE_BYTES
import uvm.refimpl.nat.NativeSupport
import uvm.utils.WithUtils.tryWithResource
/** Run Mu from the command line. */
......
......@@ -2,12 +2,10 @@ package uvm.refimpl.hail
import java.io.Reader
import scala.collection.JavaConversions._
import scala.collection.JavaConverters._
import scala.collection.mutable.HashMap
import org.antlr.v4.runtime.ANTLRInputStream
import org.antlr.v4.runtime.CommonTokenStream
import org.antlr.v4.runtime.ParserRuleContext
import org.antlr.v4.runtime._
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
......@@ -40,7 +38,7 @@ class HailScriptLoader(recordSourceInfo: Boolean = true)(implicit microVM: Micro
}
def loadHail(hailScript: String): Unit = {
val ais = new ANTLRInputStream(hailScript)
val ais = CharStreams.fromString(hailScript)
val ea = new AccumulativeAntlrErrorListener(hailScript)
val lexer = new HAILLexer(ais)
......@@ -69,6 +67,8 @@ class HailScriptLoader(recordSourceInfo: Boolean = true)(implicit microVM: Micro
class InstanceHailScriptLoader(microVM: MicroVM, memorySupport: MemorySupport, mc: MuCtx, source: String,
val recordSourceInfo: Boolean) extends AdvancedAntlrHelper {
import HailScriptLoader._
private val predefinedEntities = microVM.staticAnalyzer.predefinedEntities
val sourceLines = source.lines.toIndexedSeq
......@@ -76,7 +76,7 @@ class InstanceHailScriptLoader(microVM: MicroVM, memorySupport: MemorySupport, m
val hailObjMap = new HailObjMap
def loadTopLevel(ast: HailContext): Unit = {
ast.topLevelDef.map(_.getChild(0)) foreach {
ast.topLevelDef.asScala.map(_.getChild(0)) foreach {
case tl: FixedAllocContext => {
val hailName = tl.nam.getText
......@@ -206,7 +206,7 @@ class InstanceHailScriptLoader(microVM: MicroVM, memorySupport: MemorySupport, m
var cur: LValue = base
for (ic <- lv.indices) {
for (ic <- lv.indices.iterator.asScala) {
val index = evalIntExpr(ic.intExpr()).toLong
val newCur = cur.indexInto(index, ic)
val oldCur = cur
......@@ -229,7 +229,7 @@ class InstanceHailScriptLoader(microVM: MicroVM, memorySupport: MemorySupport, m
def unexpectedGlobalTypeError(gv: GlobalVariable): Nothing = {
throw new UvmHailParsingException(inCtx(