wasmi/src/common/stack.rs

102 lines
2.2 KiB
Rust
Raw Normal View History

#[allow(unused_imports)]
2019-04-09 16:24:45 +00:00
use crate::alloc::prelude::v1::*;
2018-01-17 15:32:33 +00:00
2018-12-11 11:54:06 +00:00
use core::fmt;
#[cfg(feature = "std")]
2018-01-17 15:32:33 +00:00
use std::error;
#[derive(Debug)]
pub struct Error(String);
impl fmt::Display for Error {
2018-12-11 11:54:06 +00:00
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
2018-01-17 15:32:33 +00:00
}
#[cfg(feature = "std")]
2018-01-17 15:32:33 +00:00
impl error::Error for Error {
2018-12-11 11:54:06 +00:00
fn description(&self) -> &str {
&self.0
}
2018-01-17 15:32:33 +00:00
}
/// Stack with limit.
#[derive(Debug)]
2018-12-11 11:54:06 +00:00
pub struct StackWithLimit<T>
where
T: Clone,
{
/// Stack values.
values: Vec<T>,
/// Stack limit (maximal stack len).
limit: usize,
2018-01-17 15:32:33 +00:00
}
2018-12-11 11:54:06 +00:00
impl<T> StackWithLimit<T>
where
T: Clone,
{
pub fn with_limit(limit: usize) -> Self {
StackWithLimit {
values: Vec::new(),
limit: limit,
}
}
pub fn is_empty(&self) -> bool {
self.values.is_empty()
}
pub fn len(&self) -> usize {
self.values.len()
}
pub fn top(&self) -> Result<&T, Error> {
self.values
.last()
.ok_or_else(|| Error("non-empty stack expected".into()))
}
pub fn top_mut(&mut self) -> Result<&mut T, Error> {
self.values
.last_mut()
.ok_or_else(|| Error("non-empty stack expected".into()))
}
pub fn get(&self, index: usize) -> Result<&T, Error> {
if index >= self.values.len() {
return Err(Error(format!(
"trying to get value at position {} on stack of size {}",
index,
self.values.len()
)));
}
Ok(self
.values
.get(self.values.len() - 1 - index)
.expect("checked couple of lines above"))
}
pub fn push(&mut self, value: T) -> Result<(), Error> {
if self.values.len() >= self.limit {
return Err(Error(format!("exceeded stack limit {}", self.limit)));
}
self.values.push(value);
Ok(())
}
pub fn pop(&mut self) -> Result<T, Error> {
self.values
.pop()
.ok_or_else(|| Error("non-empty stack expected".into()))
}
pub fn resize(&mut self, new_size: usize, dummy: T) {
debug_assert!(new_size <= self.values.len());
self.values.resize(new_size, dummy);
}
2018-01-17 15:32:33 +00:00
}