diff options
Diffstat (limited to 'testes')
-rw-r--r-- | testes/coroutine.lua | 8 | ||||
-rw-r--r-- | testes/db.lua | 14 | ||||
-rw-r--r-- | testes/locals.lua | 35 |
3 files changed, 43 insertions, 14 deletions
diff --git a/testes/coroutine.lua b/testes/coroutine.lua index 35ff27fb..9dd501e7 100644 --- a/testes/coroutine.lua +++ b/testes/coroutine.lua | |||
@@ -346,9 +346,13 @@ do | |||
346 | local st, res = coroutine.resume(B) | 346 | local st, res = coroutine.resume(B) |
347 | assert(st == true and res == false) | 347 | assert(st == true and res == false) |
348 | 348 | ||
349 | A = coroutine.wrap(function() return pcall(A, 1) end) | 349 | local X = false |
350 | A = coroutine.wrap(function() | ||
351 | local *toclose _ = setmetatable({}, {__close = function () X = true end}) | ||
352 | return pcall(A, 1) | ||
353 | end) | ||
350 | st, res = A() | 354 | st, res = A() |
351 | assert(not st and string.find(res, "non%-suspended")) | 355 | assert(not st and string.find(res, "non%-suspended") and X == true) |
352 | end | 356 | end |
353 | 357 | ||
354 | 358 | ||
diff --git a/testes/db.lua b/testes/db.lua index 95275fb4..3d94f776 100644 --- a/testes/db.lua +++ b/testes/db.lua | |||
@@ -734,18 +734,24 @@ 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 coroutines | 737 | -- check traceback of suspended (or dead with error) coroutines |
738 | |||
739 | function f(i) | ||
740 | if i == 0 then error(i) | ||
741 | else coroutine.yield(); f(i-1) | ||
742 | end | ||
743 | end | ||
738 | 744 | ||
739 | function f(i) coroutine.yield(i == 0); f(i - 1) end | ||
740 | 745 | ||
741 | co = coroutine.create(function (x) f(x) end) | 746 | co = coroutine.create(function (x) f(x) end) |
742 | a, b = coroutine.resume(co, 3) | 747 | a, b = coroutine.resume(co, 3) |
743 | t = {"'coroutine.yield'", "'f'", "in function <"} | 748 | t = {"'coroutine.yield'", "'f'", "in function <"} |
744 | repeat | 749 | while coroutine.status(co) == "suspended" do |
745 | checktraceback(co, t) | 750 | checktraceback(co, t) |
746 | a, b = coroutine.resume(co) | 751 | a, b = coroutine.resume(co) |
747 | table.insert(t, 2, "'f'") -- one more recursive call to 'f' | 752 | table.insert(t, 2, "'f'") -- one more recursive call to 'f' |
748 | until b | 753 | end |
754 | t[1] = "'error'" | ||
749 | checktraceback(co, t) | 755 | checktraceback(co, t) |
750 | 756 | ||
751 | 757 | ||
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 | |||
417 | end | 417 | end |
418 | 418 | ||
419 | 419 | ||
420 | -- to-be-closed variables in coroutines | 420 | print "to-be-closed variables in coroutines" |
421 | |||
421 | do | 422 | do |
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) |
441 | end | 442 | end |
442 | 443 | ||
444 | |||
445 | do | ||
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) | ||
455 | print(msg) | ||
456 | -- should get last error raised | ||
457 | assert(not st and string.find(msg, "%w+%.%w+:%d+: XXX")) | ||
458 | end | ||
459 | |||
460 | |||
443 | -- a suspended coroutine should not close its variables when collected | 461 | -- a suspended coroutine should not close its variables when collected |
444 | local co | 462 | local co |
445 | co = coroutine.wrap(function() | 463 | co = coroutine.wrap(function() |
@@ -449,6 +467,7 @@ co = coroutine.wrap(function() | |||
449 | end) | 467 | end) |
450 | co() -- start coroutine | 468 | co() -- start coroutine |
451 | assert(co == nil) -- eventually it will be collected | 469 | assert(co == nil) -- eventually it will be collected |
470 | collectgarbage() | ||
452 | 471 | ||
453 | 472 | ||
454 | -- to-be-closed variables in generic for loops | 473 | -- to-be-closed variables in generic for loops |