github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/runtime/internal/luagc/safepool.go (about) 1 package luagc 2 3 // 4 // Safe Pool implementation 5 // 6 7 // SafePool is an implementation of Pool that keeps alive all the values it is 8 // given. 9 type SafePool struct { 10 markedFinalize []Value 11 markedRelease []Value 12 } 13 14 func NewSafePool() *SafePool { 15 return &SafePool{} 16 } 17 18 var _ Pool = &SafePool{} 19 20 // Get returns a WeakRef with the given value. That WeakRef will keep the value 21 // alive! 22 func (p *SafePool) Get(v Value) WeakRef { 23 return safeWeakRef{v: v} 24 } 25 26 // Mark adds iface to the list of marked values. 27 func (p *SafePool) Mark(v Value, flags MarkFlags) { 28 if flags&Finalize != 0 { 29 p.markedFinalize = appendNoDup(p.markedFinalize, v) 30 } 31 if flags&Release != 0 { 32 p.markedRelease = appendNoDup(p.markedRelease, v) 33 } 34 } 35 36 // append y to the end of xs, removing a previous occurrence of y in xs if 37 // found. It is assumed that xs doesn't have any duplicates. 38 func appendNoDup(xs []Value, y Value) []Value { 39 for i, x := range xs { 40 if x == y { 41 copy(xs[i:], xs[i+1:]) 42 xs[len(xs)-1] = y 43 return xs 44 } 45 } 46 return append(xs, y) 47 } 48 49 // ExtractPendingFinalize returns nil because all marked values are kept alive by the 50 // pool. 51 func (p *SafePool) ExtractPendingFinalize() []Value { 52 return nil 53 } 54 55 // ExtractPendingRelease returns nil because all marked values are kept alive by 56 // the pool. 57 func (p *SafePool) ExtractPendingRelease() []Value { 58 return nil 59 } 60 61 // ExtractAllMarkedFinalize returns all values marked for finalizing in reverse 62 // order, clearing them. 63 func (p *SafePool) ExtractAllMarkedFinalize() []Value { 64 marked := p.markedFinalize 65 p.markedFinalize = nil 66 reverse(marked) 67 return marked 68 } 69 70 // ExtractAllMarkedRelease returns all values marked for release in reverse 71 // order, clearing them. 72 func (p *SafePool) ExtractAllMarkedRelease() []Value { 73 marked := p.markedRelease 74 p.markedRelease = nil 75 reverse(marked) 76 return marked 77 } 78 79 // 80 // WeakRef implementation for SafePool 81 // 82 83 // safeWeakRef keeps the value it reference alive. 84 type safeWeakRef struct { 85 v Value 86 } 87 88 var _ WeakRef = safeWeakRef{} 89 90 // Value returns the value r is referring to. 91 func (r safeWeakRef) Value() Value { 92 return r.v 93 } 94 95 // 96 // Helper functions 97 // 98 99 func reverse(s []Value) { 100 for i, j := 0, len(s)-1; i < j; { 101 s[i], s[j] = s[j], s[i] 102 i++ 103 j-- 104 } 105 }