revm_interpreter/interpreter/
stack.rs1use super::StackTr;
2use crate::InstructionResult;
3use core::fmt;
4use primitives::{hints_util::cold_path, U256};
5use std::vec::Vec;
6
7pub const STACK_LIMIT: usize = 1024;
9
10#[derive(Debug, PartialEq, Eq, Hash)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize))]
13pub struct Stack {
14 data: Vec<U256>,
16}
17
18impl fmt::Display for Stack {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 f.write_str("[")?;
21 for (i, x) in self.data.iter().enumerate() {
22 if i > 0 {
23 f.write_str(", ")?;
24 }
25 write!(f, "{x}")?;
26 }
27 f.write_str("]")
28 }
29}
30
31impl Default for Stack {
32 #[inline]
33 fn default() -> Self {
34 Self::new()
35 }
36}
37
38impl Clone for Stack {
39 fn clone(&self) -> Self {
40 let mut new_stack = Self::new();
44 new_stack.data.extend_from_slice(&self.data);
45 new_stack
46 }
47}
48
49impl StackTr for Stack {
50 #[inline]
51 fn len(&self) -> usize {
52 self.len()
53 }
54
55 #[inline]
56 fn data(&self) -> &[U256] {
57 &self.data
58 }
59
60 #[inline]
61 fn clear(&mut self) {
62 self.data.clear();
63 }
64
65 #[inline]
66 fn popn<const N: usize>(&mut self) -> Option<[U256; N]> {
67 self.popn()
68 }
69
70 #[inline]
71 fn popn_top<const POPN: usize>(&mut self) -> Option<([U256; POPN], &mut U256)> {
72 self.popn_top()
73 }
74
75 #[inline]
76 fn exchange(&mut self, n: usize, m: usize) -> bool {
77 self.exchange(n, m)
78 }
79
80 #[inline]
81 fn dup(&mut self, n: usize) -> bool {
82 self.dup(n)
83 }
84
85 #[inline]
86 fn push(&mut self, value: U256) -> bool {
87 self.push(value)
88 }
89
90 #[inline]
91 fn push_slice(&mut self, slice: &[u8]) -> bool {
92 self.push_slice_(slice)
93 }
94}
95
96impl Stack {
97 #[inline]
99 pub fn new() -> Self {
100 Self {
101 data: Vec::with_capacity(STACK_LIMIT),
103 }
104 }
105
106 #[inline]
108 pub const fn invalid() -> Self {
109 Self { data: Vec::new() }
110 }
111
112 #[inline]
114 pub const fn len(&self) -> usize {
115 self.data.len()
116 }
117
118 #[inline]
120 pub const fn is_empty(&self) -> bool {
121 self.data.is_empty()
122 }
123
124 #[inline]
126 pub const fn data(&self) -> &Vec<U256> {
127 &self.data
128 }
129
130 #[inline]
132 pub const fn data_mut(&mut self) -> &mut Vec<U256> {
133 &mut self.data
134 }
135
136 #[inline]
138 pub fn into_data(self) -> Vec<U256> {
139 self.data
140 }
141
142 #[inline]
145 #[cfg_attr(debug_assertions, track_caller)]
146 pub fn pop(&mut self) -> Result<U256, InstructionResult> {
147 self.data.pop().ok_or(InstructionResult::StackUnderflow)
148 }
149
150 #[inline]
156 #[cfg_attr(debug_assertions, track_caller)]
157 pub unsafe fn pop_unchecked(&mut self) -> U256 {
158 assume!(!self.is_empty());
159 self.data.pop().unwrap_unchecked()
160 }
161
162 #[inline]
164 pub fn top(&mut self) -> Option<&mut U256> {
165 self.data.last_mut()
166 }
167
168 #[inline]
174 #[cfg_attr(debug_assertions, track_caller)]
175 pub unsafe fn top_unchecked(&mut self) -> &mut U256 {
176 assume!(!self.is_empty());
177 self.data.last_mut().unwrap_unchecked()
178 }
179
180 #[inline]
182 pub fn popn<const N: usize>(&mut self) -> Option<[U256; N]> {
183 if self.len() < N {
184 return None;
185 }
186 Some(unsafe { self.popn_unchecked() })
188 }
189
190 #[inline]
196 #[cfg_attr(debug_assertions, track_caller)]
197 pub unsafe fn popn_unchecked<const N: usize>(&mut self) -> [U256; N] {
198 assume!(self.len() >= N);
199 core::array::from_fn(|_| unsafe { self.pop_unchecked() })
200 }
201
202 #[inline]
204 #[cfg_attr(debug_assertions, track_caller)]
205 pub fn popn_top<const N: usize>(&mut self) -> Option<([U256; N], &mut U256)> {
206 if self.len() < N + 1 {
207 return None;
208 }
209 Some(unsafe { self.popn_top_unchecked() })
211 }
212
213 #[inline]
219 #[cfg_attr(debug_assertions, track_caller)]
220 pub unsafe fn popn_top_unchecked<const N: usize>(&mut self) -> ([U256; N], &mut U256) {
221 unsafe { (self.popn_unchecked(), self.top_unchecked()) }
222 }
223
224 #[inline]
229 #[must_use]
230 #[cfg_attr(debug_assertions, track_caller)]
231 pub fn push(&mut self, value: U256) -> bool {
232 debug_assert!(self.data.capacity() >= STACK_LIMIT);
234 let len = self.len();
235 if len == STACK_LIMIT {
236 cold_path();
237 return false;
238 }
239 unsafe {
240 let end = self.data.as_mut_ptr().add(len);
241 core::ptr::write(end, value);
242 self.data.set_len(len + 1);
243 }
244 true
245 }
246
247 #[inline]
251 pub fn peek(&self, no_from_top: usize) -> Result<U256, InstructionResult> {
252 if self.data.len() > no_from_top {
253 Ok(self.data[self.data.len() - no_from_top - 1])
254 } else {
255 cold_path();
256 Err(InstructionResult::StackUnderflow)
257 }
258 }
259
260 #[inline]
266 #[must_use]
267 #[cfg_attr(debug_assertions, track_caller)]
268 pub fn dup(&mut self, n: usize) -> bool {
269 assume!(n > 0, "attempted to dup 0");
270 let len = self.len();
271 if (len < n) | (len + 1 > STACK_LIMIT) {
272 cold_path();
273 return false;
274 }
275 unsafe {
277 let ptr = self.data.as_mut_ptr().add(len);
278 *ptr = *ptr.sub(n);
279 self.data.set_len(len + 1);
280 }
281 true
282 }
283
284 #[inline(always)]
290 #[cfg_attr(debug_assertions, track_caller)]
291 pub fn swap(&mut self, n: usize) -> bool {
292 self.exchange(0, n)
293 }
294
295 #[inline]
303 #[cfg_attr(debug_assertions, track_caller)]
304 pub fn exchange(&mut self, n: usize, m: usize) -> bool {
305 assume!(m > 0, "overlapping exchange");
306 let len = self.len();
307 let n_m_index = n + m;
308 if n_m_index >= len {
309 cold_path();
310 return false;
311 }
312 unsafe {
314 let top = self.data.as_mut_ptr().add(len - 1);
319 core::ptr::swap_nonoverlapping(top.sub(n), top.sub(n_m_index), 1);
320 }
321 true
322 }
323
324 #[inline]
327 pub fn push_slice(&mut self, slice: &[u8]) -> Result<(), InstructionResult> {
328 if self.push_slice_(slice) {
329 Ok(())
330 } else {
331 Err(InstructionResult::StackOverflow)
332 }
333 }
334
335 #[inline]
338 fn push_slice_(&mut self, slice: &[u8]) -> bool {
339 if slice.is_empty() {
340 cold_path();
341 return true;
342 }
343
344 let n_words = slice.len().div_ceil(32);
345 let new_len = self.len() + n_words;
346 if new_len > STACK_LIMIT {
347 cold_path();
348 return false;
349 }
350
351 debug_assert!(self.data.capacity() >= new_len);
353
354 unsafe {
356 let dst = self.data.as_mut_ptr().add(self.len()).cast::<u64>();
357 self.data.set_len(new_len);
358
359 let mut i = 0;
360
361 let (words, partial_last_word) = slice.as_chunks::<32>();
363 for word in words {
364 for l in word.rchunks_exact(8) {
367 dst.add(i).write(u64::from_be_bytes(l.try_into().unwrap()));
368 i += 1;
369 }
370 }
371
372 if partial_last_word.is_empty() {
373 return true;
374 }
375
376 let limbs = partial_last_word.rchunks_exact(8);
378 let partial_last_limb = limbs.remainder();
379 for l in limbs {
380 dst.add(i).write(u64::from_be_bytes(l.try_into().unwrap()));
381 i += 1;
382 }
383
384 if !partial_last_limb.is_empty() {
386 let mut tmp = [0u8; 8];
387 tmp[8 - partial_last_limb.len()..].copy_from_slice(partial_last_limb);
388 dst.add(i).write(u64::from_be_bytes(tmp));
389 i += 1;
390 }
391
392 debug_assert_eq!(i.div_ceil(4), n_words, "wrote too much");
393
394 let m = i % 4; if m != 0 {
397 dst.add(i).write_bytes(0, 4 - m);
398 }
399 }
400
401 true
402 }
403
404 #[inline]
408 pub fn set(&mut self, no_from_top: usize, val: U256) -> Result<(), InstructionResult> {
409 if self.len() <= no_from_top {
410 cold_path();
411 return Err(InstructionResult::StackUnderflow);
412 }
413 let len = self.len();
414 self.data[len - no_from_top - 1] = val;
415 Ok(())
416 }
417}
418
419#[cfg(feature = "serde")]
420impl<'de> serde::Deserialize<'de> for Stack {
421 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
422 where
423 D: serde::Deserializer<'de>,
424 {
425 #[derive(serde::Deserialize)]
426 struct StackSerde {
427 data: Vec<U256>,
428 }
429
430 let mut stack = StackSerde::deserialize(deserializer)?;
431 if stack.data.len() > STACK_LIMIT {
432 return Err(serde::de::Error::custom(std::format!(
433 "stack size exceeds limit: {} > {}",
434 stack.data.len(),
435 STACK_LIMIT
436 )));
437 }
438 stack.data.reserve(STACK_LIMIT - stack.data.len());
439 Ok(Self { data: stack.data })
440 }
441}
442
443#[cfg(test)]
444mod tests {
445 use super::*;
446
447 fn run(f: impl FnOnce(&mut Stack)) {
448 let mut stack = Stack::new();
449 unsafe {
451 stack.data.set_len(STACK_LIMIT);
452 stack.data.fill(U256::MAX);
453 stack.data.set_len(0);
454 }
455 f(&mut stack);
456 }
457
458 #[test]
459 fn push_slices() {
460 run(|stack| {
462 stack.push_slice(b"").unwrap();
463 assert!(stack.is_empty());
464 });
465
466 run(|stack| {
468 stack.push_slice(&[42]).unwrap();
469 assert_eq!(stack.data, [U256::from(42)]);
470 });
471
472 let n = 0x1111_2222_3333_4444_5555_6666_7777_8888_u128;
473 run(|stack| {
474 stack.push_slice(&n.to_be_bytes()).unwrap();
475 assert_eq!(stack.data, [U256::from(n)]);
476 });
477
478 run(|stack| {
480 let b = [U256::from(n).to_be_bytes::<32>(); 2].concat();
481 stack.push_slice(&b).unwrap();
482 assert_eq!(stack.data, [U256::from(n); 2]);
483 });
484
485 run(|stack| {
486 let b = [&[0; 32][..], &[42u8]].concat();
487 stack.push_slice(&b).unwrap();
488 assert_eq!(stack.data, [U256::ZERO, U256::from(42)]);
489 });
490
491 run(|stack| {
492 let b = [&[0; 32][..], &n.to_be_bytes()].concat();
493 stack.push_slice(&b).unwrap();
494 assert_eq!(stack.data, [U256::ZERO, U256::from(n)]);
495 });
496
497 run(|stack| {
498 let b = [&[0; 64][..], &n.to_be_bytes()].concat();
499 stack.push_slice(&b).unwrap();
500 assert_eq!(stack.data, [U256::ZERO, U256::ZERO, U256::from(n)]);
501 });
502 }
503
504 #[test]
505 fn stack_clone() {
506 let empty_stack = Stack::new();
508 let cloned_empty = empty_stack.clone();
509 assert_eq!(empty_stack, cloned_empty);
510 assert_eq!(cloned_empty.len(), 0);
511 assert_eq!(cloned_empty.data().capacity(), STACK_LIMIT);
512
513 let mut partial_stack = Stack::new();
515 for i in 0..10 {
516 assert!(partial_stack.push(U256::from(i)));
517 }
518 let mut cloned_partial = partial_stack.clone();
519 assert_eq!(partial_stack, cloned_partial);
520 assert_eq!(cloned_partial.len(), 10);
521 assert_eq!(cloned_partial.data().capacity(), STACK_LIMIT);
522
523 assert!(cloned_partial.push(U256::from(100)));
525 assert_ne!(partial_stack, cloned_partial);
526 assert_eq!(partial_stack.len(), 10);
527 assert_eq!(cloned_partial.len(), 11);
528
529 let mut full_stack = Stack::new();
531 for i in 0..STACK_LIMIT {
532 assert!(full_stack.push(U256::from(i)));
533 }
534 let mut cloned_full = full_stack.clone();
535 assert_eq!(full_stack, cloned_full);
536 assert_eq!(cloned_full.len(), STACK_LIMIT);
537 assert_eq!(cloned_full.data().capacity(), STACK_LIMIT);
538
539 assert!(!full_stack.push(U256::from(100)));
541 assert!(!cloned_full.push(U256::from(100)));
542 }
543}