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 212638e9 authored by qinsoon's avatar qinsoon
Browse files

refactored ast

parent e31a5a4b
#![allow(dead_code)]
#![allow(unused_variables)]
use ast::ptr::P;
use ast::op::{BinOp, CmpOp, AtomicRMWOp};
use ast::types::*;
pub type WPID = usize;
......@@ -9,95 +7,84 @@ pub type MuID = usize;
pub type MuTag = &'static str;
pub type Address = usize; // TODO: replace this with Address(usize)
#[derive(Clone, Debug)]
pub struct SSAVar {
pub id: MuID,
pub tag: MuTag,
pub ty: P<MuType_>
#[derive(Debug)]
pub struct MuFunction {
pub fn_name: MuTag,
pub sig: P<MuFuncSig>,
pub entry: MuTag,
pub blocks: Vec<(MuTag, Block)>
}
#[derive(Clone, Debug)]
pub enum Value {
SSAVar(SSAVar),
Constant(MuConstant)
#[derive(Debug)]
pub struct Block {
pub label: MuTag,
pub content: Option<BlockContent>
}
#[derive(Debug)]
pub struct TreeNode {
v: TreeNodeKind,
children: Vec<P<TreeNode>>,
impl Block {
pub fn new(label: MuTag) -> Block {
Block{label: label, content: None}
}
}
#[derive(Debug)]
pub enum TreeNodeKind {
Value(Vec<P<Value>>),
Expression(P<Expression>),
pub struct BlockContent {
pub args: Vec<P<TreeNode>>,
pub body: Vec<P<TreeNode>>,
pub keepalives: Option<Vec<P<TreeNode>>>
}
#[derive(Copy, Clone, Debug)]
pub enum MemoryOrder {
NotAtomic,
Relaxed,
Consume,
Acquire,
Release,
AcqRel,
SeqCst
#[derive(Clone, Debug)]
/// always use with P<TreeNode>
pub struct TreeNode {
pub v: TreeNodeKind,
pub children: Vec<P<TreeNode>>,
}
#[derive(Copy, Clone, Debug)]
pub enum CallConvention {
Mu,
Foreign(ForeignFFI)
}
impl TreeNode {
pub fn new_value(v: P<Value>) -> P<TreeNode> {
P(TreeNode{v: TreeNodeKind::Value(v), children: vec![]})
}
#[derive(Copy, Clone, Debug)]
pub enum ForeignFFI {
C
pub fn new_inst(v: Instruction) -> P<TreeNode> {
P(TreeNode{v: TreeNodeKind::Instruction(v), children: vec![]})
}
}
#[derive(Debug)]
pub struct CallData {
pub func: P<SSAVar>,
pub args: Vec<P<Value>>,
pub convention: CallConvention
#[derive(Clone, Debug)]
pub enum TreeNodeKind {
Value(P<Value>),
Instruction(Instruction),
}
#[derive(Debug)]
pub struct Block {
pub label: MuTag,
pub content: Option<BlockContent>
/// always use with P<Value>
#[derive(Clone, Debug)]
pub enum Value {
SSAVar(SSAVar),
Constant(MuConstant)
}
impl Block {
pub fn new(label: MuTag) -> Block {
Block{label: label, content: None}
impl Value {
pub fn new_ssa(v: SSAVar) -> P<Value> {
P(Value::SSAVar(v))
}
}
#[derive(Debug)]
pub struct BlockContent {
pub args: Vec<P<Value>>,
pub body: Vec<Instruction>,
pub keepalives: Option<Vec<P<SSAVar>>>
}
#[derive(Debug)]
pub struct ResumptionData {
pub normal_dest: Destination,
pub exn_dest: Destination
pub fn new_constnat(v: MuConstant) -> P<Value> {
P(Value::Constant(v))
}
}
#[derive(Debug)]
pub enum DestArg {
Normal(P<Value>),
Freshbound(usize)
#[derive(Clone, Debug)]
pub struct SSAVar {
pub id: MuID,
pub tag: MuTag,
pub ty: P<MuType_>
}
#[derive(Debug)]
pub struct Destination {
pub target: MuTag,
pub args: Vec<DestArg>
#[derive(Clone, Debug)]
pub struct MuConstant{
pub ty: P<MuType_>,
pub val: Constant
}
#[derive(Clone, Debug)]
......@@ -111,10 +98,73 @@ pub enum Constant {
UFuncRefV(Address)
}
#[derive(Debug)]
pub enum Expression {
BinOp(BinOp, P<Value>, P<Value>),
CmpOp(CmpOp, P<Value>, P<Value>),
#[derive(Clone, Debug)]
pub enum Instruction {
NonTerm(NonTermInstruction),
Term(Terminal)
}
#[derive(Clone, Debug)]
pub enum Terminal {
Return(Vec<P<TreeNode>>),
ThreadExit,
Throw(Vec<P<TreeNode>>),
TailCall(CallData),
Branch1(Destination),
Branch2{
cond: P<TreeNode>,
true_dest: Destination,
false_dest: Destination
},
Watchpoint{ // Watchpoint NONE ResumptionData
// serves as an unconditional trap. Trap to client, and resume with ResumptionData
// Watchpoint (WPID dest) ResumptionData
// when disabled, jump to dest
// when enabled, trap to client and resume
id: Option<WPID>,
disable_dest: Option<Destination>,
resume: ResumptionData
},
WPBranch{
wp: WPID,
disable_dest: Destination,
enable_dest: Destination
},
Call{
data: CallData,
resume: ResumptionData
},
SwapStack{
stack: P<TreeNode>,
is_exception: bool,
args: Vec<P<TreeNode>>,
resume: ResumptionData
},
Switch{
cond: P<TreeNode>,
default: Destination,
branches: Vec<(P<Constant>, Destination)>
},
ExnInstruction{
inner: NonTermInstruction,
resume: ResumptionData
}
}
#[derive(Clone, Debug)]
pub enum NonTermInstruction {
Assign{
left: Vec<P<TreeNode>>,
right: Expression_
},
Fence(MemoryOrder),
}
#[derive(Clone, Debug)]
pub enum Expression_ {
BinOp(BinOp, P<TreeNode>, P<TreeNode>),
CmpOp(CmpOp, P<TreeNode>, P<TreeNode>),
// yields the constant value
Constant(P<Constant>),
......@@ -145,9 +195,9 @@ pub enum Expression {
is_strong: bool,
success_order: MemoryOrder,
fail_order: MemoryOrder,
mem_loc: P<SSAVar>,
expected_value: P<Value>,
desired_value: P<Value>
mem_loc: P<TreeNode>,
expected_value: P<TreeNode>,
desired_value: P<TreeNode>
},
// yields old memory value
......@@ -155,8 +205,8 @@ pub enum Expression {
is_iref: bool, // T for iref, F for ptr
order: MemoryOrder,
op: AtomicRMWOp,
mem_loc: P<Value>,
value: P<Value> // operand for op
mem_loc: P<TreeNode>,
value: P<TreeNode> // operand for op
},
// yields a reference of the type
......@@ -168,53 +218,53 @@ pub enum Expression {
// yields ref
NewHybrid{ // hybrid type, var part length
ty: P<MuType_>,
var_len: P<Value>
var_len: P<TreeNode>
},
// yields iref
AllocAHybrid{
ty: P<MuType_>,
var_len: P<Value>
var_len: P<TreeNode>
},
// yields stack ref
NewStack{
func: P<Value>
func: P<TreeNode>
},
// yields thread reference
NewThread{
stack: P<Value>,
args: Vec<P<Value>>
stack: P<TreeNode>,
args: Vec<P<TreeNode>>
},
// yields thread reference (thread resumes with exceptional value)
NewThreadExn{
stack: P<Value>,
exn: P<Value>
stack: P<TreeNode>,
exn: P<TreeNode>
},
// yields frame cursor
NewFrameCursor(P<Value>), // stack
NewFrameCursor(P<TreeNode>), // stack
GetIRef(P<Value>),
GetIRef(P<TreeNode>),
GetFieldIRef{
base: P<Value>, // iref or ptr
base: P<TreeNode>, // iref or ptr
index: P<Constant>
},
GetElementIRef{
base: P<Value>,
index: P<Value>
base: P<TreeNode>,
index: P<TreeNode>
},
ShiftIRef{
base: P<Value>,
offset: P<Value>
base: P<TreeNode>,
offset: P<TreeNode>
},
GetVarPartIRef(P<Value>),
GetVarPartIRef(P<TreeNode>),
// PushFrame{
// stack: P<Value>,
......@@ -225,153 +275,49 @@ pub enum Expression {
// }
}
#[derive(Debug)]
pub enum Instruction {
NonTerm(NonTermInstruction),
Term(Terminal)
#[derive(Copy, Clone, Debug)]
pub enum MemoryOrder {
NotAtomic,
Relaxed,
Consume,
Acquire,
Release,
AcqRel,
SeqCst
}
#[derive(Debug)]
pub enum NonTermInstruction {
Assign{
left: Vec<P<Value>>,
right: Expression
},
Fence(MemoryOrder),
#[derive(Copy, Clone, Debug)]
pub enum CallConvention {
Mu,
Foreign(ForeignFFI)
}
#[derive(Debug)]
pub enum Terminal {
Return(Vec<P<Value>>),
ThreadExit,
Throw(Vec<P<Value>>),
TailCall(CallData),
Branch1(Destination),
Branch2{
cond: P<Value>,
true_dest: Destination,
false_dest: Destination
},
Watchpoint{ // Watchpoint NONE ResumptionData
// serves as an unconditional trap. Trap to client, and resume with ResumptionData
// Watchpoint (WPID dest) ResumptionData
// when disabled, jump to dest
// when enabled, trap to client and resume
id: Option<WPID>,
disable_dest: Option<Destination>,
resume: ResumptionData
},
WPBranch{
wp: WPID,
disable_dest: Destination,
enable_dest: Destination
},
Call{
data: CallData,
resume: ResumptionData
},
SwapStack{
stack: P<Value>,
is_exception: bool,
args: Vec<P<Value>>,
resume: ResumptionData
},
Switch{
cond: P<Value>,
default: Destination,
branches: Vec<(P<Constant>, Destination)>
},
ExnInstruction{
inner: NonTermInstruction,
resume: ResumptionData
}
#[derive(Copy, Clone, Debug)]
pub enum ForeignFFI {
C
}
#[derive(Clone, Debug)]
pub struct MuConstant{
pub ty: P<MuType_>,
pub val: Constant
}
#[derive(Debug)]
pub struct MuFunction {
pub fn_name: MuTag,
pub sig: P<MuFuncSig>,
pub entry: MuTag,
pub blocks: Vec<(MuTag, Block)>
pub struct CallData {
pub func: P<TreeNode>,
pub args: Vec<P<TreeNode>>,
pub convention: CallConvention
}
#[derive(Copy, Clone, Debug)]
pub enum BinOp {
// Int(n) BinOp Int(n) -> Int(n)
Add,
Sub,
Mul,
Sdiv,
Srem,
Udiv,
And,
Or,
Xor,
// Int(n) BinOp Int(m) -> Int(n)
Shl,
Lshr,
AsHR,
// FP BinOp FP -> FP
Fadd,
FSub,
FMul,
FDiv,
FRem
#[derive(Clone, Debug)]
pub struct ResumptionData {
pub normal_dest: Destination,
pub exn_dest: Destination
}
#[derive(Copy, Clone, Debug)]
pub enum CmpOp {
// for Int comparison
EQ,
NE,
SGE,
SGT,
SLE,
SLT,
UGE,
UGT,
ULE,
ULT,
// for FP comparison
FFALSE,
FTRUE,
FOEQ,
FOGT,
FOGE,
FOLT,
FOLE,
FONE,
FORD,
FUEQ,
FUGT,
FUGE,
FULT,
FULE,
FUNE,
FUNO
#[derive(Clone, Debug)]
pub enum DestArg {
Normal(P<TreeNode>),
Freshbound(usize)
}
#[derive(Copy, Clone, Debug)]
pub enum AtomicRMWOp {
XCHG,
ADD,
SUB,
AND,
NAND,
OR,
XOR,
MAX,
MIN,
UMAX,
UMIN
#[derive(Clone, Debug)]
pub struct Destination {
pub target: MuTag,
pub args: Vec<DestArg>
}
\ No newline at end of file
pub mod types;
pub mod ir;
pub mod ptr;
pub mod op;
\ No newline at end of file
#[derive(Copy, Clone, Debug)]
pub enum BinOp {
// Int(n) BinOp Int(n) -> Int(n)
Add,
Sub,
Mul,
Sdiv,
Srem,
Udiv,
And,
Or,
Xor,
// Int(n) BinOp Int(m) -> Int(n)
Shl,
Lshr,
AsHR,
// FP BinOp FP -> FP
Fadd,
FSub,
FMul,
FDiv,
FRem
}
#[derive(Copy, Clone, Debug)]
pub enum CmpOp {
// for Int comparison
EQ,
NE,
SGE,
SGT,
SLE,
SLT,
UGE,
UGT,
ULE,
ULT,
// for FP comparison
FFALSE,
FTRUE,
FOEQ,
FOGT,
FOGE,
FOLT,
FOLE,
FONE,
FORD,
FUEQ,
FUGT,
FUGE,
FULT,
FULE,
FUNE,
FUNO
}
#[derive(Copy, Clone, Debug)]
pub enum AtomicRMWOp {
XCHG,
ADD,
SUB,
AND,
NAND,
OR,
XOR,
MAX,
MIN,
UMAX,
UMIN
}
\ No newline at end of file
extern crate std;
use ast::ptr::*;
use ast::ptr::P;
use ast::ir::*;
use std::collections::HashMap;
use std::sync::RwLock;
......
......@@ -3,6 +3,7 @@ extern crate mu;
use self::mu::ast::types::*;
use self::mu::ast::ir::*;
use self::mu::ast::ptr::*;
use self::mu::ast::op::*;
use self::mu::vm::context::*;
#[test]
......@@ -41,29 +42,30 @@ pub fn factorial() -> VMContext {
// %blk_0(<@int_64> %n_3):
let mut blk_0 = Block::new("blk_0");
let blk_0_n_3 = P(Value::SSAVar(SSAVar{id: 0, tag: "n_3", ty: type_def_int64.clone()}));
let blk_0_n_3 = TreeNode::new_value(Value::new_ssa(SSAVar{id: 0, tag: "n_3", ty: type_def_int64.clone()}));
let const_def_int64_1_local = TreeNode::new_value(const_def_int64_1.clone());
// %v48 = EQ <@int_64> %n_3 @int_64_1
let blk_0_v48 = P(Value::SSAVar(SSAVar{id: 1, tag: "v48", ty: type_def_int64.clone()}));
let blk_0_v48_expr = Expression::CmpOp(
let blk_0_v48 = TreeNode::new_value(Value::new_ssa(SSAVar{id: 1, tag: "v48", ty: type_def_int64.clone()}));
let blk_0_v48_expr = Expression_::CmpOp(
CmpOp::EQ,
blk_0_n_3.clone(),
const_def_int64_1.clone()
const_def_int64_1_local.clone()
);
let blk_0_inst0 = Instruction::NonTerm(NonTermInstruction::Assign{left: vec![blk_0_v48.clone()], right: blk_0_v48_expr});
let blk_0_inst0 = TreeNode::new_inst(Instruction::NonTerm(NonTermInstruction::Assign{left: vec![blk_0_v48.clone()], right: blk_0_v48_expr}));
// BRANCH2 %v48 %blk_2(@int_64_1) %blk_1(%n_3)