Commit a540f43e authored by qinsoon's avatar qinsoon

implemented some APIs related to handle and global initialization

parent d39f7cae
use super::common::*;
use utils::Address;
//use std::os::raw::c_void;
pub struct MuCtx {
/// ref to MuVM
......@@ -54,111 +56,115 @@ impl MuCtx {
}
pub fn handle_from_sint8(&mut self, num: i8, len: c_int) -> *const APIHandle {
panic!("Not implemented")
prepare_handle((self.get_mvm().vm.handle_from_sint8(num, len as usize)))
}
pub fn handle_from_uint8(&mut self, num: u8, len: c_int) -> *const APIHandle {
panic!("Not implemented")
prepare_handle((self.get_mvm().vm.handle_from_uint8(num, len as usize)))
}
pub fn handle_from_sint16(&mut self, num: i16, len: c_int) -> *const APIHandle {
panic!("Not implemented")
prepare_handle((self.get_mvm().vm.handle_from_sint16(num, len as usize)))
}
pub fn handle_from_uint16(&mut self, num: u16, len: c_int) -> *const APIHandle {
panic!("Not implemented")
prepare_handle((self.get_mvm().vm.handle_from_uint16(num, len as usize)))
}
pub fn handle_from_sint32(&mut self, num: i32, len: c_int) -> *const APIHandle {
panic!("Not implemented")
prepare_handle((self.get_mvm().vm.handle_from_sint32(num, len as usize)))
}
pub fn handle_from_uint32(&mut self, num: u32, len: c_int) -> *const APIHandle {
panic!("Not implemented")
prepare_handle((self.get_mvm().vm.handle_from_uint32(num, len as usize)))
}
pub fn handle_from_sint64(&mut self, num: i64, len: c_int) -> *const APIHandle {
panic!("Not implemented")
prepare_handle((self.get_mvm().vm.handle_from_sint64(num, len as usize)))
}
pub fn handle_from_uint64(&mut self, num: u64, len: c_int) -> *const APIHandle {
panic!("Not implemented")
prepare_handle((self.get_mvm().vm.handle_from_uint64(num, len as usize)))
}
pub fn handle_from_uint64s(&mut self, nums: &[u64], len: c_int) -> *const APIHandle {
panic!("Not implemented")
panic!("Zebu doesnt implement int with length larger than 64bits")
}
pub fn handle_from_float(&mut self, num: f32) -> *const APIHandle {
panic!("Not implemented")
prepare_handle((self.get_mvm().vm.handle_from_float(num)))
}
pub fn handle_from_double(&mut self, num: f64) -> *const APIHandle {
panic!("Not implemented")
prepare_handle((self.get_mvm().vm.handle_from_double(num)))
}
pub fn handle_from_ptr(&mut self, mu_type: MuID, ptr: CMuCPtr) -> *const APIHandle {
panic!("Not implemented")
let addr = Address::from_mut_ptr(ptr);
prepare_handle((self.get_mvm().vm.handle_from_uptr(mu_type, addr)))
}
pub fn handle_from_fp(&mut self, mu_type: MuID, fp: CMuCFP) -> *const APIHandle {
panic!("Not implemented")
let addr = Address::from_mut_ptr(fp);
prepare_handle((self.get_mvm().vm.handle_from_ufp(mu_type, addr)))
}
pub fn handle_to_sint8(&mut self, opnd: &APIHandle) -> i8 {
panic!("Not implemented")
self.get_mvm().vm.handle_to_sint8(opnd)
}
pub fn handle_to_uint8(&mut self, opnd: &APIHandle) -> u8 {
panic!("Not implemented")
self.get_mvm().vm.handle_to_uint8(opnd)
}
pub fn handle_to_sint16(&mut self, opnd: &APIHandle) -> i16 {
panic!("Not implemented")
self.get_mvm().vm.handle_to_sint16(opnd)
}
pub fn handle_to_uint16(&mut self, opnd: &APIHandle) -> u16 {
panic!("Not implemented")
self.get_mvm().vm.handle_to_uint16(opnd)
}
pub fn handle_to_sint32(&mut self, opnd: &APIHandle) -> i32 {
panic!("Not implemented")
self.get_mvm().vm.handle_to_sint32(opnd)
}
pub fn handle_to_uint32(&mut self, opnd: &APIHandle) -> u32 {
panic!("Not implemented")
self.get_mvm().vm.handle_to_uint32(opnd)
}
pub fn handle_to_sint64(&mut self, opnd: &APIHandle) -> i64 {
panic!("Not implemented")
self.get_mvm().vm.handle_to_sint64(opnd)
}
pub fn handle_to_uint64(&mut self, opnd: &APIHandle) -> u64 {
panic!("Not implemented")
self.get_mvm().vm.handle_to_uint64(opnd)
}
pub fn handle_to_float(&mut self, opnd: &APIHandle) -> f32 {
panic!("Not implemented")
self.get_mvm().vm.handle_to_float(opnd)
}
pub fn handle_to_double(&mut self, opnd: &APIHandle) -> f64 {
panic!("Not implemented")
self.get_mvm().vm.handle_to_double(opnd)
}
pub fn handle_to_ptr(&mut self, opnd: &APIHandle) -> CMuCPtr {
panic!("Not implemented")
self.get_mvm().vm.handle_to_uptr(opnd).to_ptr_mut()
}
pub fn handle_to_fp(&mut self, opnd: &APIHandle) -> CMuCFP {
panic!("Not implemented")
self.get_mvm().vm.handle_to_ufp(opnd).to_ptr_mut()
}
pub fn handle_from_const(&mut self, id: MuID) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_from_const(id))
}
pub fn handle_from_global(&mut self, id: MuID) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_from_global(id))
}
pub fn handle_from_func(&mut self, id: MuID) -> *const APIHandle {
......@@ -170,7 +176,7 @@ impl MuCtx {
}
pub fn delete_value(&mut self, opnd: &APIHandle) {
panic!("Not implemented")
delete_handle(opnd);
}
pub fn ref_eq(&mut self, lhs: &APIHandle, rhs: &APIHandle) -> bool {
......@@ -198,11 +204,11 @@ impl MuCtx {
}
pub fn new_fixed(&mut self, mu_type: MuID) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.new_fixed(mu_type))
}
pub fn new_hybrid(&mut self, mu_type: MuID, length: &APIHandle) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.new_hybrid(mu_type, length))
}
pub fn refcast(&mut self, opnd: &APIHandle, new_type: MuID) -> *const APIHandle {
......@@ -210,11 +216,11 @@ impl MuCtx {
}
pub fn get_iref(&mut self, opnd: &APIHandle) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_get_iref(opnd))
}
pub fn get_field_iref(&mut self, opnd: &APIHandle, field: c_int) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_get_field_iref(opnd, field as usize))
}
pub fn get_elem_iref(&mut self, opnd: &APIHandle, index: &APIHandle) -> *const APIHandle {
......@@ -222,19 +228,19 @@ impl MuCtx {
}
pub fn shift_iref(&mut self, opnd: &APIHandle, offset: &APIHandle) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_shift_iref(opnd, offset))
}
pub fn get_var_part_iref(&mut self, opnd: &APIHandle) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_get_var_part_iref(opnd))
}
pub fn load(&mut self, ord: CMuMemOrd, loc: &APIHandle) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_load(impl_memorder(ord), loc))
}
pub fn store(&mut self, ord: CMuMemOrd, loc: &APIHandle, newval: &APIHandle) {
panic!("Not implemented")
self.get_mvm().vm.handle_store(impl_memorder(ord), loc, newval);
}
pub fn cmpxchg(&mut self, ord_succ: CMuMemOrd, ord_fail: CMuMemOrd, weak: bool, loc: &APIHandle, expected: &APIHandle, desired: &APIHandle, is_succ: *mut CMuBool) -> *const APIHandle {
......@@ -404,3 +410,25 @@ impl MuCtx {
}
}
fn prepare_handle(handle: APIHandleResult) -> *const APIHandle {
Box::into_raw(handle)
}
fn delete_handle(handle: APIHandleArg) {
unsafe {Box::from_raw((handle as *const APIHandle) as *mut APIHandle);}
}
use ast::inst::MemoryOrder;
fn impl_memorder(order: CMuMemOrd) -> MemoryOrder {
match order {
CMU_ORD_NOT_ATOMIC => MemoryOrder::NotAtomic,
CMU_ORD_RELAXED => MemoryOrder::Relaxed,
CMU_ORD_CONSUME => MemoryOrder::Consume,
CMU_ORD_ACQUIRE => MemoryOrder::Acquire,
CMU_ORD_RELEASE => MemoryOrder::Release,
CMU_ORD_ACQ_REL => MemoryOrder::AcqRel,
CMU_ORD_SEQ_CST => MemoryOrder::SeqCst,
_ => panic!("invalid CMuMemOrd flag: {}", order)
}
}
\ No newline at end of file
......@@ -4,7 +4,6 @@ use ast::types::*;
use utils::BitSize;
use utils::Address;
use std::sync::Arc;
pub type APIHandleResult = Box<APIHandle>;
pub type APIHandleArg<'a> = &'a APIHandle;
......@@ -20,8 +19,8 @@ pub enum APIHandleValue {
Int(u64, BitSize),
Float(f32),
Double(f64),
UPtr(Address),
UFP(Address),
UPtr(P<MuType>, Address), // uptr<T>
UFP (P<MuType>, Address), // ufuncptr<sig>
// SeqValue
Struct(Vec<APIHandleValue>),
......@@ -48,7 +47,6 @@ pub enum APIHandleValue {
Inst,
// GenRef->IR->Child->Var->Global
Const,
Global(MuID),
Func,
ExpFunc,
......@@ -80,4 +78,32 @@ impl APIHandleValue {
_ => panic!("expected Int handle")
}
}
pub fn as_float(&self) -> f32 {
match self {
&APIHandleValue::Float(val) => val,
_ => panic!("expected Float handle")
}
}
pub fn as_double(&self) -> f64 {
match self {
&APIHandleValue::Double(val) => val,
_ => panic!("expected Double handle")
}
}
pub fn as_uptr(&self) -> (P<MuType>, Address) {
match self {
&APIHandleValue::UPtr(ref ty, addr) => (ty.clone(), addr),
_ => panic!("expected UPtr handle")
}
}
pub fn as_ufp(&self) -> (P<MuType>, Address) {
match self {
&APIHandleValue::UFP(ref ty, addr) => (ty.clone(), addr),
_ => panic!("expected UFP handle")
}
}
}
\ No newline at end of file
......@@ -380,6 +380,22 @@ impl Decodable for VM {
}
}
macro_rules! gen_handle_int {
($fn_from: ident, $fn_to: ident, $int_ty: ty) => {
pub fn $fn_from (&self, num: $int_ty, len: BitSize) -> APIHandleResult {
let handle_id = self.next_id();
self.new_handle (APIHandle {
id: handle_id,
v: APIHandleValue::Int(num as u64, len)
})
}
pub fn $fn_to (&self, handle: APIHandleArg) -> $int_ty {
handle.v.as_int() as $int_ty
}
}
}
impl <'a> VM {
pub fn new() -> VM {
VM::new_internal(VMOptions::default())
......@@ -436,18 +452,18 @@ impl <'a> VM {
// synchronise at the time of inter-thread communication, rather than creation of the VM.
ret.next_id.store(USER_ID_START, Ordering::Relaxed);
ret.init_vm();
// init types
types::init_types();
ret.init_runtime();
ret
}
fn init_vm(&self) {
fn init_runtime(&self) {
// init log
VM::start_logging(self.vm_options.flag_log_level);
// init types
types::init_types();
// init gc
{
let ref options = self.vm_options;
......@@ -484,7 +500,7 @@ impl <'a> VM {
let vm : VM = json::decode(serialized_vm).unwrap();
vm.init_vm();
vm.init_runtime();
// restore gc types
{
......@@ -942,6 +958,29 @@ impl <'a> VM {
})
}
pub fn handle_load(&self, ord: MemoryOrder, loc: APIHandleArg) -> APIHandleResult {
let (ty, addr) = loc.v.as_iref();
let handle_id = self.next_id();
let handle_value = {
match ty.v {
MuType_::Int(len) => APIHandleValue::Int(unsafe {addr.load::<u64>()}, len),
MuType_::Float => APIHandleValue::Float(unsafe {addr.load::<f32>()}),
MuType_::Double => APIHandleValue::Double(unsafe {addr.load::<f64>()}),
MuType_::Ref(ref ty) => APIHandleValue::Ref(ty.clone(), unsafe {addr.load::<Address>()}),
MuType_::IRef(ref ty) => APIHandleValue::IRef(ty.clone(), unsafe {addr.load::<Address>()}),
MuType_::UPtr(ref ty) => APIHandleValue::UPtr(ty.clone(), unsafe {addr.load::<Address>()}),
_ => unimplemented!()
}
};
self.new_handle(APIHandle {
id: handle_id,
v : handle_value
})
}
pub fn handle_store(&self, ord: MemoryOrder, loc: APIHandleArg, val: APIHandleArg) {
// FIXME: take memory order into consideration
......@@ -963,8 +1002,8 @@ impl <'a> VM {
},
APIHandleValue::Float(fval) => addr.store::<f32>(fval),
APIHandleValue::Double(fval) => addr.store::<f64>(fval),
APIHandleValue::UPtr(aval) => addr.store::<Address>(aval),
APIHandleValue::UFP(aval) => addr.store::<Address>(aval),
APIHandleValue::UPtr(_, aval) => addr.store::<Address>(aval),
APIHandleValue::UFP(_, aval) => addr.store::<Address>(aval),
APIHandleValue::Struct(_)
| APIHandleValue::Array(_)
......@@ -997,16 +1036,109 @@ impl <'a> VM {
})
}
pub fn handle_from_uint64(&self, num: u64, len: BitSize) -> APIHandleResult {
pub fn handle_from_const(&self, id: MuID) -> APIHandleResult {
let constant = {
let lock = self.constants.read().unwrap();
lock.get(&id).unwrap().clone()
};
let ref const_ty = constant.ty;
let handle_id = self.next_id();
let handle = match constant.v {
Value_::Constant(Constant::Int(val)) => {
let len = match const_ty.get_int_length() {
Some(len) => len,
None => panic!("expected ty to be Int for a Constant::Int, found {}", const_ty)
};
APIHandle {
id: handle_id,
v : APIHandleValue::Int(val, len)
}
}
Value_::Constant(Constant::Float(val)) => {
APIHandle {
id: handle_id,
v : APIHandleValue::Float(val)
}
}
Value_::Constant(Constant::Double(val)) => {
APIHandle {
id: handle_id,
v : APIHandleValue::Double(val)
}
}
Value_::Constant(Constant::FuncRef(id)) => {
unimplemented!()
}
Value_::Constant(Constant::NullRef) => {
unimplemented!()
}
_ => unimplemented!()
};
self.new_handle(APIHandle {
self.new_handle(handle)
}
gen_handle_int!(handle_from_uint64, handle_to_uint64, u64);
gen_handle_int!(handle_from_uint32, handle_to_uint32, u32);
gen_handle_int!(handle_from_uint16, handle_to_uint16, u16);
gen_handle_int!(handle_from_uint8 , handle_to_uint8 , u8 );
gen_handle_int!(handle_from_sint64, handle_to_sint64, i64);
gen_handle_int!(handle_from_sint32, handle_to_sint32, i32);
gen_handle_int!(handle_from_sint16, handle_to_sint16, i16);
gen_handle_int!(handle_from_sint8 , handle_to_sint8 , i8 );
pub fn handle_from_float(&self, num: f32) -> APIHandleResult {
let handle_id = self.next_id();
self.new_handle (APIHandle {
id: handle_id,
v : APIHandleValue::Int(num, len)
v: APIHandleValue::Float(num)
})
}
pub fn handle_to_uint64(&self, handle: APIHandleArg) -> u64 {
handle.v.as_int()
pub fn handle_to_float (&self, handle: APIHandleArg) -> f32 {
handle.v.as_float()
}
}
pub fn handle_from_double(&self, num: f64) -> APIHandleResult {
let handle_id = self.next_id();
self.new_handle (APIHandle {
id: handle_id,
v: APIHandleValue::Double(num)
})
}
pub fn handle_to_double (&self, handle: APIHandleArg) -> f64 {
handle.v.as_double()
}
pub fn handle_from_uptr(&self, tyid: MuID, ptr: Address) -> APIHandleResult {
let ty = self.get_type(tyid);
let handle_id = self.next_id();
self.new_handle (APIHandle {
id: handle_id,
v : APIHandleValue::UPtr(ty, ptr)
})
}
pub fn handle_to_uptr(&self, handle: APIHandleArg) -> Address {
handle.v.as_uptr().1
}
pub fn handle_from_ufp(&self, tyid: MuID, ptr: Address) -> APIHandleResult {
let ty = self.get_type(tyid);
let handle_id = self.next_id();
self.new_handle (APIHandle {
id: handle_id,
v : APIHandleValue::UFP(ty, ptr)
})
}
pub fn handle_to_ufp(&self, handle: APIHandleArg) -> Address {
handle.v.as_ufp().1
}
}
\ No newline at end of file
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