Skip to main content

neo_vm_core/
stack_item.rs

1//! Neo VM Stack Item types
2
3use serde::{Deserialize, Serialize};
4
5/// Stack item types in Neo VM (simplified for zkVM)
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7pub enum StackItem {
8    Null,
9    Boolean(bool),
10    Integer(i128),
11    ByteString(Vec<u8>),
12    Buffer(Vec<u8>),
13    Array(Vec<StackItem>),
14    Struct(Vec<StackItem>),
15    Map(Vec<(StackItem, StackItem)>),
16    Pointer(u32),
17}
18
19// SAFETY: NeoVM is designed for single-threaded use. StackItem contains Vec which is not
20// thread-safe by default, but we explicitly mark it as Send/Sync because the VM
21// is never shared across threads in the intended usage pattern (SP1 guest execution
22// or single-threaded CLI usage). Users must not share NeoVM instances between threads.
23unsafe impl Send for StackItem {}
24unsafe impl Sync for StackItem {}
25
26impl StackItem {
27    #[inline]
28    pub fn to_bool(&self) -> bool {
29        match self {
30            StackItem::Null => false,
31            StackItem::Boolean(b) => *b,
32            StackItem::Integer(i) => *i != 0,
33            StackItem::ByteString(b) | StackItem::Buffer(b) => b.iter().any(|&x| x != 0),
34            StackItem::Array(a) | StackItem::Struct(a) => !a.is_empty(),
35            StackItem::Map(m) => !m.is_empty(),
36            _ => true,
37        }
38    }
39
40    #[inline]
41    pub fn to_integer(&self) -> Option<i128> {
42        match self {
43            StackItem::Integer(i) => Some(*i),
44            StackItem::Boolean(b) => Some(*b as i128),
45            _ => None,
46        }
47    }
48}