address.rs 4.7 KB
Newer Older
qinsoon's avatar
qinsoon committed
1 2
#![allow(dead_code)]

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
use std::cmp;
use std::fmt;
use std::mem;

#[repr(C)]
#[derive(Copy, Clone, Eq, Hash)]
pub struct Address(usize);

impl Address {
    #[inline(always)]
    pub fn plus(&self, bytes: usize) -> Self {
        Address(self.0 + bytes)
    }
    #[inline(always)]
    pub fn sub(&self, bytes: usize) -> Self {
        Address(self.0 - bytes)
    }
    #[inline(always)]
qinsoon's avatar
qinsoon committed
21 22 23 24 25
    pub fn offset(&self, offset: isize) -> Self {
        Address((self.0 as isize + offset) as usize)
    }
    #[inline(always)]
    pub fn shift<T>(&self, offset: isize) -> Self {
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
        Address((self.0 as isize + mem::size_of::<T>() as isize * offset) as usize)
    }
    #[inline(always)]
    pub fn diff(&self, another: Address) -> usize {
        debug_assert!(self.0 >= another.0, "for a.diff(b), a needs to be larger than b");
        self.0 - another.0
    }
    
    #[inline(always)]
    pub unsafe fn load<T: Copy> (&self) -> T {
        *(self.0 as *mut T)
    }
    #[inline(always)]
    pub unsafe fn store<T> (&self, value: T) {
        *(self.0 as *mut T) = value;
    }
    #[inline(always)]
    pub fn is_zero(&self) -> bool {
        self.0 == 0
    }
    #[inline(always)]
    pub fn align_up(&self, align: usize) -> Address {
        Address((self.0 + align - 1) & !(align - 1))
    }
    
    pub fn is_aligned_to(&self, align: usize) -> bool {
        self.0 % align == 0
    }
    
    pub fn memset(&self, char: u8, length: usize) {
        let mut cur : *mut u8 = self.0 as *mut u8;
        for _ in 0..length {
            unsafe {
                *cur = char;
                cur = cur.offset(1);
            }
        }
    }
    
    #[inline(always)]
    pub unsafe fn to_object_reference(&self) -> ObjectReference {
        mem::transmute(self.0)
    }
    #[inline(always)]
    pub fn from_ptr<T> (ptr: *const T) -> Address {
        unsafe {mem::transmute(ptr)}
    }
    #[inline(always)]
74 75 76 77
    pub fn from_mut_ptr<T> (ptr: *mut T) -> Address {
        unsafe {mem::transmute(ptr)}
    }
    #[inline(always)]
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
    pub fn to_ptr<T> (&self) -> *const T {
        unsafe {mem::transmute(self.0)}
    }
    #[inline(always)]
    pub fn to_ptr_mut<T> (&self) -> *mut T {
        unsafe {mem::transmute(self.0)}
    }
    #[inline(always)]
    pub fn as_usize(&self) -> usize {
        self.0
    }
    #[inline(always)]
    pub unsafe fn zero() -> Address {
        Address(0)
    }
93 94 95 96 97
    #[inline(always)]
    pub unsafe fn max() -> Address {
        use std::usize;
        Address(usize::MAX)
    }
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
}

impl PartialOrd for Address {
    #[inline(always)]
    fn partial_cmp(&self, other: &Address) -> Option<cmp::Ordering> {
        Some(self.0.cmp(& other.0))
    }
}

impl PartialEq for Address {
    #[inline(always)]
    fn eq(&self, other: &Address) -> bool {
        self.0 == other.0
    }
    #[inline(always)]
    fn ne(&self, other: &Address) -> bool {
        self.0 != other.0
    }
}

impl fmt::UpperHex for Address {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:X}", self.0) 
    }
}

124 125 126 127 128 129
impl fmt::LowerHex for Address {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:x}", self.0) 
    }
}

130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
impl fmt::Display for Address {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "0x{:X}", self.0)
    }
}

impl fmt::Debug for Address {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "0x{:X}", self.0)
    }
}

#[derive(Copy, Clone, Eq, Hash)]
pub struct ObjectReference (usize);

impl ObjectReference {
    #[inline(always)]
    pub fn to_address(&self) -> Address {
        unsafe {mem::transmute(self.0)}
    }
    #[inline(always)]
    pub fn is_null(&self) -> bool {
        self.0 != 0
    }
    pub fn value(&self) -> usize {
        self.0
    }
}

impl PartialOrd for ObjectReference {
    #[inline(always)]
    fn partial_cmp(&self, other: &ObjectReference) -> Option<cmp::Ordering> {
        Some(self.0.cmp(& other.0))
    }
}

impl PartialEq for ObjectReference {
    #[inline(always)]
    fn eq(&self, other: &ObjectReference) -> bool {
        self.0 == other.0
    }
    #[inline(always)]
    fn ne(&self, other: &ObjectReference) -> bool {
        self.0 != other.0
    }
}

impl fmt::UpperHex for ObjectReference {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:X}", self.0) 
    }
}

183 184 185 186 187 188
impl fmt::LowerHex for ObjectReference {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:x}", self.0) 
    }
}

189 190 191 192 193 194 195 196 197 198
impl fmt::Display for ObjectReference {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "0x{:X}", self.0)
    }
}

impl fmt::Debug for ObjectReference {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "0x{:X}", self.0)
    }
199
}