cfx_vm_interpreter/interpreter/
stack.rs1use super::instructions;
22use std::fmt;
23
24pub trait Stack<T> {
26 fn peek(&self, no_from_top: usize) -> &T;
28 fn swap_with_top(&mut self, no_from_top: usize);
30 fn has(&self, no_of_elems: usize) -> bool;
32 fn pop_back(&mut self) -> T;
34 fn pop_n(&mut self, no_of_elems: usize) -> &[T];
37 fn push(&mut self, elem: T);
39 fn size(&self) -> usize;
41 #[allow(dead_code)]
43 fn peek_top(&self, no_of_elems: usize) -> &[T];
44}
45
46pub struct VecStack<S> {
47 stack: Vec<S>,
48 logs: [S; instructions::MAX_NO_OF_TOPICS],
49}
50
51impl<S: Copy> VecStack<S> {
52 pub fn with_capacity(capacity: usize, zero: S) -> Self {
53 VecStack {
54 stack: Vec::with_capacity(capacity),
55 logs: [zero; instructions::MAX_NO_OF_TOPICS],
56 }
57 }
58
59 pub fn content(&self) -> &Vec<S> { &self.stack }
60}
61
62impl<S: fmt::Display> Stack<S> for VecStack<S> {
63 fn peek(&self, no_from_top: usize) -> &S {
64 &self.stack[self.stack.len() - no_from_top - 1]
65 }
66
67 fn swap_with_top(&mut self, no_from_top: usize) {
68 let len = self.stack.len();
69 self.stack.swap(len - no_from_top - 1, len - 1);
70 }
71
72 fn has(&self, no_of_elems: usize) -> bool {
73 self.stack.len() >= no_of_elems
74 }
75
76 fn pop_back(&mut self) -> S {
77 self.stack.pop().expect(
78 "instruction validation prevents from popping too many items; qed",
79 )
80 }
81
82 fn pop_n(&mut self, no_of_elems: usize) -> &[S] {
83 assert!(no_of_elems <= instructions::MAX_NO_OF_TOPICS);
84
85 for i in 0..no_of_elems {
86 self.logs[i] = self.pop_back();
87 }
88 &self.logs[0..no_of_elems]
89 }
90
91 fn push(&mut self, elem: S) { self.stack.push(elem); }
92
93 fn size(&self) -> usize { self.stack.len() }
94
95 fn peek_top(&self, no_from_top: usize) -> &[S] {
96 assert!(
97 self.stack.len() >= no_from_top,
98 "peek_top asked for more items than exist."
99 );
100 &self.stack[self.stack.len() - no_from_top..self.stack.len()]
101 }
102}