github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/vm/ref_counter.go (about) 1 package vm 2 3 import ( 4 "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" 5 ) 6 7 // refCounter represents a reference counter for the VM. 8 type refCounter int 9 10 func newRefCounter() *refCounter { 11 return new(refCounter) 12 } 13 14 // Add adds an item to the reference counter. 15 func (r *refCounter) Add(item stackitem.Item) { 16 if r == nil { 17 return 18 } 19 *r++ 20 21 switch t := item.(type) { 22 case *stackitem.Array: 23 if t.IncRC() == 1 { 24 for _, it := range t.Value().([]stackitem.Item) { 25 r.Add(it) 26 } 27 } 28 case *stackitem.Struct: 29 if t.IncRC() == 1 { 30 for _, it := range t.Value().([]stackitem.Item) { 31 r.Add(it) 32 } 33 } 34 case *stackitem.Map: 35 if t.IncRC() == 1 { 36 elems := t.Value().([]stackitem.MapElement) 37 for i := range elems { 38 r.Add(elems[i].Key) 39 r.Add(elems[i].Value) 40 } 41 } 42 } 43 } 44 45 // Remove removes an item from the reference counter. 46 func (r *refCounter) Remove(item stackitem.Item) { 47 if r == nil { 48 return 49 } 50 *r-- 51 52 switch t := item.(type) { 53 case *stackitem.Array: 54 if t.DecRC() == 0 { 55 for _, it := range t.Value().([]stackitem.Item) { 56 r.Remove(it) 57 } 58 } 59 case *stackitem.Struct: 60 if t.DecRC() == 0 { 61 for _, it := range t.Value().([]stackitem.Item) { 62 r.Remove(it) 63 } 64 } 65 case *stackitem.Map: 66 if t.DecRC() == 0 { 67 elems := t.Value().([]stackitem.MapElement) 68 for i := range elems { 69 r.Remove(elems[i].Key) 70 r.Remove(elems[i].Value) 71 } 72 } 73 } 74 }