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.

Commit 04c10e0b authored by qinsoon's avatar qinsoon
Browse files

fixed all tests. Now using a lock for MuName

parent b20cc1a4
...@@ -8,6 +8,7 @@ use utils::vec_utils; ...@@ -8,6 +8,7 @@ use utils::vec_utils;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
use std::default; use std::default;
use std::sync::RwLock;
use std::cell::Cell; use std::cell::Cell;
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
...@@ -55,8 +56,7 @@ pub fn new_internal_id() -> MuID { ...@@ -55,8 +56,7 @@ pub fn new_internal_id() -> MuID {
#[derive(Debug)] #[derive(Debug)]
pub struct MuFunction { pub struct MuFunction {
pub id: MuID, pub hdr: MuEntityHeader,
pub name: Option<MuName>,
pub sig: P<MuFuncSig>, pub sig: P<MuFuncSig>,
pub cur_ver: Option<MuID>, pub cur_ver: Option<MuID>,
...@@ -66,8 +66,7 @@ pub struct MuFunction { ...@@ -66,8 +66,7 @@ pub struct MuFunction {
impl MuFunction { impl MuFunction {
pub fn new(id: MuID, sig: P<MuFuncSig>) -> MuFunction { pub fn new(id: MuID, sig: P<MuFuncSig>) -> MuFunction {
MuFunction { MuFunction {
id: id, hdr: MuEntityHeader::unnamed(id),
name: None,
sig: sig, sig: sig,
cur_ver: None, cur_ver: None,
all_vers: vec![] all_vers: vec![]
...@@ -77,18 +76,13 @@ impl MuFunction { ...@@ -77,18 +76,13 @@ impl MuFunction {
impl fmt::Display for MuFunction { impl fmt::Display for MuFunction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.name.is_none() { write!(f, "Func {}", self.hdr)
write!(f, "Func #{}", self.id)
} else {
write!(f, "Func {}#{}", self.name.unwrap(), self.id)
}
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct MuFunctionVersion { pub struct MuFunctionVersion {
pub id: MuID, pub hdr: MuEntityHeader,
pub name: Option<MuName>,
pub func_id: MuID, pub func_id: MuID,
pub sig: P<MuFuncSig>, pub sig: P<MuFuncSig>,
...@@ -100,19 +94,14 @@ pub struct MuFunctionVersion { ...@@ -100,19 +94,14 @@ pub struct MuFunctionVersion {
impl fmt::Display for MuFunctionVersion { impl fmt::Display for MuFunctionVersion {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.name.is_none() { write!(f, "FuncVer {} of Func #{}", self.hdr, self.func_id)
write!(f, "FuncVer #{} of Func#{}", self.id, self.func_id)
} else {
write!(f, "FuncVer {}#{} of Func#{}", self.name.unwrap(), self.id, self.func_id)
}
} }
} }
impl MuFunctionVersion { impl MuFunctionVersion {
pub fn new(id: MuID, func: MuID, sig: P<MuFuncSig>) -> MuFunctionVersion { pub fn new(id: MuID, func: MuID, sig: P<MuFuncSig>) -> MuFunctionVersion {
MuFunctionVersion{ MuFunctionVersion{
id: id, hdr: MuEntityHeader::unnamed(id),
name: None,
func_id: func, func_id: func,
sig: sig, sig: sig,
content: None, content: None,
...@@ -129,12 +118,10 @@ impl MuFunctionVersion { ...@@ -129,12 +118,10 @@ impl MuFunctionVersion {
self.context.values.insert(id, SSAVarEntry{id: id, name: Some(tag), ty: ty.clone(), use_count: Cell::new(0), expr: None}); self.context.values.insert(id, SSAVarEntry{id: id, name: Some(tag), ty: ty.clone(), use_count: Cell::new(0), expr: None});
P(TreeNode { P(TreeNode {
id: id, hdr: MuEntityHeader::unnamed(id),
name: None,
op: pick_op_code_for_ssa(&ty), op: pick_op_code_for_ssa(&ty),
v: TreeNode_::Value(P(Value{ v: TreeNode_::Value(P(Value{
id: id, hdr: MuEntityHeader::named(id, tag),
name: Some(tag),
ty: ty, ty: ty,
v: Value_::SSAVar(id) v: Value_::SSAVar(id)
})) }))
...@@ -143,8 +130,7 @@ impl MuFunctionVersion { ...@@ -143,8 +130,7 @@ impl MuFunctionVersion {
pub fn new_constant(&mut self, id: MuID, v: P<Value>) -> P<TreeNode> { pub fn new_constant(&mut self, id: MuID, v: P<Value>) -> P<TreeNode> {
P(TreeNode{ P(TreeNode{
id: id, hdr: MuEntityHeader::unnamed(id),
name: None,
op: pick_op_code_for_value(&v.ty), op: pick_op_code_for_value(&v.ty),
v: TreeNode_::Value(v) v: TreeNode_::Value(v)
}) })
...@@ -152,8 +138,7 @@ impl MuFunctionVersion { ...@@ -152,8 +138,7 @@ impl MuFunctionVersion {
pub fn new_global(&mut self, id: MuID, v: P<Value>) -> P<TreeNode> { pub fn new_global(&mut self, id: MuID, v: P<Value>) -> P<TreeNode> {
P(TreeNode{ P(TreeNode{
id: id, hdr: MuEntityHeader::unnamed(id),
name: None,
op: pick_op_code_for_value(&v.ty), op: pick_op_code_for_value(&v.ty),
v: TreeNode_::Value(v) v: TreeNode_::Value(v)
}) })
...@@ -161,8 +146,7 @@ impl MuFunctionVersion { ...@@ -161,8 +146,7 @@ impl MuFunctionVersion {
pub fn new_inst(&mut self, id: MuID, v: Instruction) -> P<TreeNode> { pub fn new_inst(&mut self, id: MuID, v: Instruction) -> P<TreeNode> {
P(TreeNode{ P(TreeNode{
id: id, hdr: MuEntityHeader::unnamed(id),
name: None,
op: pick_op_code_for_inst(&v), op: pick_op_code_for_inst(&v),
v: TreeNode_::Instruction(v), v: TreeNode_::Instruction(v),
}) })
...@@ -243,15 +227,14 @@ impl FunctionContext { ...@@ -243,15 +227,14 @@ impl FunctionContext {
#[derive(Debug)] #[derive(Debug)]
pub struct Block { pub struct Block {
pub id: MuID, pub hdr: MuEntityHeader,
pub name: Option<MuName>,
pub content: Option<BlockContent>, pub content: Option<BlockContent>,
pub control_flow: ControlFlow pub control_flow: ControlFlow
} }
impl Block { impl Block {
pub fn new(id: MuID) -> Block { pub fn new(id: MuID) -> Block {
Block{id: id, name: None, content: None, control_flow: ControlFlow::default()} Block{hdr: MuEntityHeader::unnamed(id), content: None, control_flow: ControlFlow::default()}
} }
} }
...@@ -391,11 +374,10 @@ impl BlockContent { ...@@ -391,11 +374,10 @@ impl BlockContent {
} }
} }
#[derive(Debug, Clone)] #[derive(Debug)]
/// always use with P<TreeNode> /// always use with P<TreeNode>
pub struct TreeNode { pub struct TreeNode {
pub id: MuID, pub hdr: MuEntityHeader,
pub name: Option<MuName>,
pub op: OpCode, pub op: OpCode,
pub v: TreeNode_, pub v: TreeNode_,
} }
...@@ -404,8 +386,7 @@ impl TreeNode { ...@@ -404,8 +386,7 @@ impl TreeNode {
// this is a hack to allow creating TreeNode without using a &mut MuFunctionVersion // this is a hack to allow creating TreeNode without using a &mut MuFunctionVersion
pub fn new_inst(id: MuID, v: Instruction) -> P<TreeNode> { pub fn new_inst(id: MuID, v: Instruction) -> P<TreeNode> {
P(TreeNode{ P(TreeNode{
id: id, hdr: MuEntityHeader::unnamed(id),
name: None,
op: pick_op_code_for_inst(&v), op: pick_op_code_for_inst(&v),
v: TreeNode_::Instruction(v), v: TreeNode_::Instruction(v),
}) })
...@@ -464,10 +445,9 @@ pub enum TreeNode_ { ...@@ -464,10 +445,9 @@ pub enum TreeNode_ {
} }
/// always use with P<Value> /// always use with P<Value>
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, PartialEq)]
pub struct Value { pub struct Value {
pub id: MuID, pub hdr: MuEntityHeader,
pub name: Option<MuName>,
pub ty: P<MuType>, pub ty: P<MuType>,
pub v: Value_ pub v: Value_
} }
...@@ -522,25 +502,18 @@ impl Value { ...@@ -522,25 +502,18 @@ impl Value {
impl fmt::Display for Value { impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let tag = {
if self.name.is_some() {
self.name.unwrap()
} else {
"???"
}
};
match self.v { match self.v {
Value_::SSAVar(id) => { Value_::SSAVar(id) => {
write!(f, "+({} %{}#{})", self.ty, tag, id) write!(f, "+({} %{})", self.ty, self.hdr)
}, },
Value_::Constant(ref c) => { Value_::Constant(ref c) => {
write!(f, "+({} {})", self.ty, c) write!(f, "+({} {} @{})", self.ty, c, self.hdr)
}, },
Value_::Global => { Value_::Global(ref ty) => {
write!(f, "+(GLOBAL {} @{})", self.ty, self.name.unwrap()) write!(f, "+(GLOBAL {} @{})", ty, self.hdr)
}, },
Value_::Memory(ref mem) => { Value_::Memory(ref mem) => {
write!(f, "+({})", mem) write!(f, "+(MEM {} %{})", mem, self.hdr)
} }
} }
} }
...@@ -550,7 +523,7 @@ impl fmt::Display for Value { ...@@ -550,7 +523,7 @@ impl fmt::Display for Value {
pub enum Value_ { pub enum Value_ {
SSAVar(MuID), SSAVar(MuID),
Constant(Constant), Constant(Constant),
Global, Global(P<MuType>), // what type is this global (without IRef)
Memory(MemoryLocation) Memory(MemoryLocation)
} }
...@@ -649,30 +622,74 @@ impl fmt::Display for MemoryLocation { ...@@ -649,30 +622,74 @@ impl fmt::Display for MemoryLocation {
} }
} }
#[derive(Debug)] // Display, PartialEq
pub struct MuEntityHeader {
id: MuID,
name: RwLock<Option<MuName>>
}
impl MuEntityHeader {
pub fn unnamed(id: MuID) -> MuEntityHeader {
MuEntityHeader {
id: id,
name: RwLock::new(None)
}
}
pub fn named(id: MuID, name: MuName) -> MuEntityHeader {
MuEntityHeader {
id: id,
name: RwLock::new(Some(name))
}
}
pub fn id(&self) -> MuID {
self.id
}
pub fn name(&self) -> Option<MuName> {
*self.name.read().unwrap()
}
}
impl PartialEq for MuEntityHeader {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl fmt::Display for MuEntityHeader {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.name().is_none() {
write!(f, "#{}", self.id)
} else {
write!(f, "{} #{}", self.name().unwrap(), self.id)
}
}
}
pub trait MuEntity { pub trait MuEntity {
fn id(&self) -> MuID; fn id(&self) -> MuID;
fn name(&self) -> Option<MuName>; fn name(&self) -> Option<MuName>;
fn set_name(&mut self, name: MuName); fn set_name(&self, name: MuName);
fn as_entity(&self) -> &MuEntity; fn as_entity(&self) -> &MuEntity;
fn as_entity_mut(&mut self) -> &mut MuEntity;
} }
macro_rules! impl_mu_entity { macro_rules! impl_mu_entity {
($entity: ty) => { ($entity: ty) => {
impl MuEntity for $entity { impl MuEntity for $entity {
#[inline(always)] #[inline(always)]
fn id(&self) -> MuID {self.id} fn id(&self) -> MuID {self.hdr.id}
#[inline(always)] #[inline(always)]
fn name(&self) -> Option<MuName> {self.name} fn name(&self) -> Option<MuName> {self.hdr.name()}
fn set_name(&mut self, name: MuName) {self.name = Some(name);} fn set_name(&self, name: MuName) {
let mut write_guard = self.hdr.name.write().unwrap();
*write_guard = Some(name);
}
fn as_entity(&self) -> &MuEntity { fn as_entity(&self) -> &MuEntity {
let ref_ty : &$entity = self; let ref_ty : &$entity = self;
ref_ty as &MuEntity ref_ty as &MuEntity
} }
fn as_entity_mut(&mut self) -> &mut MuEntity {
let ref_ty : &mut $entity = self;
ref_ty as &mut MuEntity
}
} }
} }
} }
......
...@@ -41,76 +41,78 @@ use std::hash::{Hash, Hasher}; ...@@ -41,76 +41,78 @@ use std::hash::{Hash, Hasher};
use std::ops::Deref; use std::ops::Deref;
use std::ops::DerefMut; use std::ops::DerefMut;
/// An owned smart pointer. use std::sync::Arc;
pub struct P<T> {
ptr: Box<T> pub type P<T> = Arc<T>;
}
///// An owned smart pointer.
//pub struct P<T> {
// ptr: Box<T>
//}
#[allow(non_snake_case)] #[allow(non_snake_case)]
/// Construct a `P<T>` from a `T` value. /// Construct a `P<T>` from a `T` value.
pub fn P<T: 'static>(value: T) -> P<T> { pub fn P<T: 'static>(value: T) -> P<T> {
P { Arc::new(value)
ptr: Box::new(value)
}
}
impl<T: 'static> P<T> {
/// Move out of the pointer.
/// Intended for chaining transformations not covered by `map`.
pub fn and_then<U, F>(self, f: F) -> U where
F: FnOnce(T) -> U,
{
f(*self.ptr)
}
}
impl<T> Deref for P<T> {
type Target = T;
fn deref<'a>(&'a self) -> &'a T {
&*self.ptr
}
}
impl<T> DerefMut for P<T> {
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
&mut *self.ptr
}
}
impl<T: 'static + Clone> Clone for P<T> {
fn clone(&self) -> P<T> {
P((**self).clone())
}
}
impl<T: PartialEq> PartialEq for P<T> {
fn eq(&self, other: &P<T>) -> bool {
**self == **other
}
}
impl<T: Eq> Eq for P<T> {}
impl<T: Debug> Debug for P<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&**self, f)
}
}
impl<T: Display> Display for P<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&**self, f)
}
}
impl<T> fmt::Pointer for P<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Pointer::fmt(&self.ptr, f)
}
} }
impl<T: Hash> Hash for P<T> { //impl<T: 'static> P<T> {
fn hash<H: Hasher>(&self, state: &mut H) { // /// Move out of the pointer.
(**self).hash(state); // /// Intended for chaining transformations not covered by `map`.
} // pub fn and_then<U, F>(self, f: F) -> U where
} // F: FnOnce(T) -> U,
// {
// f(*self.ptr)
// }
//}
//
//impl<T> Deref for P<T> {
// type Target = T;
//
// fn deref<'a>(&'a self) -> &'a T {
// &*self.ptr
// }
//}
//
//impl<T> DerefMut for P<T> {
// fn deref_mut<'a>(&'a mut self) -> &'a mut T {
// &mut *self.ptr
// }
//}
//
//impl<T: 'static + Clone> Clone for P<T> {
// fn clone(&self) -> P<T> {
// P((**self).clone())
// }
//}
//
//impl<T: PartialEq> PartialEq for P<T> {
// fn eq(&self, other: &P<T>) -> bool {
// **self == **other
// }
//}
//
//impl<T: Eq> Eq for P<T> {}
//
//impl<T: Debug> Debug for P<T> {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Debug::fmt(&**self, f)
// }
//}
//impl<T: Display> Display for P<T> {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Display::fmt(&**self, f)
// }
//}
//
//impl<T> fmt::Pointer for P<T> {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// fmt::Pointer::fmt(&self.ptr, f)
// }
//}
//
//impl<T: Hash> Hash for P<T> {
// fn hash<H: Hasher>(&self, state: &mut H) {
// (**self).hash(state);
// }
//}
...@@ -6,24 +6,22 @@ use std::fmt; ...@@ -6,24 +6,22 @@ use std::fmt;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::RwLock; use std::sync::RwLock;
#[derive(Clone, PartialEq, Eq, Debug, Hash)] #[derive(PartialEq, Debug)]
pub struct MuType { pub struct MuType {
pub id: MuID, pub hdr: MuEntityHeader,
pub name: Option<MuName>,
pub v: MuType_ pub v: MuType_
} }
impl MuType { impl MuType {
pub fn new(id: MuID, v: MuType_) -> MuType { pub fn new(id: MuID, v: MuType_) -> MuType {
MuType { MuType {
id: id, hdr: MuEntityHeader::unnamed(id),
name: None,
v: v v: v
} }
} }
} }
#[derive(Clone, PartialEq, Eq, Debug, Hash)] #[derive(PartialEq, Debug)]
pub enum MuType_ { pub enum MuType_ {
/// int <length> /// int <length>
Int (usize), Int (usize),
...@@ -107,7 +105,7 @@ lazy_static! { ...@@ -107,7 +105,7 @@ lazy_static! {
pub static ref STRUCT_TAG_MAP : RwLock<HashMap<MuName, StructType_>> = RwLock::new(HashMap::new()); pub static ref STRUCT_TAG_MAP : RwLock<HashMap<MuName, StructType_>> = RwLock::new(HashMap::new());
} }
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(PartialEq, Debug)]
pub struct StructType_ { pub struct StructType_ {
tys: Vec<P<MuType>> tys: Vec<P<MuType>>
} }
...@@ -325,10 +323,9 @@ macro_rules! is_type ( ...@@ -325,10 +323,9 @@ macro_rules! is_type (
) )
); );
#[derive(Clone, PartialEq, Eq, Debug, Hash)] #[derive(PartialEq, Debug)]
pub struct MuFuncSig { pub struct MuFuncSig {
pub id: MuID, pub hdr: MuEntityHeader,
pub name: Option<MuName>,
pub ret_tys : Vec<P<MuType>>, pub ret_tys : Vec<P<MuType>>,
pub arg_tys: Vec<P<MuType>> pub arg_tys: Vec<P<MuType>>
}