diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-06-01 15:07:58 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-06-01 15:07:58 -0300 |
commit | 63295f1f7fa052fabcb4d69d49203cf33a7deef0 (patch) | |
tree | 05ba23f84fc76bd9a6b44883e7527ca1afcd274e /testes | |
parent | 50523b107d5bcc8069b1aec4b5b11b3fcc87da8d (diff) | |
download | lua-63295f1f7fa052fabcb4d69d49203cf33a7deef0.tar.gz lua-63295f1f7fa052fabcb4d69d49203cf33a7deef0.tar.bz2 lua-63295f1f7fa052fabcb4d69d49203cf33a7deef0.zip |
Fixed two bugs in to-be-closed variables x constants
The parser were mixing compiler indices of variables with stack indices,
so that when a to-be-closed variable was used inside the scope of
compile-time constants (which may be optimized away), it might be closed
in the wrong place. (See new tests for examples.)
Besides fixing the bugs, this commit also changed comments and variable
names to avoid that kind of confusion and added tests.
Diffstat (limited to 'testes')
-rw-r--r-- | testes/locals.lua | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/testes/locals.lua b/testes/locals.lua index 4f103be9..0e5e0c74 100644 --- a/testes/locals.lua +++ b/testes/locals.lua | |||
@@ -264,6 +264,43 @@ do | |||
264 | end | 264 | end |
265 | 265 | ||
266 | 266 | ||
267 | -- testing to-be-closed x compile-time constants | ||
268 | -- (there were some bugs here in Lua 5.4-rc3, due to a confusion | ||
269 | -- between compile levels and stack levels of variables) | ||
270 | do | ||
271 | local flag = false | ||
272 | local x = setmetatable({}, | ||
273 | {__close = function() assert(flag == false); flag = true end}) | ||
274 | local y <const> = nil | ||
275 | local z <const> = nil | ||
276 | do | ||
277 | local a <close> = x | ||
278 | end | ||
279 | assert(flag) -- 'x' must be closed here | ||
280 | end | ||
281 | |||
282 | do | ||
283 | -- similar problem, but with implicit close in for loops | ||
284 | local flag = false | ||
285 | local x = setmetatable({}, | ||
286 | {__close = function () assert(flag == false); flag = true end}) | ||
287 | -- return an empty iterator, nil, nil, and 'x' to be closed | ||
288 | local function a () | ||
289 | return (function () return nil end), nil, nil, x | ||
290 | end | ||
291 | local v <const> = 1 | ||
292 | local w <const> = 1 | ||
293 | local x <const> = 1 | ||
294 | local y <const> = 1 | ||
295 | local z <const> = 1 | ||
296 | for k in a() do | ||
297 | a = k | ||
298 | end -- ending the loop must close 'x' | ||
299 | assert(flag) -- 'x' must be closed here | ||
300 | end | ||
301 | |||
302 | |||
303 | |||
267 | do | 304 | do |
268 | -- calls cannot be tail in the scope of to-be-closed variables | 305 | -- calls cannot be tail in the scope of to-be-closed variables |
269 | local X, Y | 306 | local X, Y |