summaryrefslogtreecommitdiff
path: root/testes/locals.lua
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-05-09 11:13:45 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-05-09 11:13:45 -0300
commit389116d8abcc96db3cfe2f3cc25789c089fe12d6 (patch)
treef3d07b50c17f28ba09cf547d5a67519ffe3271a4 /testes/locals.lua
parent01bded3d8cd88a2d7f472b45f706565f1a9ef3b1 (diff)
downloadlua-389116d8abcc96db3cfe2f3cc25789c089fe12d6.tar.gz
lua-389116d8abcc96db3cfe2f3cc25789c089fe12d6.tar.bz2
lua-389116d8abcc96db3cfe2f3cc25789c089fe12d6.zip
Coroutines do not unwind the stack in case of errors
Back to how it was, a coroutine does not unwind its stack in case of errors (and therefore do not close its to-be-closed variables). This allows the stack to be examined after the error. The program can use 'coroutine.kill' to close the variables. The function created by 'coroutine.wrap', however, closes the coroutine's variables in case of errors, as it is impossible to examine the stack any way.
Diffstat (limited to 'testes/locals.lua')
-rw-r--r--testes/locals.lua35
1 files changed, 27 insertions, 8 deletions
diff --git a/testes/locals.lua b/testes/locals.lua
index de47ae31..814d1b16 100644
--- a/testes/locals.lua
+++ b/testes/locals.lua
@@ -417,12 +417,13 @@ if rawget(_G, "T") then
417end 417end
418 418
419 419
420-- to-be-closed variables in coroutines 420print "to-be-closed variables in coroutines"
421
421do 422do
422 -- an error in a coroutine closes variables 423 -- an error in a wrapped coroutine closes variables
423 local x = false 424 local x = false
424 local y = false 425 local y = false
425 local co = coroutine.create(function () 426 local co = coroutine.wrap(function ()
426 local *toclose xv = func2close(function () x = true end) 427 local *toclose xv = func2close(function () x = true end)
427 do 428 do
428 local *toclose yv = func2close(function () y = true end) 429 local *toclose yv = func2close(function () y = true end)
@@ -432,14 +433,31 @@ do
432 error(23) -- error does 433 error(23) -- error does
433 end) 434 end)
434 435
435 local a, b = coroutine.resume(co) 436 local b = co()
436 assert(a and b == 100 and not x and not y) 437 assert(b == 100 and not x and not y)
437 a, b = coroutine.resume(co) 438 b = co()
438 assert(a and b == 200 and not x and y) 439 assert(b == 200 and not x and y)
439 a, b = coroutine.resume(co) 440 local a, b = pcall(co)
440 assert(not a and b == 23 and x and y) 441 assert(not a and b == 23 and x and y)
441end 442end
442 443
444
445do
446 -- error in a wrapped coroutine raising errors when closing a variable
447 local x = false
448 local co = coroutine.wrap(function ()
449 local *toclose xv = func2close(function () error("XXX") end)
450 coroutine.yield(100)
451 error(200)
452 end)
453 assert(co() == 100)
454 local st, msg = pcall(co)
455print(msg)
456 -- should get last error raised
457 assert(not st and string.find(msg, "%w+%.%w+:%d+: XXX"))
458end
459
460
443-- a suspended coroutine should not close its variables when collected 461-- a suspended coroutine should not close its variables when collected
444local co 462local co
445co = coroutine.wrap(function() 463co = coroutine.wrap(function()
@@ -449,6 +467,7 @@ co = coroutine.wrap(function()
449end) 467end)
450co() -- start coroutine 468co() -- start coroutine
451assert(co == nil) -- eventually it will be collected 469assert(co == nil) -- eventually it will be collected
470collectgarbage()
452 471
453 472
454-- to-be-closed variables in generic for loops 473-- to-be-closed variables in generic for loops