diff options
Diffstat (limited to 'testes')
| -rw-r--r-- | testes/db.lua | 9 | ||||
| -rw-r--r-- | testes/locals.lua | 33 |
2 files changed, 33 insertions, 9 deletions
diff --git a/testes/db.lua b/testes/db.lua index 2feaaef1..9da68210 100644 --- a/testes/db.lua +++ b/testes/db.lua | |||
| @@ -734,19 +734,18 @@ a, b = coroutine.resume(co, 100) | |||
| 734 | assert(a and b == 30) | 734 | assert(a and b == 30) |
| 735 | 735 | ||
| 736 | 736 | ||
| 737 | -- check traceback of suspended (or dead with error) coroutines | 737 | -- check traceback of suspended coroutines |
| 738 | 738 | ||
| 739 | function f(i) if i==0 then error(i) else coroutine.yield(); f(i-1) end end | 739 | function f(i) coroutine.yield(i == 0); f(i - 1) end |
| 740 | 740 | ||
| 741 | co = coroutine.create(function (x) f(x) end) | 741 | co = coroutine.create(function (x) f(x) end) |
| 742 | a, b = coroutine.resume(co, 3) | 742 | a, b = coroutine.resume(co, 3) |
| 743 | t = {"'coroutine.yield'", "'f'", "in function <"} | 743 | t = {"'coroutine.yield'", "'f'", "in function <"} |
| 744 | while coroutine.status(co) == "suspended" do | 744 | repeat |
| 745 | checktraceback(co, t) | 745 | checktraceback(co, t) |
| 746 | a, b = coroutine.resume(co) | 746 | a, b = coroutine.resume(co) |
| 747 | table.insert(t, 2, "'f'") -- one more recursive call to 'f' | 747 | table.insert(t, 2, "'f'") -- one more recursive call to 'f' |
| 748 | end | 748 | until b |
| 749 | t[1] = "'error'" | ||
| 750 | checktraceback(co, t) | 749 | checktraceback(co, t) |
| 751 | 750 | ||
| 752 | 751 | ||
diff --git a/testes/locals.lua b/testes/locals.lua index d12c70a0..f21fa2ec 100644 --- a/testes/locals.lua +++ b/testes/locals.lua | |||
| @@ -274,13 +274,38 @@ if rawget(_G, "T") then | |||
| 274 | end | 274 | end |
| 275 | 275 | ||
| 276 | 276 | ||
| 277 | -- to-be-closed variables in coroutines | ||
| 278 | do | ||
| 279 | -- an error in a coroutine closes variables | ||
| 280 | local x = false | ||
| 281 | local y = false | ||
| 282 | local co = coroutine.create(function () | ||
| 283 | local scoped xv = function () x = true end | ||
| 284 | do | ||
| 285 | local scoped yv = function () y = true end | ||
| 286 | coroutine.yield(100) -- yield doesn't close variable | ||
| 287 | end | ||
| 288 | coroutine.yield(200) -- yield doesn't close variable | ||
| 289 | error(23) -- error does | ||
| 290 | end) | ||
| 291 | |||
| 292 | local a, b = coroutine.resume(co) | ||
| 293 | assert(a and b == 100 and not x and not y) | ||
| 294 | a, b = coroutine.resume(co) | ||
| 295 | assert(a and b == 200 and not x and y) | ||
| 296 | a, b = coroutine.resume(co) | ||
| 297 | assert(not a and b == 23 and x and y) | ||
| 298 | end | ||
| 299 | |||
| 277 | -- a suspended coroutine should not close its variables when collected | 300 | -- a suspended coroutine should not close its variables when collected |
| 278 | local co = coroutine.wrap(function() | 301 | local co |
| 302 | co = coroutine.wrap(function() | ||
| 279 | local scoped x = function () os.exit(false) end -- should not run | 303 | local scoped x = function () os.exit(false) end -- should not run |
| 280 | coroutine.yield() | 304 | co = nil |
| 305 | coroutine.yield() | ||
| 281 | end) | 306 | end) |
| 282 | co() | 307 | co() -- start coroutine |
| 283 | co = nil | 308 | assert(co == nil) -- eventually it will be collected |
| 284 | 309 | ||
| 285 | print('OK') | 310 | print('OK') |
| 286 | 311 | ||
