use super::*;
pub type EnvError = mtk::Error;
pub struct Env {
mem: Vec<Option<Vec<i128>>>,
routines: Vec<Routine>
}
impl Env {
pub fn new() -> Env {
Env {
mem: vec![Some(vec![0x0; 0])],
routines: Vec::new()
}
}
pub fn alloc(&mut self, size: usize) -> Result<usize, EnvError> {
if size <= 0 {
return Err(EnvError::from(format!("size should be atleast 1")));
}
self.mem.push(Some(vec![0x0; size]));
Ok(self.mem.len() - 1)
}
pub fn dealloc(&mut self, addr: usize) -> Result<usize, EnvError> {
match self.mem.get_mut(addr) {
Some(some) => {
if *some == None {
Err(EnvError::from(format!("address {} is already deallocated", addr)))
} else {
let size = match some {
Some(some) => some.len(),
None => 0
};
*some = None;
Ok(size)
}
},
None => Err(EnvError::from(format!("nothing allocated on address {}", addr)))
}
}
pub fn def(&mut self, data: Vec<i128>) -> Result<usize, EnvError> {
let routine = Routine::from(self, data);
self.routines.push(routine.clone());
Ok(self.routines.len() - 1)
}
pub unsafe fn call(&mut self, index: usize, argv: Vec<usize>) -> Result<Result<usize, usize>, CallError> {
match self.routines.get_mut(index) {
Some(some) => some.call(argv),
None => Err(CallError::from(format!("could not get the routine at index {}", index)))
}
}
pub fn get_mem(&self) -> &Vec<Option<Vec<i128>>> {
&self.mem
}
pub fn get_mem_mut(&mut self) -> &mut Vec<Option<Vec<i128>>> {
&mut self.mem
}
}