GitLab will continue to be upgraded from 11.4.5-ce.0 on November 25th 2019 at 4.00pm (AEDT) to 5.00pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available.

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