revm_rwasm_interpreter/interpreter/
stack.rs1use crate::InstructionResult;
2use core::{fmt, ptr};
3use primitives::U256;
4use std::vec::Vec;
5
6use super::StackTr;
7
8pub const STACK_LIMIT: usize = 1024;
10
11#[derive(Debug, PartialEq, Eq, Hash)]
13#[cfg_attr(feature = "serde", derive(serde::Serialize))]
14pub struct Stack {
15 data: Vec<U256>,
17}
18
19impl fmt::Display for Stack {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 f.write_str("[")?;
22 for (i, x) in self.data.iter().enumerate() {
23 if i > 0 {
24 f.write_str(", ")?;
25 }
26 write!(f, "{x}")?;
27 }
28 f.write_str("]")
29 }
30}
31
32impl Default for Stack {
33 #[inline]
34 fn default() -> Self {
35 Self::new()
36 }
37}
38
39impl Clone for Stack {
40 fn clone(&self) -> Self {
41 let mut new_stack = Self::new();
45 new_stack.data.extend_from_slice(&self.data);
46 new_stack
47 }
48}
49
50impl StackTr for Stack {
51 #[inline]
52 fn len(&self) -> usize {
53 self.len()
54 }
55
56 #[inline]
57 fn data(&self) -> &[U256] {
58 &self.data
59 }
60
61 #[inline]
62 fn clear(&mut self) {
63 self.data.clear();
64 }
65
66 #[inline]
67 fn popn<const N: usize>(&mut self) -> Option<[U256; N]> {
68 if self.len() < N {
69 return None;
70 }
71 Some(unsafe { self.popn::<N>() })
73 }
74
75 #[inline]
76 fn popn_top<const POPN: usize>(&mut self) -> Option<([U256; POPN], &mut U256)> {
77 if self.len() < POPN + 1 {
78 return None;
79 }
80 Some(unsafe { self.popn_top::<POPN>() })
82 }
83
84 #[inline]
85 fn exchange(&mut self, n: usize, m: usize) -> bool {
86 self.exchange(n, m)
87 }
88
89 #[inline]
90 fn dup(&mut self, n: usize) -> bool {
91 self.dup(n)
92 }
93
94 #[inline]
95 fn push(&mut self, value: U256) -> bool {
96 self.push(value)
97 }
98
99 #[inline]
100 fn push_slice(&mut self, slice: &[u8]) -> bool {
101 self.push_slice_(slice)
102 }
103}
104
105impl Stack {
106 #[inline]
108 pub fn new() -> Self {
109 Self {
110 data: Vec::with_capacity(STACK_LIMIT),
112 }
113 }
114
115 #[inline]
117 pub fn invalid() -> Self {
118 Self { data: Vec::new() }
119 }
120
121 #[inline]
123 pub fn len(&self) -> usize {
124 self.data.len()
125 }
126
127 #[inline]
129 pub fn is_empty(&self) -> bool {
130 self.data.is_empty()
131 }
132
133 #[inline]
135 pub fn data(&self) -> &Vec<U256> {
136 &self.data
137 }
138
139 #[inline]
141 pub fn data_mut(&mut self) -> &mut Vec<U256> {
142 &mut self.data
143 }
144
145 #[inline]
147 pub fn into_data(self) -> Vec<U256> {
148 self.data
149 }
150
151 #[inline]
154 #[cfg_attr(debug_assertions, track_caller)]
155 pub fn pop(&mut self) -> Result<U256, InstructionResult> {
156 let len = self.data.len();
158 if primitives::hints_util::unlikely(len == 0) {
159 Err(InstructionResult::StackUnderflow)
160 } else {
161 unsafe {
162 self.data.set_len(len - 1);
163 Ok(core::ptr::read(self.data.as_ptr().add(len - 1)))
164 }
165 }
166 }
167
168 #[inline]
174 #[cfg_attr(debug_assertions, track_caller)]
175 pub unsafe fn pop_unsafe(&mut self) -> U256 {
176 assume!(!self.data.is_empty());
177 self.data.pop().unwrap_unchecked()
178 }
179
180 #[inline]
186 #[cfg_attr(debug_assertions, track_caller)]
187 pub unsafe fn top_unsafe(&mut self) -> &mut U256 {
188 assume!(!self.data.is_empty());
189 self.data.last_mut().unwrap_unchecked()
190 }
191
192 #[inline]
198 #[cfg_attr(debug_assertions, track_caller)]
199 pub unsafe fn popn<const N: usize>(&mut self) -> [U256; N] {
200 assume!(self.data.len() >= N);
201 core::array::from_fn(|_| unsafe { self.pop_unsafe() })
202 }
203
204 #[inline]
210 #[cfg_attr(debug_assertions, track_caller)]
211 pub unsafe fn popn_top<const POPN: usize>(&mut self) -> ([U256; POPN], &mut U256) {
212 let result = self.popn::<POPN>();
213 let top = self.top_unsafe();
214 (result, top)
215 }
216
217 #[inline]
222 #[must_use]
223 #[cfg_attr(debug_assertions, track_caller)]
224 pub fn push(&mut self, value: U256) -> bool {
225 debug_assert!(self.data.capacity() >= STACK_LIMIT);
227 let len = self.data.len();
228 if len == STACK_LIMIT {
229 return false;
230 }
231 unsafe {
232 let end = self.data.as_mut_ptr().add(len);
233 core::ptr::write(end, value);
234 self.data.set_len(len + 1);
235 }
236 true
237 }
238
239 #[inline]
243 pub fn peek(&self, no_from_top: usize) -> Result<U256, InstructionResult> {
244 if self.data.len() > no_from_top {
245 Ok(self.data[self.data.len() - no_from_top - 1])
246 } else {
247 Err(InstructionResult::StackUnderflow)
248 }
249 }
250
251 #[inline]
253 pub fn peekn<const N: usize>(&self) -> Option<[U256; N]> {
254 let len = self.data.len();
255 (len >= N).then(|| core::array::from_fn(|i| self.data[len - 1 - i]))
256 }
257
258 #[inline]
264 #[must_use]
265 #[cfg_attr(debug_assertions, track_caller)]
266 pub fn dup(&mut self, n: usize) -> bool {
267 assume!(n > 0, "attempted to dup 0");
268 let len = self.data.len();
269 if len < n || len + 1 > STACK_LIMIT {
270 false
271 } else {
272 unsafe {
274 let ptr = self.data.as_mut_ptr().add(len);
275 ptr::copy_nonoverlapping(ptr.sub(n), ptr, 1);
276 self.data.set_len(len + 1);
277 }
278 true
279 }
280 }
281
282 #[inline(always)]
288 #[cfg_attr(debug_assertions, track_caller)]
289 pub fn swap(&mut self, n: usize) -> bool {
290 self.exchange(0, n)
291 }
292
293 #[inline]
301 #[cfg_attr(debug_assertions, track_caller)]
302 pub fn exchange(&mut self, n: usize, m: usize) -> bool {
303 assume!(m > 0, "overlapping exchange");
304 let len = self.data.len();
305 let n_m_index = n + m;
306 if n_m_index >= len {
307 return false;
308 }
309 unsafe {
311 let top = self.data.as_mut_ptr().add(len - 1);
316 core::ptr::swap_nonoverlapping(top.sub(n), top.sub(n_m_index), 1);
317 }
318 true
319 }
320
321 #[inline]
324 pub fn push_slice(&mut self, slice: &[u8]) -> Result<(), InstructionResult> {
325 if self.push_slice_(slice) {
326 Ok(())
327 } else {
328 Err(InstructionResult::StackOverflow)
329 }
330 }
331
332 #[inline]
335 fn push_slice_(&mut self, slice: &[u8]) -> bool {
336 if slice.is_empty() {
337 return true;
338 }
339
340 let n_words = slice.len().div_ceil(32);
341 let new_len = self.data.len() + n_words;
342 if new_len > STACK_LIMIT {
343 return false;
344 }
345
346 debug_assert!(self.data.capacity() >= new_len);
348
349 unsafe {
351 let dst = self.data.as_mut_ptr().add(self.data.len()).cast::<u64>();
352 self.data.set_len(new_len);
353
354 let mut i = 0;
355
356 let words = slice.chunks_exact(32);
358 let partial_last_word = words.remainder();
359 for word in words {
360 for l in word.rchunks_exact(8) {
363 dst.add(i).write(u64::from_be_bytes(l.try_into().unwrap()));
364 i += 1;
365 }
366 }
367
368 if partial_last_word.is_empty() {
369 return true;
370 }
371
372 let limbs = partial_last_word.rchunks_exact(8);
374 let partial_last_limb = limbs.remainder();
375 for l in limbs {
376 dst.add(i).write(u64::from_be_bytes(l.try_into().unwrap()));
377 i += 1;
378 }
379
380 if !partial_last_limb.is_empty() {
382 let mut tmp = [0u8; 8];
383 tmp[8 - partial_last_limb.len()..].copy_from_slice(partial_last_limb);
384 dst.add(i).write(u64::from_be_bytes(tmp));
385 i += 1;
386 }
387
388 debug_assert_eq!(i.div_ceil(4), n_words, "wrote too much");
389
390 let m = i % 4; if m != 0 {
393 dst.add(i).write_bytes(0, 4 - m);
394 }
395 }
396
397 true
398 }
399
400 #[inline]
404 pub fn set(&mut self, no_from_top: usize, val: U256) -> Result<(), InstructionResult> {
405 if self.data.len() > no_from_top {
406 let len = self.data.len();
407 self.data[len - no_from_top - 1] = val;
408 Ok(())
409 } else {
410 Err(InstructionResult::StackUnderflow)
411 }
412 }
413}
414
415#[cfg(feature = "serde")]
416impl<'de> serde::Deserialize<'de> for Stack {
417 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
418 where
419 D: serde::Deserializer<'de>,
420 {
421 #[derive(serde::Deserialize)]
422 struct StackSerde {
423 data: Vec<U256>,
424 }
425
426 let mut stack = StackSerde::deserialize(deserializer)?;
427 if stack.data.len() > STACK_LIMIT {
428 return Err(serde::de::Error::custom(std::format!(
429 "stack size exceeds limit: {} > {}",
430 stack.data.len(),
431 STACK_LIMIT
432 )));
433 }
434 stack.data.reserve(STACK_LIMIT - stack.data.len());
435 Ok(Self { data: stack.data })
436 }
437}
438
439#[cfg(test)]
440mod tests {
441 use super::*;
442
443 fn run(f: impl FnOnce(&mut Stack)) {
444 let mut stack = Stack::new();
445 unsafe {
447 stack.data.set_len(STACK_LIMIT);
448 stack.data.fill(U256::MAX);
449 stack.data.set_len(0);
450 }
451 f(&mut stack);
452 }
453
454 #[test]
455 fn push_slices() {
456 run(|stack| {
458 stack.push_slice(b"").unwrap();
459 assert!(stack.data.is_empty());
460 });
461
462 run(|stack| {
464 stack.push_slice(&[42]).unwrap();
465 assert_eq!(stack.data, [U256::from(42)]);
466 });
467
468 let n = 0x1111_2222_3333_4444_5555_6666_7777_8888_u128;
469 run(|stack| {
470 stack.push_slice(&n.to_be_bytes()).unwrap();
471 assert_eq!(stack.data, [U256::from(n)]);
472 });
473
474 run(|stack| {
476 let b = [U256::from(n).to_be_bytes::<32>(); 2].concat();
477 stack.push_slice(&b).unwrap();
478 assert_eq!(stack.data, [U256::from(n); 2]);
479 });
480
481 run(|stack| {
482 let b = [&[0; 32][..], &[42u8]].concat();
483 stack.push_slice(&b).unwrap();
484 assert_eq!(stack.data, [U256::ZERO, U256::from(42)]);
485 });
486
487 run(|stack| {
488 let b = [&[0; 32][..], &n.to_be_bytes()].concat();
489 stack.push_slice(&b).unwrap();
490 assert_eq!(stack.data, [U256::ZERO, U256::from(n)]);
491 });
492
493 run(|stack| {
494 let b = [&[0; 64][..], &n.to_be_bytes()].concat();
495 stack.push_slice(&b).unwrap();
496 assert_eq!(stack.data, [U256::ZERO, U256::ZERO, U256::from(n)]);
497 });
498 }
499
500 #[test]
501 fn stack_clone() {
502 let empty_stack = Stack::new();
504 let cloned_empty = empty_stack.clone();
505 assert_eq!(empty_stack, cloned_empty);
506 assert_eq!(cloned_empty.len(), 0);
507 assert_eq!(cloned_empty.data().capacity(), STACK_LIMIT);
508
509 let mut partial_stack = Stack::new();
511 for i in 0..10 {
512 assert!(partial_stack.push(U256::from(i)));
513 }
514 let mut cloned_partial = partial_stack.clone();
515 assert_eq!(partial_stack, cloned_partial);
516 assert_eq!(cloned_partial.len(), 10);
517 assert_eq!(cloned_partial.data().capacity(), STACK_LIMIT);
518
519 assert!(cloned_partial.push(U256::from(100)));
521 assert_ne!(partial_stack, cloned_partial);
522 assert_eq!(partial_stack.len(), 10);
523 assert_eq!(cloned_partial.len(), 11);
524
525 let mut full_stack = Stack::new();
527 for i in 0..STACK_LIMIT {
528 assert!(full_stack.push(U256::from(i)));
529 }
530 let mut cloned_full = full_stack.clone();
531 assert_eq!(full_stack, cloned_full);
532 assert_eq!(cloned_full.len(), STACK_LIMIT);
533 assert_eq!(cloned_full.data().capacity(), STACK_LIMIT);
534
535 assert!(!full_stack.push(U256::from(100)));
537 assert!(!cloned_full.push(U256::from(100)));
538 }
539}