WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit 559c72dc authored by Kunshan Wang's avatar Kunshan Wang
Browse files

Tested parser.

parent 3323a4b7
......@@ -2,8 +2,9 @@ package uvm
import uvm.types._
import uvm.ssavariables._
import scala.collection.mutable.HashMap
class Bundle {
abstract class Bundle {
/*
* There is a hierarchy of namespaces. A subnode is a subset of the parent.
*
......@@ -35,7 +36,30 @@ class Bundle {
val globalCellNs = globalVarNs.makeSubSpace[GlobalCell]()
val funcNs = globalVarNs.makeSubSpace[Function]()
val expFuncNs = globalVarNs.makeSubSpace[ExposedFunc]()
}
/**
* This kind of bundle is generated when parsing a .UIR file.
* <p>
* In this kind of bundle, a Function does not have a FuncVer as its version.
* The funcNs only contains new functions declared in this bundle, not existing
* functions declared previously. When this bundle is merged with the global bundle,
* both funcNs and funcVerNs are simply merged, and new FuncVer objects become the
* newest version of the Function, whether the Function is newly declared or not.
*/
class TrantientBundle extends Bundle {
/**
* All functions (declared here or previously) that are defined in this bundle.
* <p>
* Mainly for debugging purpose.
*/
//val defFuncNs = new SimpleNamespace[Function]
}
/**
* This kind of bundle holds the global state. Functions and versions are fully merged.
*/
class GlobalBundle extends Bundle {
private def simpleMerge[T <: Identified](oldNs: Namespace[T], newNs: Namespace[T]) {
for (cand <- newNs.all) {
try {
......@@ -49,7 +73,13 @@ class Bundle {
}
}
def merge(newBundle: Bundle) {
private def redefineFunctions(newNs: Namespace[FuncVer]) {
for (fv <- newNs.all) {
fv.func.versions = fv :: fv.func.versions
}
}
def merge(newBundle: TrantientBundle) {
// Only merge leaves
simpleMerge(typeNs, newBundle.typeNs)
simpleMerge(funcSigNs, newBundle.funcSigNs)
......@@ -58,5 +88,8 @@ class Bundle {
simpleMerge(globalCellNs, newBundle.globalCellNs)
simpleMerge(funcNs, newBundle.funcNs)
simpleMerge(expFuncNs, newBundle.expFuncNs)
redefineFunctions(newBundle.funcVerNs)
}
}
\ No newline at end of file
......@@ -18,12 +18,12 @@ class UIRTextReader(val idFactory: IDFactory) {
import UIRTextReader._
import uvm.ir.textinput.Later.Laterable
def read(ir: String, globalBundle: Bundle): Bundle = {
def read(ir: String, globalBundle: GlobalBundle): TrantientBundle = {
val input = new ANTLRInputStream(ir)
read(ir, input, globalBundle)
}
def read(ir: java.io.Reader, globalBundle: Bundle): Bundle = {
def read(ir: java.io.Reader, globalBundle: GlobalBundle): TrantientBundle = {
val sb = new StringBuilder()
val cb = new Array[Char](4096)
......@@ -57,7 +57,7 @@ class UIRTextReader(val idFactory: IDFactory) {
def getMessages(): String = buf.mkString("\n")
}
def read(source: String, ais: ANTLRInputStream, globalBundle: Bundle): Bundle = {
def read(source: String, ais: ANTLRInputStream, globalBundle: GlobalBundle): TrantientBundle = {
val ea = new AccumulativeAntlrErrorListener(source)
val lexer = new UIRLexer(ais)
......@@ -144,8 +144,8 @@ class UIRTextReader(val idFactory: IDFactory) {
case e: Exception => throw new TextIRParsingException(inCtx(ctx, s), e)
}
def read(ir: IrContext, globalBundle: Bundle): Bundle = {
val bundle = new Bundle()
def read(ir: IrContext, globalBundle: GlobalBundle): TrantientBundle = {
val bundle = new TrantientBundle()
// Resolve global entities. (If any resXxxx is not present, that's because it is simply not currently used)
......@@ -364,6 +364,7 @@ class UIRTextReader(val idFactory: IDFactory) {
}
case fdef: FuncDefContext => {
val func = findOldFunc(fdef.nam).getOrElse(declFunc(fdef.nam, fdef.funcSig))
//bundle.defFuncNs.add(func)
funcDefs += ((func, fdef))
}
case edef: FuncExpDefContext => {
......@@ -385,7 +386,7 @@ class UIRTextReader(val idFactory: IDFactory) {
addFuncVer(ver)
ver.func = func
func.versions = ver :: func.versions
//func.versions = ver :: func.versions // Don't override here. Let the MicroVM redefine functions.
def globalizeBB(name: String): String = globalize(name, verName)
......
......@@ -153,7 +153,6 @@ case class KillOld() extends CurStackAction
abstract class NewStackAction
case class PassValue(var argTy: Type, var arg: SSAVariable) extends NewStackAction
case class PassVoid() extends NewStackAction
case class ThrowExc(var exc: SSAVariable) extends NewStackAction
/**
......
......@@ -717,6 +717,6 @@ class TextIRWriterTest extends FlatSpec with Matchers {
println(ir)
val muBundle = new UIRTextReader(new IDFactory).read(ir, new uvm.Bundle())
val muBundle = new UIRTextReader(new IDFactory).read(ir, new uvm.GlobalBundle())
}
}
\ No newline at end of file
......@@ -3,25 +3,25 @@ package uvm.ir.textinput
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import uvm.Bundle
import uvm.GlobalBundle
import uvm.TrantientBundle
class NicerErrorMessage extends FlatSpec with Matchers
with TestingBundlesValidators {
def parseFile(fileName: String, globalBundle: Bundle, fac: Option[IDFactory] = None): Bundle = {
def parseFile(fileName: String, globalBundle: GlobalBundle, fac: Option[IDFactory] = None): TrantientBundle = {
val idf = fac.getOrElse(new IDFactory())
val r = new UIRTextReader(idf)
val ir = r.read(new java.io.FileReader(fileName), globalBundle)
ir
}
val EMPTY_BUNDLE = new Bundle()
behavior of "UIRTextReader"
it should "give nice error messages" in {
try {
val b = parseFile("tests/uvm-parsing-test/bundle-with-error.uir", EMPTY_BUNDLE)
val gb = new GlobalBundle()
val b = parseFile("tests/uvm-parsing-test/bundle-with-error.uir", gb)
} catch {
case e: TextIRParsingException => // expected
e.printStackTrace()
......
......@@ -3,10 +3,9 @@ package uvm.ir.textinput
import org.scalatest._
import uvm._
import uvm.types._
import uvm.ssavariables._
import uvm.comminsts._
import UIRTextReader.globalize
import uvm.ssavariables._
import uvm.types._
trait TestingBundlesValidators extends Matchers with ExtraMatchers {
......@@ -35,7 +34,7 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
def inst(s: String) = d.localVarNs(UIRTextReader.globalize(s, d.name.get))
}
def validateTypes(bundle: Bundle) {
def validateTypes(bundle: GlobalBundle) {
val our = bundle
our ty "@i1" shouldBeATypeIntOf(1)
......@@ -149,7 +148,7 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
our anything "@sig0" shouldBe sig0
}
def validateConstants(bundle: Bundle) {
def validateConstants(bundle: GlobalBundle) {
val our = bundle
our const "@ci8" shouldBeAConstIntOf (8, 127)
......@@ -268,7 +267,7 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
our anything "@gi64" shouldBe gi64
}
def validateFunctions(bundle: Bundle) {
def validateFunctions(bundle: GlobalBundle) {
val our = bundle
our sig "@foo" shouldBeA[FuncSig] { its =>
......@@ -360,11 +359,15 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
f(func, ver)
}
def in(funcVer: FuncVer)(f: FuncVer => Unit) {
f(funcVer)
}
def in(b: BasicBlock)(f: BasicBlock => Unit) {
f(b)
}
def validateInstructions(bundle: Bundle) {
def validateInstructions(bundle: GlobalBundle) {
val our = bundle
in (our func "@intBinOpTest") { (func, the) =>
......@@ -725,9 +728,8 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
}
}
/*
in (our func "@aggregate") { (func, the) =>
val my = ver
in(the bb "%entry") { my =>
my inst "%e0" shouldBeA[InstExtractValue] { its =>
its.strTy shouldBe (our ty "@sid")
......@@ -756,14 +758,14 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
}
my inst "%ee0" shouldBeA[InstExtractElement] { its =>
its.vecTy shouldBe (our ty "@4xfloat")
its.seqTy shouldBe (our ty "@4xfloat")
its.indTy shouldBe (our ty "@i32")
its.opnd shouldBe (our value "@v1")
its.index shouldBe (our value "@I32_0")
}
my inst "%ie0" shouldBeA[InstInsertElement] { its =>
its.vecTy shouldBe (our ty "@4xfloat")
its.seqTy shouldBe (our ty "@4xfloat")
its.indTy shouldBe (our ty "@i32")
its.opnd shouldBe (our value "@v1")
its.index shouldBe (our value "@I32_1")
......@@ -778,9 +780,10 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
its.mask shouldBe (our value "@vshf")
}
}
}
in (our func "@memops") { (func, the) =>
val my = ver
in(the bb "%entry") { my =>
my inst "%new" shouldBeA[InstNew] { its =>
its.allocTy shouldBe (our ty "@i64")
......@@ -808,27 +811,43 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
my inst "%new_s" shouldBeA[InstNew] { its =>
its.allocTy shouldBe (our ty "@i64")
its.excClause shouldBe Some(ExcClause((my bb "%bb2"), (my bb "%handler")))
its.excClause shouldBe Some(ExcClause(
DestClause(the bb "%bb2", Seq("%alloca", "%allocahybrid", "%p0", "%p1").map(my.value)),
DestClause(the bb "%handler", Seq())))
}
}
in(the bb "%bb2") { my =>
my inst "%newhybrid_s" shouldBeA[InstNewHybrid] { its =>
its.allocTy shouldBe (our ty "@hic")
its.lenTy shouldBe (our ty "@i64")
its.length shouldBe (my param "%p0")
its.excClause shouldBe Some(ExcClause((my bb "%bb3"), (my bb "%handler")))
its.excClause shouldBe Some(ExcClause(
DestClause(the bb "%bb3", Seq("%alloca", "%allocahybrid", "%p0", "%p1").map(my.value)),
DestClause(the bb "%handler", Seq())))
}
}
in(the bb "%bb3") { my =>
my inst "%alloca_s" shouldBeA[InstAlloca] { its =>
its.allocTy shouldBe (our ty "@i64")
its.excClause shouldBe Some(ExcClause((my bb "%bb4"), (my bb "%handler")))
its.excClause shouldBe Some(ExcClause(
DestClause(the bb "%bb4", Seq("%alloca", "%allocahybrid", "%p0", "%p1").map(my.value)),
DestClause(the bb "%handler", Seq())))
}
}
in(the bb "%bb4") { my =>
my inst "%allocahybrid_s" shouldBeA[InstAllocaHybrid] { its =>
its.allocTy shouldBe (our ty "@hic")
its.lenTy shouldBe (our ty "@i64")
its.length shouldBe (my param "%p0")
its.excClause shouldBe Some(ExcClause((my bb "%bb5"), (my bb "%handler")))
its.excClause shouldBe Some(ExcClause(
DestClause(the bb "%bb5", Seq("%alloca", "%allocahybrid", "%p1").map(my.value)),
DestClause(the bb "%handler", Seq())))
}
}
in(the bb "%bb5") { my =>
my inst "%new2" shouldBeA[InstNew] { its =>
its.allocTy shouldBe (our ty "@sid")
......@@ -923,8 +942,12 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
its.ord shouldBe MemoryOrder.NOT_ATOMIC
its.referentTy shouldBe (our ty "@i64")
its.loc shouldBe (my inst "%alloca")
its.excClause shouldBe Some(ExcClause((my bb "%bb6"), (my bb "%handler")))
its.excClause shouldBe Some(ExcClause(
DestClause(the bb "%bb6", Seq(my value "%alloca")),
DestClause(the bb "%handler", Seq())))
}
}
in(the bb "%bb6") { my =>
my inst "%store_s" shouldBeA[InstStore] { its =>
its.ptr shouldBe false
......@@ -932,8 +955,12 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
its.referentTy shouldBe (our ty "@i64")
its.loc shouldBe (my inst "%alloca")
its.newVal shouldBe (our const "@I64_42")
its.excClause shouldBe Some(ExcClause((my bb "%bb7"), (my bb "%handler")))
its.excClause shouldBe Some(ExcClause(
DestClause(the bb "%bb7", Seq(my value "%alloca" )),
DestClause(the bb "%handler", Seq())))
}
}
in(the bb "%bb7") { my =>
my inst "%cmpxchg_s" shouldBeA[InstCmpXchg] { its =>
its.ptr shouldBe false
......@@ -943,8 +970,12 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
its.loc shouldBe (my inst "%alloca")
its.expected shouldBe (our const "@I64_42")
its.desired shouldBe (our const "@I64_0")
its.excClause shouldBe Some(ExcClause((my bb "%bb8"), (my bb "%handler")))
its.excClause shouldBe Some(ExcClause(
DestClause(the bb "%bb8", Seq(my value "%alloca")),
DestClause(the bb "%handler", Seq())))
}
}
in(the bb "%bb8") { my =>
my inst "%atomicrmw_s" shouldBeA[InstAtomicRMW] { its =>
its.ptr shouldBe false
......@@ -953,16 +984,21 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
its.referentTy shouldBe (our ty "@i64")
its.loc shouldBe (my inst "%alloca")
its.opnd shouldBe (our const "@I64_43")
its.excClause shouldBe Some(ExcClause((my bb "%bb9"), (my bb "%handler")))
its.excClause shouldBe Some(ExcClause(
DestClause(the bb "%bb9", Seq()),
DestClause(the bb "%handler", Seq())))
}
}
in(the bb "%bb9") { my =>
my inst "%fence" shouldBeA[InstFence] { its =>
its.ord shouldBe (MemoryOrder.SEQ_CST)
}
}
}
in (our func "@memops_ptr") { (func, the) =>
val my = ver
in(the bb "%entry") { my =>
my inst "%p" shouldBeA[InstCommInst] { _.argList(0) shouldBe (my inst "%new")}
......@@ -1038,11 +1074,11 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
its.opnd shouldBe (our const "@I64_43")
its.excClause shouldBe None
}
}
}
in (our func "@memorder") { (func, the) =>
val my = ver
in(the bb "%entry") { my =>
my inst "%l0" shouldBeA[InstLoad] { _.ord shouldBe MemoryOrder.NOT_ATOMIC }
my inst "%l1" shouldBeA[InstLoad] { _.ord shouldBe MemoryOrder.RELAXED }
......@@ -1055,9 +1091,10 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
}
my inst "%l6" shouldBeA[InstLoad] { _.ord shouldBe MemoryOrder.SEQ_CST }
}
}
in (our func "@atomicrmwops") { (func, the) =>
val my = ver
in(the bb "%entry") { my =>
my inst "%old0" shouldBeA[InstAtomicRMW] { _.op shouldBe AtomicRMWOptr.XCHG }
my inst "%old1" shouldBeA[InstAtomicRMW] { _.op shouldBe AtomicRMWOptr.ADD }
......@@ -1071,9 +1108,10 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
my inst "%old9" shouldBeA[InstAtomicRMW] { _.op shouldBe AtomicRMWOptr.UMAX }
my inst "%olda" shouldBeA[InstAtomicRMW] { _.op shouldBe AtomicRMWOptr.UMIN }
}
}
in (our func "@traps") { (func, the) =>
val my = ver
in(the bb "%entry") { my =>
my inst "%tp" shouldBeA[InstTrap] { its =>
its.retTy shouldBe (our ty "@i32")
......@@ -1083,31 +1121,38 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
my inst "%tp_s" shouldBeA[InstTrap] { its =>
its.retTy shouldBe (our ty "@i64")
its.excClause shouldBe Some(ExcClause(my bb "%tp_s_cont", my bb "%tp_s_exc"))
its.excClause shouldBe Some(ExcClause(
DestClause(the bb "%tp_s_cont", Seq("%a", "%b").map(my.value)),
DestClause(the bb "%tp_s_exc", Seq())))
its.keepAlives shouldBe Seq(my inst "%b")
}
}
in(the bb "%tp_s_cont") { my =>
my inst "%wp" shouldBeA[InstWatchPoint] { its =>
its.wpID shouldBe 1
its.retTy shouldBe (our ty "@float")
its.dis shouldBe (my bb "%wp_dis_cont")
its.ena shouldBe (my bb "%wp_ena_cont")
its.dis shouldBe DestClause(the bb "%wp_dis_cont", Seq("%b").map(my.value))
its.ena shouldBe DestClause(the bb "%wp_ena_cont", Seq())
its.exc shouldBe None
its.keepAlives shouldBe Seq(my inst "%a")
}
}
in(the bb "%wp_dis_cont") { my =>
my inst "%wp_s" shouldBeA[InstWatchPoint] { its =>
its.wpID shouldBe 2
its.retTy shouldBe (our ty "@double")
its.dis shouldBe (my bb "%wp_s_dis_cont")
its.ena shouldBe (my bb "%wp_s_ena_cont")
its.exc shouldBe Some(my bb "%wp_s_exc")
its.dis shouldBe DestClause(the bb "%wp_s_dis_cont", Seq())
its.ena shouldBe DestClause(the bb "%wp_s_ena_cont", Seq())
its.exc shouldBe Some(DestClause(the bb "%wp_s_exc", Seq()))
its.keepAlives shouldBe Seq(my inst "%b")
}
}
}
in (our func "@ccall") { (func, the) =>
val my = ver
in(the bb "%entry") { my =>
my inst "%rv" shouldBeA[InstCCall] { its =>
its.callConv shouldBe Flag("#DEFAULT")
......@@ -1117,9 +1162,10 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
its.argList shouldBe Seq(our value "@D_1")
}
}
}
in (our func "@gen") { (func, the) =>
val my = ver
in(the bb "%entry") { my =>
my inst "%ss1" shouldBeA[InstSwapStack] { its =>
its.swappee shouldBe (my value "%main")
......@@ -1136,9 +1182,10 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
its.keepAlives shouldBe empty
}
}
}
in (our func "@swapstack") { (func, the) =>
val my = ver
in(the bb "%entry") { my =>
my inst "%curstack" shouldBeA[InstCommInst] { its =>
its.inst shouldBe (CommInsts("@uvm.current_stack"))
......@@ -1152,27 +1199,33 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
its.sig shouldBe (our sig "@iii_sig")
its.callee shouldBe (our value "@callee2")
its.argList shouldBe Seq(my value "%curstack")
its.excClause shouldBe Some(ExcClause(my bb "%cont", my bb "%exc"))
its.excClause shouldBe Some(ExcClause(
DestClause(the bb "%cont", Seq("%curstack", "%coro").map(my.value)),
DestClause(the bb "%exc", Seq())))
}
}
in(the bb "%cont") { my =>
my inst "%ss1" shouldBeA[InstSwapStack] { its =>
its.swappee shouldBe (my value "%coro")
its.curStackAction shouldBe RetWith(our ty "@i64")
its.newStackAction shouldBe PassVoid()
its.newStackAction shouldBe PassValue(our ty "@void", our const "@VOID")
its.excClause shouldBe None
its.keepAlives shouldBe Seq(my value "%curstack")
}
my inst "%ss2" shouldBeA[InstSwapStack] { its =>
its.swappee shouldBe (my value "%coro")
its.curStackAction shouldBe RetWith(our ty "@i64")
its.newStackAction shouldBe PassVoid()
its.excClause shouldBe Some(ExcClause(my bb "%nor", my bb "%exc"))
its.newStackAction shouldBe PassValue(our ty "@void", our const "@VOID")
its.excClause shouldBe Some(ExcClause(
DestClause(the bb "%nor", Seq()),
DestClause(the bb "%exc", Seq())))
its.keepAlives shouldBe empty
}
}
}
in (our func "@comminst") { (func, the) =>
val my = ver
in(the bb "%entry") { my =>
my inst "%thr" shouldBeA[InstCommInst] { its =>
its.inst shouldBe CommInsts("@uvm.new_thread")
......@@ -1205,59 +1258,60 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
}
}
}
}
def validateRedef(globalBundle: Bundle, bundle: Bundle) {
val ourOld = globalBundle
val ourNew = bundle
def validateRedef(globalBundle: GlobalBundle, b1: TrantientBundle, b2: TrantientBundle) {
val ourGlobal = globalBundle
val ourOld = b1
val ourNew = b2
in (ourOld func "@meaning_of_life") { (func, the) =>
val my = ver
in (ourGlobal func "@meaning_of_life") { (func, the) =>
in (the bb "%entry") { my =>
my inst "%ret" shouldBeA[InstRet] { its =>
its.retTy shouldBe (ourOld ty "@i64")
its.retVal shouldBe (ourOld const "@I64_42")
}
}
}
(ourOld func "@foxsay").versions shouldBe Nil
(ourOld func "@meaning_of_life").versions shouldBe Seq(ourOld funcVer "@meaning_of_life_v1")
(ourGlobal func "@foxsay").versions shouldBe Nil
(ourGlobal func "@meaning_of_life").versions shouldBe Seq(ourGlobal funcVer "@meaning_of_life.v1")
(ourNew func "@meaning_of_life").id shouldEqual (ourOld func "@meaning_of_life").id
(ourNew func "@foxsay").id shouldEqual (ourOld func "@foxsay").id
ourNew.funcNs.get("@foxsay") shouldBe None
ourNew.funcNs.get("@meaning_of_life") shouldBe None
in (ourNew func "@meaning_of_life") { (func, the) =>
val my = ver
(ourNew funcVer "@meaning_of_life.v2").func shouldBe (ourGlobal func "@meaning_of_life")
(ourNew funcVer "@foxsay.v1").func shouldEqual (ourGlobal func "@foxsay")
in (ourNew funcVer "@meaning_of_life.v2") { the =>
in (the bb "%entry") { my =>
my inst "%ret" shouldBeA[InstRet] { its =>
its.retTy shouldBe (ourOld ty "@i64")
its.retVal shouldBe (ourNew const "@I64_43")
}
}
}
(ourNew func "@foxsay").versions shouldBe Seq(ourNew funcVer "@foxsay_v1")
(ourNew func "@meaning_of_life").versions shouldBe Seq(ourNew funcVer "@meaning_of_life_v2")
in (ourNew func "@foxsay") { (func, the) =>
val my = ver
in (ourNew funcVer "@foxsay.v1") { the =>
in (the bb "%entry") { my =>
my inst "%ret" shouldBeA[InstRet] { its =>
its.retTy shouldBe (ourOld ty "@i64")
its.retVal shouldBe (ourNew const "@I64_99")
}
}
*/
}
}