use super::ffi;
use mtk::result;
pub const MEMSTACK_LIMIT: usize = usize::MAX;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct MemStack {
inner: Vec<Option<Vec<ffi::Byte>>>,
}
impl MemStack {
pub fn new() -> Self {
MemStack { inner: Vec::new() }
}
pub fn alloc(&mut self, size: usize) -> result::Result<ffi::Ref> {
if self.inner.len() + 1 >= MEMSTACK_LIMIT {
result::Error::quick(format!(
"self.inner.len() ({}) + 1 >= MEMSTACK_LIMIT ({})",
self.inner.len(),
MEMSTACK_LIMIT
))
} else {
self.inner.push(Some(vec![0; size]));
Ok((self.inner.len() - 1) as ffi::Ref)
}
}
pub fn dealloc(&mut self, mem_ref: ffi::Ref) -> result::Result<usize> {
match self.inner.get_mut(mem_ref as usize) {
Some(some) => {
let mem_raw = match some {
Some(some) => some,
None => {
return result::Error::quick(format!(
"memory {} is already deallocated",
mem_ref
))
}
};
let len = mem_raw.len();
*some = None;
Ok(len)
}
None => result::Error::quick(format!("can not access to memory {}", mem_ref)),
}
}
pub fn get(&self, mem_ref: ffi::Ref) -> result::Result<&Vec<ffi::Byte>> {
match self.inner.get(mem_ref as usize) {
Some(some) => match some {
Some(some) => Ok(some),
None => result::Error::quick(format!("can not access to {}", mem_ref)),
},
None => result::Error::quick(format!("can not access to memory {}", mem_ref)),
}
}
pub fn get_mut(&mut self, mem_ref: ffi::Ref) -> result::Result<&mut Vec<ffi::Byte>> {
match self.inner.get_mut(mem_ref as usize) {
Some(some) => match some {
Some(some) => Ok(some),
None => result::Error::quick(format!("can not access to {}", mem_ref)),
},
None => result::Error::quick(format!("can not access to memory {}", mem_ref)),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct ByteStack {
inner: Vec<ffi::Byte>,
}
impl ByteStack {
pub fn new() -> Self {
ByteStack { inner: Vec::new() }
}
pub fn push(&mut self, byte: ffi::Byte) {
self.inner.push(byte)
}
pub fn pop(&mut self) -> Option<ffi::Byte> {
self.inner.pop()
}
}