Skip to content

Commit ef5440f

Browse files
committed
Issue yuin#514 : Fix compileRegAssignment cardinality
Use `nvars` as the assignment numbers rather than `lennames`. This makes no difference in `compileLocalAssignStmt` as the numbers are equal, but in `compileGenericForStmt` the names are the iteration variables while `nvars` refers to the local generator, state, and control. The iteration variables feel a bit out of place here. The whole body of `compileRegAssignment` seem inconsistent, using `names` only for its length, and mixing `lennames` and `nvars` in surprising ways. Moreover the function name `compileRegAssignment` suggests assigning to registers rather than names, so I dropped `lennames` entirely to use only `nvars`.
1 parent ccacf66 commit ef5440f

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

_glua-tests/issues.lua

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,3 +490,22 @@ function test()
490490
assert(b == nil)
491491
end
492492
test()
493+
494+
-- issue #514
495+
function test()
496+
local tbl = {foo = 42, bar = "baz"}
497+
local iter = function(s,k)
498+
k,_ = next(tbl, k)
499+
return k
500+
end
501+
local seen1, seen2 = {}, {}
502+
for item in iter do
503+
seen1[item] = true
504+
end
505+
for item in iter do
506+
seen2[item] = true
507+
end
508+
assert(seen1.foo and seen1.bar)
509+
assert(seen2.foo and seen2.bar)
510+
end
511+
test()

compile.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -812,20 +812,19 @@ func compileAssignStmt(context *funcContext, stmt *ast.AssignStmt) { // {{{
812812
}
813813
} // }}}
814814

815-
func compileRegAssignment(context *funcContext, names []string, exprs []ast.Expr, reg int, nvars int, line int) { // {{{
816-
lennames := len(names)
815+
func compileRegAssignment(context *funcContext, exprs []ast.Expr, reg int, nvars int, line int) { // {{{
817816
lenexprs := len(exprs)
818817
namesassigned := 0
819818
ec := &expcontext{}
820819

821-
for namesassigned < lennames && namesassigned < lenexprs {
820+
for namesassigned < nvars && namesassigned < lenexprs {
822821
if isVarArgReturnExpr(exprs[namesassigned]) && (lenexprs-namesassigned-1) <= 0 {
823822

824823
varargopt := nvars - namesassigned
825824
ecupdate(ec, ecVararg, reg, varargopt-1)
826825
compileExpr(context, reg, exprs[namesassigned], ec)
827826
reg += varargopt
828-
namesassigned = lennames
827+
namesassigned = nvars
829828
} else {
830829
ecupdate(ec, ecLocal, reg, 0)
831830
compileExpr(context, reg, exprs[namesassigned], ec)
@@ -835,8 +834,8 @@ func compileRegAssignment(context *funcContext, names []string, exprs []ast.Expr
835834
}
836835

837836
// extra left names
838-
if lennames > namesassigned {
839-
restleft := lennames - namesassigned - 1
837+
if nvars > namesassigned {
838+
restleft := nvars - namesassigned - 1
840839
context.Code.AddLoadNil(reg, reg+restleft, line)
841840
reg += restleft
842841
}
@@ -857,12 +856,12 @@ func compileLocalAssignStmt(context *funcContext, stmt *ast.LocalAssignStmt) { /
857856
if len(stmt.Names) == 1 && len(stmt.Exprs) == 1 {
858857
if _, ok := stmt.Exprs[0].(*ast.FunctionExpr); ok {
859858
context.RegisterLocalVar(stmt.Names[0])
860-
compileRegAssignment(context, stmt.Names, stmt.Exprs, reg, len(stmt.Names), sline(stmt))
859+
compileRegAssignment(context, stmt.Exprs, reg, len(stmt.Names), sline(stmt))
861860
return
862861
}
863862
}
864863

865-
compileRegAssignment(context, stmt.Names, stmt.Exprs, reg, len(stmt.Names), sline(stmt))
864+
compileRegAssignment(context, stmt.Exprs, reg, len(stmt.Names), sline(stmt))
866865
for _, name := range stmt.Names {
867866
context.RegisterLocalVar(name)
868867
}
@@ -1100,7 +1099,7 @@ func compileGenericForStmt(context *funcContext, stmt *ast.GenericForStmt) { //
11001099
context.RegisterLocalVar("(for state)")
11011100
context.RegisterLocalVar("(for control)")
11021101

1103-
compileRegAssignment(context, stmt.Names, stmt.Exprs, context.RegTop()-3, 3, sline(stmt))
1102+
compileRegAssignment(context, stmt.Exprs, context.RegTop()-3, 3, sline(stmt))
11041103

11051104
code.AddASbx(OP_JMP, 0, fllabel, sline(stmt))
11061105

0 commit comments

Comments
 (0)