Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,16 @@ func (l *State) newUpValueAt(level int) *upValue {
func (l *State) close(level int) {
// TODO this seems really inefficient - how can we terminate early?
var p *openUpValue
for e := l.upValues; e != nil; e, p = e.next, e {
for e := l.upValues; e != nil; e = e.next {
if e.upValue.isInStackAbove(level) {
e.upValue.close()
if p != nil {
p.next = e.next
} else {
l.upValues = e.next
}
} else {
p = e
}
}
}
Expand Down
29 changes: 29 additions & 0 deletions stack_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package lua

import "testing"

func TestCloseUnlinksAdjacentClosedUpValues(t *testing.T) {
l := NewState()
l.stack[1] = "kept open"
l.stack[2] = "closed first"
l.stack[3] = "closed second"

kept := l.newUpValueAt(1)
closedFirst := l.newUpValueAt(2)
closedSecond := l.newUpValueAt(3)

l.close(2)

if got := closedFirst.value(); got != "closed first" {
t.Errorf("first closed upvalue = %v, want %q", got, "closed first")
}
if got := closedSecond.value(); got != "closed second" {
t.Errorf("second closed upvalue = %v, want %q", got, "closed second")
}
if !kept.isInStackAt(1) {
t.Fatal("upvalue below the closing level was closed")
}
if l.upValues == nil || l.upValues.upValue != kept || l.upValues.next != nil {
t.Error("closed upvalues remain in the open upvalue list")
}
}
Loading