Commit 913424bb authored by John Zhang's avatar John Zhang

Merge branch 'master' into jit-test

parents 76d20891 dcfeb8fc
......@@ -19,12 +19,19 @@ use std::collections::HashMap;
use std::collections::HashSet;
use std::sync::Mutex;
use std::sync::RwLock;
use super::super::vm::VM;
use super::api_c::*;
use super::api_bridge::*;
use super::deps::*;
//use super::deps::*; // maybe it is better to import * here.
use super::irnodes::*;
use ast::bundle::*;
use ast::ir::*;
use ast::ptr::*;
use ast::types::*;
/**
* Create a micro VM instance, and expose it as a C-visible `*mut CMuVM` pointer.
......@@ -66,19 +73,43 @@ pub struct MuVM {
}
pub struct MuCtx<'v> {
// ref to the MuVM struct.
mvm: &'v mut MuVM,
/// ref to MuVM
mvm: &'v MuVM,
// Point to the C-visible CMuCtx so that `close_context` can deallocate itself.
/// Point to the C-visible CMuCtx so that `close_context` can deallocate itself.
c_struct: *mut CMuCtx,
}
pub struct MuIRBuilder<'c> {
// ref to the MuCtx struct.
ctx: &'c mut MuCtx<'c>,
pub struct MuIRBuilder<'v> {
/// ref to MuVM
mvm: &'v MuVM,
// Point to the C-visible CMuIRBuilder so that `load` and `abort` can deallocate itself.
/// Point to the C-visible CMuIRBuilder so that `load` and `abort` can deallocate itself.
c_struct: *mut CMuIRBuilder,
/// Map IDs to names. Items are inserted during `gen_sym`. MuIRBuilder is supposed to be used
/// by one thread, so there is no need for locking.
id_name_map: HashMap<MuID, MuName>,
/// The "trantient bundle" includes everything being built here.
bundle: TrantientBundle,
}
/// A trantient bundle, i.e. the bundle being built, but not yet loaded into the MuVM.
#[derive(Default)]
pub struct TrantientBundle {
types: Vec<Box<NodeType>>,
sigs: Vec<Box<NodeFuncSig>>,
consts: Vec<Box<NodeConst>>,
globals: Vec<Box<NodeGlobalCell>>,
funcs: Vec<Box<NodeFunc>>,
expfuncs: Vec<Box<NodeExpFunc>>,
funcvers: Vec<Box<NodeFuncVer>>,
bbs: Vec<Box<NodeBB>>,
insts: Vec<Box<NodeInst>>,
dest_clauses: Vec<Box<NodeDestClause>>,
exc_clauses: Vec<Box<NodeExcClause>>,
ka_clauses: Vec<Box<NodeKeepaliveClause>>,
}
/**
......@@ -104,7 +135,7 @@ impl MuVM {
}
}
pub fn new_context(&mut self) -> *mut CMuCtx {
pub fn new_context(&self) -> *mut CMuCtx {
info!("Creating MuCtx...");
let ctx = Box::new(MuCtx {
......@@ -125,11 +156,11 @@ impl MuVM {
cctx
}
pub fn id_of(&mut self, name: MuName) -> MuID {
pub fn id_of(&self, name: MuName) -> MuID {
self.vm.id_of_by_refstring(&name)
}
pub fn name_of(&mut self, id: MuID) -> CMuCString {
pub fn name_of(&self, id: MuID) -> CMuCString {
let mut map = self.name_cache.lock().unwrap();
let cname = map.entry(id).or_insert_with(|| {
......@@ -140,7 +171,7 @@ impl MuVM {
cname.as_ptr()
}
pub fn set_trap_handler(&mut self, trap_handler: CMuTrapHandler, userdata: CMuCPtr) {
pub fn set_trap_handler(&self, trap_handler: CMuTrapHandler, userdata: CMuCPtr) {
panic!("Not implemented")
}
......@@ -148,8 +179,9 @@ impl MuVM {
impl<'v> MuCtx<'v> {
#[inline(always)]
fn get_mvm(&mut self) -> &mut MuVM {
fn get_mvm(&mut self) -> &MuVM {
self.mvm
//unsafe { &mut *self.mvm }
}
pub fn id_of(&mut self, name: MuName) -> MuID {
......@@ -511,12 +543,14 @@ impl<'v> MuCtx<'v> {
panic!("Not implemented")
}
pub fn new_ir_builder(&'v mut self) -> *mut CMuIRBuilder {
pub fn new_ir_builder(&mut self) -> *mut CMuIRBuilder {
info!("Creating MuIRBuilder...");
let b: Box<MuIRBuilder<'v>> = Box::new(MuIRBuilder {
ctx: self,
let b: Box<MuIRBuilder> = Box::new(MuIRBuilder {
mvm: self.mvm,
c_struct: ptr::null_mut(),
id_name_map: Default::default(),
bundle: Default::default(),
});
let b_ptr = Box::into_raw(b);
......@@ -538,24 +572,19 @@ impl<'v> MuCtx<'v> {
}
impl<'c> MuIRBuilder<'c> {
impl<'v> MuIRBuilder<'v> {
#[inline(always)]
fn get_ctx(&'c mut self) -> &mut MuCtx {
self.ctx
}
#[inline(always)]
fn get_mvm(&'c mut self) -> &mut MuVM {
self.get_ctx().get_mvm()
fn get_mvm(&mut self) -> &MuVM {
self.mvm
}
#[inline(always)]
fn get_vm(&'c mut self) -> &mut VM {
&mut self.get_mvm().vm
fn get_vm(&mut self) -> &VM {
&self.get_mvm().vm
}
#[inline(always)]
fn next_id(&'c mut self) -> MuID {
fn next_id(&mut self) -> MuID {
self.get_vm().next_id()
}
......@@ -569,6 +598,13 @@ impl<'c> MuIRBuilder<'c> {
}
}
/// Get the Mu name of the `id`. This will consume the entry in the `id_name_map`. For this
/// reason, this function is only called when the actual MuEntity that has this ID is created
/// (such as `new_type_int`).
fn consume_name_of(&mut self, id: MuID) -> Option<MuName> {
self.id_name_map.remove(&id)
}
pub fn load(&mut self) {
panic!("Please implement bundle loading before deallocating itself.");
self.deallocate();
......@@ -579,13 +615,37 @@ impl<'c> MuIRBuilder<'c> {
self.deallocate();
}
pub fn gen_sym(&'c mut self, name: Option<String>) -> MuID {
pub fn gen_sym(&mut self, name: Option<String>) -> MuID {
let my_id = self.next_id();
panic!("Not implemented")
debug!("gen_sym({:?}) -> {}", name, my_id);
match name {
None => {},
Some(the_name) => {
let old = self.id_name_map.insert(my_id, the_name);
debug_assert!(old.is_none(), "ID already exists: {}, new name: {}, old name: {}",
my_id, self.id_name_map.get(&my_id).unwrap(), old.unwrap());
},
};
my_id
}
pub fn new_type_int(&mut self, id: MuID, len: c_int) {
panic!("Not implemented")
self.bundle.types.push(Box::new(NodeType::TypeInt { id: id, len: len }));
// let maybe_name = self.consume_name_of(id);
// let pty = P(MuType {
// hdr: MuEntityHeader {
// id: id,
// name: RwLock::new(maybe_name),
// },
// v: MuType_::Int(len as usize),
// });
//
// self.bundle.types.push(pty);
}
pub fn new_type_float(&mut self, id: MuID) {
......@@ -597,7 +657,8 @@ impl<'c> MuIRBuilder<'c> {
}
pub fn new_type_uptr(&mut self, id: MuID, ty: MuID) {
panic!("Not implemented")
self.bundle.types.push(Box::new(NodeType::TypeUPtr{ id: id,
ty: ty }));
}
pub fn new_type_ufuncptr(&mut self, id: MuID, sig: MuID) {
......@@ -605,7 +666,8 @@ impl<'c> MuIRBuilder<'c> {
}
pub fn new_type_struct(&mut self, id: MuID, fieldtys: Vec<MuID>) {
panic!("Not implemented")
self.bundle.types.push(Box::new(NodeType::TypeStruct { id: id,
fieldtys: fieldtys }));
}
pub fn new_type_hybrid(&mut self, id: MuID, fixedtys: Vec<MuID>, varty: MuID) {
......@@ -661,11 +723,13 @@ impl<'c> MuIRBuilder<'c> {
}
pub fn new_funcsig(&mut self, id: MuID, paramtys: Vec<MuID>, rettys: Vec<MuID>) {
panic!("Not implemented")
self.bundle.sigs.push(Box::new(NodeFuncSig { id: id,
paramtys: paramtys, rettys: rettys }));
}
pub fn new_const_int(&mut self, id: MuID, ty: MuID, value: u64) {
panic!("Not implemented")
self.bundle.consts.push(Box::new(NodeConst::ConstInt { id: id,
ty: ty, value: value }));
}
pub fn new_const_int_ex(&mut self, id: MuID, ty: MuID, values: &[u64]) {
......@@ -693,11 +757,13 @@ impl<'c> MuIRBuilder<'c> {
}
pub fn new_global_cell(&mut self, id: MuID, ty: MuID) {
panic!("Not implemented")
self.bundle.globals.push(Box::new(NodeGlobalCell { id: id,
ty: ty }));
}
pub fn new_func(&mut self, id: MuID, sig: MuID) {
panic!("Not implemented")
self.bundle.funcs.push(Box::new(NodeFunc { id: id,
sig: sig }));
}
pub fn new_exp_func(&mut self, id: MuID, func: MuID, callconv: CMuCallConv, cookie: MuID) {
......@@ -705,11 +771,14 @@ impl<'c> MuIRBuilder<'c> {
}
pub fn new_func_ver(&mut self, id: MuID, func: MuID, bbs: Vec<MuID>) {
panic!("Not implemented")
self.bundle.funcvers.push(Box::new(NodeFuncVer { id: id,
func: func, bbs: bbs }));
}
pub fn new_bb(&mut self, id: MuID, nor_param_ids: Vec<MuID>, nor_param_types: Vec<MuID>, exc_param_id: Option<MuID>, insts: Vec<MuID>) {
panic!("Not implemented")
self.bundle.bbs.push(Box::new(NodeBB { id: id,
norParamIDs: nor_param_ids, norParamTys: nor_param_types,
excParamID: exc_param_id, insts: insts }));
}
pub fn new_dest_clause(&mut self, id: MuID, dest: MuID, vars: Vec<MuID>) {
......@@ -741,7 +810,10 @@ impl<'c> MuIRBuilder<'c> {
}
pub fn new_binop(&mut self, id: MuID, result_id: MuID, optr: CMuBinOptr, ty: MuID, opnd1: MuID, opnd2: MuID, exc_clause: Option<MuID>) {
panic!("Not implemented")
self.bundle.insts.push(Box::new(NodeInst::NodeBinOp {
id: id, resultID: result_id, statusResultIDs: vec![],
optr: optr, flags: 0, ty: ty, opnd1: opnd1, opnd2: opnd2,
excClause: exc_clause}))
}
pub fn new_binop_with_status(&mut self, id: MuID, result_id: MuID, status_result_ids: Vec<MuID>, optr: CMuBinOptr, status_flags: CMuBinOpStatus, ty: MuID, opnd1: MuID, opnd2: MuID, exc_clause: Option<MuID>) {
......
#![allow(non_snake_case)]
#![allow(dead_code)]
use super::deps::*;
//pub type MuID = usize;
pub type MuTypeNode = MuID;
pub type MuFuncSigNode = MuID;
pub type MuVarNode = MuID;
pub type MuGlobalVarNode = MuID;
pub type MuLocalVarNode = MuID;
pub type MuConstNode = MuID;
pub type MuConstIntNode = MuID;
pub type MuFuncNode = MuID;
pub type MuFuncVerNode = MuID;
pub type MuBBNode = MuID;
pub type MuInstNode = MuID;
pub type MuDestClause = MuID;
pub type MuExcClause = MuID;
pub type MuKeepaliveClause = MuID;
pub type MuCurStackClause = MuID;
pub type MuNewStackClause = MuID;
pub type MuWPID = MuID;
pub type Flag = u32;
pub type MuBinOptr = Flag;
pub type MuBinOpStatus = Flag;
pub type MuCmpOptr = Flag;
pub type MuConvOptr = Flag;
pub type MuMemoryOrder = Flag;
pub type MuAtomicRMWOptr = Flag;
pub type MuCommInst = Flag;
#[derive(Debug)]
pub enum NodeType {
TypeInt { id: MuID, len: i32 },
TypeFloat { id: MuID },
TypeDouble { id: MuID },
TypeUPtr { id: MuID, ty: MuTypeNode },
TypeUFuncPtr { id: MuID, sig: MuFuncSigNode },
TypeStruct { id: MuID, fieldtys: Vec<MuTypeNode> },
TypeHybrid { id: MuID, fixedtys: Vec<MuTypeNode>, varty: MuTypeNode },
TypeArray { id: MuID, elemty: MuTypeNode, len: usize },
TypeVector { id: MuID, elemty: MuTypeNode, lem: usize },
TypeRef { id: MuID, ty: MuTypeNode },
TypeIRef { id: MuID, ty: MuTypeNode },
TypeWeakRef { id: MuID, ty: MuTypeNode },
TypeFuncRef { id: MuID, sig: MuFuncSigNode },
TypeThreadRef { id: MuID },
TypeStackRef { id: MuID },
TypeFrameCursorRef { id: MuID },
TypeIRBuilderRef { id: MuID },
}
#[derive(Debug)]
pub struct NodeFuncSig { pub id: MuID, pub paramtys: Vec<MuTypeNode>, pub rettys: Vec<MuTypeNode> }
#[derive(Debug)]
pub enum NodeConst {
ConstInt { id: MuID, ty: MuTypeNode, value: u64 },
ConstFloat { id: MuID, ty: MuTypeNode, value: f32 },
ConstDouble { id: MuID, ty: MuTypeNode, value: f64 },
ConstNull { id: MuID, ty: MuTypeNode },
ConstSeq { id: MuID, ty: MuTypeNode, elems: Vec<MuGlobalVarNode> },
ConstExtern { id: MuID, ty: MuTypeNode, symbol: String },
}
#[derive(Debug)]
pub struct NodeGlobalCell { pub id: MuID, pub ty: MuTypeNode }
#[derive(Debug)]
pub struct NodeFunc { pub id: MuID, pub sig: MuFuncSigNode }
#[derive(Debug)]
pub struct NodeExpFunc { pub id: MuID, pub func: MuFuncNode, pub callconv: usize, pub cookie: MuConstIntNode }
#[derive(Debug)]
pub struct NodeFuncVer { pub id: MuID, pub func: MuFuncNode, pub bbs: Vec<MuBBNode> }
#[derive(Debug)]
pub struct NodeBB { pub id: MuID, pub norParamIDs: Vec<MuID>, pub norParamTys: Vec<MuTypeNode>, pub excParamID: Option<MuID>, pub insts: Vec<MuInstNode> }
#[derive(Debug)]
pub struct NodeDestClause { pub id: MuID, pub dest: MuBBNode, pub vars: Vec<MuVarNode> }
#[derive(Debug)]
pub struct NodeExcClause { pub id: MuID, pub nor: MuDestClause, pub exc: MuDestClause }
#[derive(Debug)]
pub struct NodeKeepaliveClause { pub id: MuID, pub vars: Vec<MuLocalVarNode> }
#[derive(Debug)]
pub struct NodeCscRetWith { pub id: MuID, pub rettys: Vec<MuVarNode> }
#[derive(Debug)]
pub struct NodeCscKillOld { pub id: MuID }
#[derive(Debug)]
pub struct NodeNscPassValues { pub id: MuID, pub tys: Vec<MuTypeNode>, pub vars: Vec<MuVarNode> }
#[derive(Debug)]
pub struct NodeNscThrowExc { pub id: MuID, pub exc: MuVarNode }
#[derive(Debug)]
pub enum NodeInst {
NodeBinOp { id: MuID, resultID: MuID, statusResultIDs: Vec<MuID>, optr: MuBinOptr, flags: MuBinOpStatus, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode, excClause: Option<MuExcClause> },
NodeCmp { id: MuID, resultID: MuID, optr: MuCmpOptr, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode },
NodeConv { id: MuID, resultID: MuID, optr: MuConvOptr, fromTy: MuTypeNode, toTy: MuTypeNode, opnd: MuVarNode },
NodeSelect { id: MuID, resultID: MuID, condTy: MuTypeNode, opndTy: MuTypeNode, cond: MuVarNode, ifTrue: MuVarNode, ifFalse: MuVarNode },
NodeBranch { id: MuID, dest: MuDestClause },
NodeBranch2 { id: MuID, cond: MuVarNode, ifTrue: MuDestClause, ifFalse: MuDestClause },
NodeSwitch { id: MuID, opndTy: MuTypeNode, opnd: MuVarNode, defaultDest: MuDestClause, cases: Vec<MuConstNode>, dests: Vec<MuDestClause> },
NodeCall { id: MuID, resultIDs: Vec<MuID>, sig: MuFuncSigNode, callee: MuVarNode, args: Vec<MuVarNode>, excClause: Option<MuExcClause>, keepaliveClause: Option<MuKeepaliveClause> },
NodeTailCall { id: MuID, sig: MuFuncSigNode, callee: MuVarNode, args: Vec<MuVarNode> },
NodeRet { id: MuID, rvs: Vec<MuVarNode> },
NodeThrow { id: MuID, exc: MuVarNode },
NodeExtractValue { id: MuID, resultID: MuID, strty: MuTypeNode, index: i32, opnd: MuVarNode },
NodeInsertValue { id: MuID, resultID: MuID, strty: MuTypeNode, index: i32, opnd: MuVarNode, newval: MuVarNode },
NodeExtractElement { id: MuID, resultID: MuID, seqty: MuTypeNode, indty: MuTypeNode, opnd: MuVarNode, index: MuVarNode },
NodeInsertElement { id: MuID, resultID: MuID, seqty: MuTypeNode, indty: MuTypeNode, opnd: MuVarNode, index: MuVarNode, newval: MuVarNode },
NodeShuffleVector { id: MuID, resultID: MuID, vecty: MuTypeNode, maskty: MuTypeNode, vec1: MuVarNode, vec2: MuVarNode, mask: MuVarNode },
NodeNew { id: MuID, resultID: MuID, allocty: MuTypeNode, excClause: Option<MuExcClause> },
NodeNewHybrid { id: MuID, resultID: MuID, allocty: MuTypeNode, lenty: MuTypeNode, length: MuVarNode, excClause: Option<MuExcClause> },
NodeAlloca { id: MuID, resultID: MuID, allocty: MuTypeNode, excClause: Option<MuExcClause> },
NodeAllocaHybrid { id: MuID, resultID: MuID, allocty: MuTypeNode, lenty: MuTypeNode, length: MuVarNode, excClause: Option<MuExcClause> },
NodeGetIRef { id: MuID, resultID: MuID, refty: MuTypeNode, opnd: MuVarNode },
NodeGetFieldIRef { id: MuID, resultID: MuID, isPtr: bool, refty: MuTypeNode, index: i32, opnd: MuVarNode },
NodeGetElemIRef { id: MuID, resultID: MuID, isPtr: bool, refty: MuTypeNode, indty: MuTypeNode, opnd: MuVarNode, index: MuVarNode },
NodeShiftIRef { id: MuID, resultID: MuID, isPtr: bool, refty: MuTypeNode, offty: MuTypeNode, opnd: MuVarNode, offset: MuVarNode },
NodeGetVarPartIRef { id: MuID, resultID: MuID, isPtr: bool, refty: MuTypeNode, opnd: MuVarNode },
NodeLoad { id: MuID, resultID: MuID, isPtr: bool, ord: MuMemoryOrder, refty: MuTypeNode, loc: MuVarNode, excClause: Option<MuExcClause> },
NodeStore { id: MuID, isPtr: bool, ord: MuMemoryOrder, refty: MuTypeNode, loc: MuVarNode, newval: MuVarNode, excClause: Option<MuExcClause> },
NodeCmpXchg { id: MuID, valueResultID: MuID, succResultID: MuID, isPtr: bool, isWeak: bool, ordSucc: MuMemoryOrder, ordFail: MuMemoryOrder, refty: MuTypeNode, loc: MuVarNode, expected: MuVarNode, desired: MuVarNode, excClause: Option<MuExcClause> },
NodeAtomicRMW { id: MuID, resultID: MuID, isPtr: bool, ord: MuMemoryOrder, optr: MuAtomicRMWOptr, refTy: MuTypeNode, loc: MuVarNode, opnd: MuVarNode, excClause: Option<MuExcClause> },
NodeFence { id: MuID, ord: MuMemoryOrder, },
NodeTrap { id: MuID, resultIDs: Vec<MuID>, rettys: Vec<MuTypeNode>, excClause: Option<MuExcClause>, keepaliveClause: Option<MuKeepaliveClause> },
NodeWatchPoint { id: MuID, wpid: MuWPID, resultIDs: Vec<MuID>, rettys: Vec<MuTypeNode>, dis: MuDestClause, ena: MuDestClause, exc: Option<MuDestClause>, keepaliveClause: Option<MuKeepaliveClause> },
NodeWPBranch { id: MuID, wpid: MuWPID, dis: MuDestClause, ena: MuDestClause },
NodeCCall { id: MuID, resultIDs: Vec<MuID>, callconv: Flag, calleeTy: MuTypeNode, sig: MuFuncSigNode, callee: MuVarNode, args: Vec<MuVarNode>, excClause: Option<MuExcClause>, keepaliveClause: Option<MuKeepaliveClause> },
NodeNewThread { id: MuID, resultID: MuID, stack: MuVarNode, threadlocal: Option<MuVarNode>, newStackClause: MuNewStackClause, excClause: Option<MuExcClause> },
NodeSwapStack { id: MuID, resultIDs: Vec<MuID>, swappee: MuVarNode, curStackClause: MuCurStackClause, newStackClause: MuNewStackClause, excClause: Option<MuExcClause>, keepaliveClause: Option<MuKeepaliveClause> },
NodeCommInst { id: MuID, resultIDs: Vec<MuID>, opcode: MuCommInst, flags: Vec<Flag>, tys: Vec<MuTypeNode>, sigs: Vec<MuFuncSigNode>, args: Vec<MuVarNode>, excClause: Option<MuExcClause>, keepaliveClause: Option<MuKeepaliveClause> },
}
pub mod api_c; // This is pub because `api_c` can be used directly. It is just an interface.
mod api_bridge; // This is mostly auto-generatd code, and should not be used externally.
mod api_impl; // Mostly private.
mod irnodes;
pub use self::api_impl::mu_fastimpl_new;
......
......@@ -14,6 +14,8 @@ use self::mu::vm::*;
use self::mu::vm::api::*;
use std::mem;
use std::ptr;
use std::ffi::CString;
#[test]
#[allow(unused_variables)]
......@@ -42,6 +44,10 @@ fn test_startup_shutdown() {
let b = ((*ctx).new_ir_builder)(ctx);
let id1 = ((*b).gen_sym)(b, ptr::null_mut());
let id2 = ((*b).gen_sym)(b, CString::new("@id2").unwrap().as_ptr());
let id3 = ((*b).gen_sym)(b, ptr::null_mut());
((*b).abort)(b);
((*ctx).close_context)(ctx);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment