github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/runtime/closure.go (about) 1 package runtime 2 3 import "unsafe" 4 5 // Closure is the data structure that represents a Lua function. It is simply a 6 // reference to a Code instance and a set of upvalues. 7 type Closure struct { 8 *Code 9 Upvalues []Cell 10 upvalueIndex int 11 } 12 13 var _ Callable = (*Closure)(nil) 14 15 // NewClosure returns a pointer to a new Closure instance for the given code. 16 func NewClosure(r *Runtime, c *Code) *Closure { 17 if c.UpvalueCount > 0 { 18 r.RequireArrSize(unsafe.Sizeof(Cell{}), int(c.UpvalueCount)) 19 } 20 return &Closure{ 21 Code: c, 22 Upvalues: make([]Cell, c.UpvalueCount), 23 } 24 } 25 26 // Equals returns a true if it can assert that c and c1 implement the same 27 // function. 28 func (c *Closure) Equals(c1 *Closure) bool { 29 if c.Code != c1.Code || len(c.Upvalues) != len(c1.Upvalues) { 30 return false 31 } 32 for i, upv := range c.Upvalues { 33 if c1.Upvalues[i] != upv { 34 return false 35 } 36 } 37 return true 38 } 39 40 // AddUpvalue append a new upvalue to the closure. 41 func (c *Closure) AddUpvalue(cell Cell) { 42 c.Upvalues[c.upvalueIndex] = cell 43 c.upvalueIndex++ 44 } 45 46 // Continuation implements Callable.Continuation. 47 func (c *Closure) Continuation(t *Thread, next Cont) Cont { 48 return NewLuaCont(t, c, next) 49 } 50 51 // GetUpvalue returns the upvalue for c at index n. 52 func (c *Closure) GetUpvalue(n int) Value { 53 return c.Upvalues[n].get() 54 } 55 56 // SetUpvalue sets the upvalue for c at index n to v. 57 func (c *Closure) SetUpvalue(n int, val Value) { 58 c.Upvalues[n].set(val) 59 }