xwasmi_validation/
stack.rs1#[allow(unused_imports)]
2use alloc::prelude::v1::*;
3
4use core::fmt;
5#[cfg(feature = "std")]
6use std::error;
7
8#[derive(Debug)]
9pub struct Error(String);
10
11impl fmt::Display for Error {
12 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
13 write!(f, "{}", self.0)
14 }
15}
16
17#[cfg(feature = "std")]
18impl error::Error for Error {
19 fn description(&self) -> &str {
20 &self.0
21 }
22}
23
24#[derive(Debug)]
26pub struct StackWithLimit<T>
27where
28 T: Clone,
29{
30 values: Vec<T>,
32 limit: usize,
34}
35
36impl<T> StackWithLimit<T>
37where
38 T: Clone,
39{
40 pub fn with_limit(limit: usize) -> Self {
41 StackWithLimit {
42 values: Vec::new(),
43 limit: limit,
44 }
45 }
46
47 pub fn is_empty(&self) -> bool {
48 self.values.is_empty()
49 }
50
51 pub fn len(&self) -> usize {
52 self.values.len()
53 }
54
55 pub fn top(&self) -> Result<&T, Error> {
56 self.values
57 .last()
58 .ok_or_else(|| Error("non-empty stack expected".into()))
59 }
60
61 pub fn top_mut(&mut self) -> Result<&mut T, Error> {
62 self.values
63 .last_mut()
64 .ok_or_else(|| Error("non-empty stack expected".into()))
65 }
66
67 pub fn get(&self, index: usize) -> Result<&T, Error> {
68 if index >= self.values.len() {
69 return Err(Error(format!(
70 "trying to get value at position {} on stack of size {}",
71 index,
72 self.values.len()
73 )));
74 }
75
76 Ok(self
77 .values
78 .get(self.values.len() - 1 - index)
79 .expect("checked couple of lines above"))
80 }
81
82 pub fn push(&mut self, value: T) -> Result<(), Error> {
83 if self.values.len() >= self.limit {
84 return Err(Error(format!("exceeded stack limit {}", self.limit)));
85 }
86
87 self.values.push(value);
88 Ok(())
89 }
90
91 pub fn pop(&mut self) -> Result<T, Error> {
92 self.values
93 .pop()
94 .ok_or_else(|| Error("non-empty stack expected".into()))
95 }
96
97 pub fn resize(&mut self, new_size: usize, dummy: T) {
98 debug_assert!(new_size <= self.values.len());
99 self.values.resize(new_size, dummy);
100 }
101}