package vm import ( "encoding/json" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) // Slot is a fixed-size slice of stack items. type Slot struct { storage []stackitem.Item refs *refCounter } // newSlot returns new slot with the provided reference counter. func newSlot(refs *refCounter) *Slot { return &Slot{ refs: refs, } } // init sets static slot size to n. It is intended to be used only by INITSSLOT. func (s *Slot) init(n int) { if s.storage != nil { panic("already initialized") } s.storage = make([]stackitem.Item, n) } func (v *VM) newSlot(n int) *Slot { s := newSlot(&v.refs) s.init(n) return s } // Set sets i-th storage slot. func (s *Slot) Set(i int, item stackitem.Item) { if s.storage[i] == item { return } old := s.storage[i] s.storage[i] = item if old != nil { s.refs.Remove(old) } s.refs.Add(item) } // Get returns item contained in i-th slot. func (s *Slot) Get(i int) stackitem.Item { if item := s.storage[i]; item != nil { return item } return stackitem.Null{} } // Clear removes all slot variables from reference counter. func (s *Slot) Clear() { for _, item := range s.storage { s.refs.Remove(item) } } // Size returns slot size. func (s *Slot) Size() int { if s.storage == nil { panic("not initialized") } return len(s.storage) } // MarshalJSON implements JSON marshalling interface. func (s *Slot) MarshalJSON() ([]byte, error) { items := s.storage arr := make([]json.RawMessage, len(items)) for i := range items { data, err := stackitem.ToJSONWithTypes(items[i]) if err == nil { arr[i] = data } } return json.Marshal(arr) }