aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto I <roberto@inf.puc-rio.br>2026-07-23 13:58:30 -0300
committerRoberto I <roberto@inf.puc-rio.br>2026-07-23 13:58:30 -0300
commit7579fc9d7ed90240487251dfb69168f8e64e9294 (patch)
treedbf17260333869dc4963c7b3c3dae98d7370e771
parentd5bbe955840c5c83e37ed19df4d392d7ba0970ed (diff)
downloadlua-5.5.1.tar.gz
lua-5.5.1.tar.bz2
lua-5.5.1.zip
Small change in scope of variables in repeat-untilHEADv5.5.1master
A close instruction is still inside the scope of the variables it is closing. The extra close in a repeat-until (to close variables before repeating the loop) was being coded outside that scope.
-rw-r--r--lparser.c2
-rw-r--r--testes/locals.lua19
2 files changed, 20 insertions, 1 deletions
diff --git a/lparser.c b/lparser.c
index fe29194c..3c26a4fd 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1614,7 +1614,6 @@ static void repeatstat (LexState *ls, int line) {
1614 statlist(ls); 1614 statlist(ls);
1615 check_match(ls, TK_UNTIL, TK_REPEAT, line); 1615 check_match(ls, TK_UNTIL, TK_REPEAT, line);
1616 condexit = cond(ls); /* read condition (inside scope block) */ 1616 condexit = cond(ls); /* read condition (inside scope block) */
1617 leaveblock(fs); /* finish scope */
1618 if (bl2.upval) { /* upvalues? */ 1617 if (bl2.upval) { /* upvalues? */
1619 int exit = luaK_jump(fs); /* normal exit must jump over fix */ 1618 int exit = luaK_jump(fs); /* normal exit must jump over fix */
1620 luaK_patchtohere(fs, condexit); /* repetition must close upvalues */ 1619 luaK_patchtohere(fs, condexit); /* repetition must close upvalues */
@@ -1623,6 +1622,7 @@ static void repeatstat (LexState *ls, int line) {
1623 luaK_patchtohere(fs, exit); /* normal exit comes to here */ 1622 luaK_patchtohere(fs, exit); /* normal exit comes to here */
1624 } 1623 }
1625 luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ 1624 luaK_patchlist(fs, condexit, repeat_init); /* close the loop */
1625 leaveblock(fs); /* finish scope */
1626 leaveblock(fs); /* finish loop */ 1626 leaveblock(fs); /* finish loop */
1627} 1627}
1628 1628
diff --git a/testes/locals.lua b/testes/locals.lua
index 6cd10547..e9718341 100644
--- a/testes/locals.lua
+++ b/testes/locals.lua
@@ -1179,6 +1179,25 @@ if rawget(_G, "T") then
1179end 1179end
1180 1180
1181 1181
1182do
1183 -- detail in scopes of variables in the loop of 'repeat-until'
1184 local res = {}
1185 local function foo (a)
1186 repeat
1187 local x
1188 local i <close> = setmetatable({}, {__close = function ()
1189 res[#res + 1] = debug.getlocal(2, 2) -- get 'x'
1190 res[#res + 1] = debug.getlocal(2, 3) -- get 'i'
1191 a = true
1192 end})
1193 until a
1194 end
1195 foo(false)
1196 -- loop variables still in scope when closing 'i', both when 'repeat'
1197 -- repeats and when 'repeat' stops.
1198 assert(res[1] == "x" and res[2] == "i" and res[3] == "x" and res[4] == "i")
1199end
1200
1182 1201
1183-- to-be-closed variables in generic for loops 1202-- to-be-closed variables in generic for loops
1184do 1203do