ttvm 0.3.5

Runtime and compiler infrastructure API for Rust
Documentation
use super::*;

pub type MemError = mtk::Error;

pub const NULL: IPtr = 0;

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Mem {
    mem: Vec<Option<Box<[Byte]>>>
}

impl Mem {
    pub fn new() -> Mem {
        Mem {
            mem: vec![Some(vec![0; 0].into_boxed_slice())]
        }
    }

    pub fn alloc(&mut self, size: usize) -> Result<usize, MemError> {
        self.mem.push(Some(vec![0x0; size].into_boxed_slice()));

        Ok(self.mem.len() - 1)
    }

    pub fn dealloc(&mut self, addr: usize) -> Result<usize, MemError> {
        match self.mem.get_mut(addr) {
            Some(some) => {
                let size = match some {
                    Some(some) => some.len(),
                    None => return Err(MemError::from(format!("address {} is not allocated", addr)))
                };

                *some = None;

                Ok(size)
            },
            None => Err(MemError::from(format!("address {} is not allocated", addr)))
        }
    }

    pub fn get_mut(&mut self, addr: usize) -> Result<&mut Box<[Byte]>, MemError> {
        match self.mem.get_mut(addr) {
            Some(some) => {
                match some {
                    Some(some) => Ok(some),
                    None => Err(MemError::from(format!("address {} is not allocated", addr)))
                }
            },
            None => Err(MemError::from(format!("address {} is not allocated", addr)))
        }
    }

    pub fn get(&self, addr: usize) -> Result<&Box<[Byte]>, MemError> {
        match self.mem.get(addr) {
            Some(some) => Ok(match some {
                Some(some) => some,
                None => return Err(MemError::from(format!("address {} is not allocated", addr)))
            }),
            None => Err(MemError::from(format!("address {} is not allocated", addr)))
        }
    }
    
    pub fn size(&self) -> usize {
        self.mem.len()
    }
}

pub mod raw {
    use super::*;

    pub fn malloc(mem: &mut Mem, size: usize) -> usize {
        match mem.alloc(size) {
            Ok(ok) => ok,
            Err(_) => NULL as RPtr
        }
    }
    
    pub fn calloc(mem: &mut Mem, size: usize, block_size: usize) -> usize {
        match mem.alloc(size * block_size) {
            Ok(ok) => ok,
            Err(_) => NULL as RPtr
        }
    }
    
    pub fn realloc(mem: &mut Mem, addr: usize, size: usize) -> usize {
        let copy = match mem.get(addr) {
            Ok(some) => some.clone(),
            Err(_) => return NULL as RPtr
        };
    
        match mem.dealloc(addr) {
            Ok(_) => {
                let new_addr = match mem.alloc(size) {
                    Ok(ok) => ok,
                    Err(_) => return NULL as RPtr
                };
    
                match mem.get_mut(new_addr) {
                    Ok(some) => {
                        for i in 0..copy.len() {
                            *match some.get_mut(i) {
                                Some(some) => some,
                                None => break
                            } = match copy.get(i) {
                                Some(some) => *some,
                                None => return NULL as RPtr
                            };
                        }
    
                        new_addr
                    },
                    Err(_) => NULL as RPtr
                }
            },
            Err(_) => NULL as RPtr
        }
    }
    
    pub fn free(mem: &mut Mem, addr: usize) -> usize {
        match mem.dealloc(addr) {
            Ok(ok) => ok,
            Err(_) => NULL as RPtr
        }
    }
}

pub use raw as c;