use alloc;
use core::cell::UnsafeCell;
use core::mem::{size_of,align_of,transmute};
use core::ptr;
use collections::Vec;
extern "C" { fn usercall(nr: u64, p1: u64, p2: u64, _ignore: u64, p3: u64, p4: u64) -> u64; }
pub unsafe fn do_usercall(nr: u64, p1: u64, p2: u64, p3: u64, p4: u64) -> u64 {
if nr==0 || nr>=0x8000_0000_0000_0000 { panic!("Invalid usercall number {}",nr) }
usercall(nr,p1,p2,0,p3,p4)
}
pub use alloc::init_user as init_user_heap;
pub struct UserBox<T: Copy>(*mut T);
impl<T: Copy> UserBox<T> {
pub fn new(val: T) -> UserBox<T> {
unsafe {
let p=alloc::USER_HEAP.lock().as_mut().expect("Trying to allocate on unintialized heap")
.allocate(size_of::<T>(),align_of::<T>()) as *mut T;
assert!(p != ptr::null_mut());
ptr::write(p,val);
UserBox(p)
}
}
pub unsafe fn as_ptr(&self) -> *const T {
self.0 as *const T
}
pub fn to_enclave(&self) -> T {
unsafe{ptr::read(self.0)}
}
}
impl<T: Copy> Drop for UserBox<T> {
fn drop(&mut self) {
unsafe{alloc::USER_HEAP.lock().as_mut().unwrap()
.deallocate(self.0 as *mut u8,size_of::<T>(),align_of::<T>())};
}
}
pub struct UserSlice<T: Copy> {
data: *mut T,
len: usize,
}
impl<T: Copy> UserSlice<T> {
pub fn clone_from(val: &[T]) -> UserSlice<T> {
let ret=Self::new_uninit(val.len());
unsafe{ptr::copy(val.as_ptr(),ret.data,val.len())};
ret
}
pub fn new_uninit(len: usize) -> UserSlice<T> {
unsafe {
let p=alloc::USER_HEAP.lock().as_mut().expect("Trying to allocate on unintialized heap")
.allocate(size_of::<T>()*len,align_of::<T>()) as *mut T;
assert!(p != ptr::null_mut());
UserSlice{data:p,len:len}
}
}
fn as_unsafe_cell(&self) -> &UnsafeCell<[T]> {
use core::slice::from_raw_parts;
unsafe{transmute::<&[T],&UnsafeCell<[T]>>(from_raw_parts(self.data,self.len))}
}
pub unsafe fn as_ptr(&self) -> *const T {
self.data
}
pub fn len(&self) -> usize {
self.len
}
pub fn clone_into_enclave(&self,dst: &mut [T]) {
assert!(dst.len()<=self.len());
let len=::core::cmp::min(dst.len(),self.len());
(&mut dst[..len]).clone_from_slice(&unsafe{&*self.as_unsafe_cell().get()}[..len]);
}
pub fn to_enclave_vec(&self) -> Vec<T> {
unsafe{&*self.as_unsafe_cell().get()}.to_vec()
}
}
impl<T: Copy> Drop for UserSlice<T> {
fn drop(&mut self) {
unsafe{alloc::USER_HEAP.lock().as_mut().unwrap()
.deallocate(self.data as *mut u8,size_of::<T>()*self.len,align_of::<T>())};
}
}