diff options
Diffstat (limited to 'testes/coroutine.lua')
-rw-r--r-- | testes/coroutine.lua | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/testes/coroutine.lua b/testes/coroutine.lua index 15fccc30..de7e46fb 100644 --- a/testes/coroutine.lua +++ b/testes/coroutine.lua | |||
@@ -30,7 +30,8 @@ local function eqtab (t1, t2) | |||
30 | end | 30 | end |
31 | 31 | ||
32 | _G.x = nil -- declare x | 32 | _G.x = nil -- declare x |
33 | function foo (a, ...) | 33 | _G.f = nil -- declare f |
34 | local function foo (a, ...) | ||
34 | local x, y = coroutine.running() | 35 | local x, y = coroutine.running() |
35 | assert(x == f and y == false) | 36 | assert(x == f and y == false) |
36 | -- next call should not corrupt coroutine (but must fail, | 37 | -- next call should not corrupt coroutine (but must fail, |
@@ -67,10 +68,11 @@ assert(coroutine.status(f) == "dead") | |||
67 | s, a = coroutine.resume(f, "xuxu") | 68 | s, a = coroutine.resume(f, "xuxu") |
68 | assert(not s and string.find(a, "dead") and coroutine.status(f) == "dead") | 69 | assert(not s and string.find(a, "dead") and coroutine.status(f) == "dead") |
69 | 70 | ||
71 | _G.f = nil | ||
70 | 72 | ||
71 | -- yields in tail calls | 73 | -- yields in tail calls |
72 | local function foo (i) return coroutine.yield(i) end | 74 | local function foo (i) return coroutine.yield(i) end |
73 | f = coroutine.wrap(function () | 75 | local f = coroutine.wrap(function () |
74 | for i=1,10 do | 76 | for i=1,10 do |
75 | assert(foo(i) == _G.x) | 77 | assert(foo(i) == _G.x) |
76 | end | 78 | end |
@@ -79,8 +81,10 @@ end) | |||
79 | for i=1,10 do _G.x = i; assert(f(i) == i) end | 81 | for i=1,10 do _G.x = i; assert(f(i) == i) end |
80 | _G.x = 'xuxu'; assert(f('xuxu') == 'a') | 82 | _G.x = 'xuxu'; assert(f('xuxu') == 'a') |
81 | 83 | ||
84 | _G.x = nil | ||
85 | |||
82 | -- recursive | 86 | -- recursive |
83 | function pf (n, i) | 87 | local function pf (n, i) |
84 | coroutine.yield(n) | 88 | coroutine.yield(n) |
85 | pf(n*i, i+1) | 89 | pf(n*i, i+1) |
86 | end | 90 | end |
@@ -93,14 +97,14 @@ for i=1,10 do | |||
93 | end | 97 | end |
94 | 98 | ||
95 | -- sieve | 99 | -- sieve |
96 | function gen (n) | 100 | local function gen (n) |
97 | return coroutine.wrap(function () | 101 | return coroutine.wrap(function () |
98 | for i=2,n do coroutine.yield(i) end | 102 | for i=2,n do coroutine.yield(i) end |
99 | end) | 103 | end) |
100 | end | 104 | end |
101 | 105 | ||
102 | 106 | ||
103 | function filter (p, g) | 107 | local function filter (p, g) |
104 | return coroutine.wrap(function () | 108 | return coroutine.wrap(function () |
105 | while 1 do | 109 | while 1 do |
106 | local n = g() | 110 | local n = g() |
@@ -221,14 +225,14 @@ do | |||
221 | -- <close> versus pcall in coroutines | 225 | -- <close> versus pcall in coroutines |
222 | local X = false | 226 | local X = false |
223 | local Y = false | 227 | local Y = false |
224 | function foo () | 228 | local function foo () |
225 | local x <close> = func2close(function (self, err) | 229 | local x <close> = func2close(function (self, err) |
226 | Y = debug.getinfo(2) | 230 | Y = debug.getinfo(2) |
227 | X = err | 231 | X = err |
228 | end) | 232 | end) |
229 | error(43) | 233 | error(43) |
230 | end | 234 | end |
231 | co = coroutine.create(function () return pcall(foo) end) | 235 | local co = coroutine.create(function () return pcall(foo) end) |
232 | local st1, st2, err = coroutine.resume(co) | 236 | local st1, st2, err = coroutine.resume(co) |
233 | assert(st1 and not st2 and err == 43) | 237 | assert(st1 and not st2 and err == 43) |
234 | assert(X == 43 and Y.what == "C") | 238 | assert(X == 43 and Y.what == "C") |
@@ -275,7 +279,7 @@ end | |||
275 | 279 | ||
276 | -- yielding across C boundaries | 280 | -- yielding across C boundaries |
277 | 281 | ||
278 | co = coroutine.wrap(function() | 282 | local co = coroutine.wrap(function() |
279 | assert(not pcall(table.sort,{1,2,3}, coroutine.yield)) | 283 | assert(not pcall(table.sort,{1,2,3}, coroutine.yield)) |
280 | assert(coroutine.isyieldable()) | 284 | assert(coroutine.isyieldable()) |
281 | coroutine.yield(20) | 285 | coroutine.yield(20) |
@@ -303,15 +307,15 @@ local r1, r2, v = f1(nil) | |||
303 | assert(r1 and not r2 and v[1] == (10 + 1)*10/2) | 307 | assert(r1 and not r2 and v[1] == (10 + 1)*10/2) |
304 | 308 | ||
305 | 309 | ||
306 | function f (a, b) a = coroutine.yield(a); error{a + b} end | 310 | local function f (a, b) a = coroutine.yield(a); error{a + b} end |
307 | function g(x) return x[1]*2 end | 311 | local function g(x) return x[1]*2 end |
308 | 312 | ||
309 | co = coroutine.wrap(function () | 313 | co = coroutine.wrap(function () |
310 | coroutine.yield(xpcall(f, g, 10, 20)) | 314 | coroutine.yield(xpcall(f, g, 10, 20)) |
311 | end) | 315 | end) |
312 | 316 | ||
313 | assert(co() == 10) | 317 | assert(co() == 10) |
314 | r, msg = co(100) | 318 | local r, msg = co(100) |
315 | assert(not r and msg == 240) | 319 | assert(not r and msg == 240) |
316 | 320 | ||
317 | 321 | ||
@@ -373,9 +377,10 @@ assert(not a and b == foo and coroutine.status(x) == "dead") | |||
373 | a,b = coroutine.resume(x) | 377 | a,b = coroutine.resume(x) |
374 | assert(not a and string.find(b, "dead") and coroutine.status(x) == "dead") | 378 | assert(not a and string.find(b, "dead") and coroutine.status(x) == "dead") |
375 | 379 | ||
380 | goo = nil | ||
376 | 381 | ||
377 | -- co-routines x for loop | 382 | -- co-routines x for loop |
378 | function all (a, n, k) | 383 | local function all (a, n, k) |
379 | if k == 0 then coroutine.yield(a) | 384 | if k == 0 then coroutine.yield(a) |
380 | else | 385 | else |
381 | for i=1,n do | 386 | for i=1,n do |
@@ -415,7 +420,7 @@ assert(f() == 43 and f() == 53) | |||
415 | 420 | ||
416 | -- old bug: attempt to resume itself | 421 | -- old bug: attempt to resume itself |
417 | 422 | ||
418 | function co_func (current_co) | 423 | local function co_func (current_co) |
419 | assert(coroutine.running() == current_co) | 424 | assert(coroutine.running() == current_co) |
420 | assert(coroutine.resume(current_co) == false) | 425 | assert(coroutine.resume(current_co) == false) |
421 | coroutine.yield(10, 20) | 426 | coroutine.yield(10, 20) |
@@ -491,15 +496,16 @@ a = nil | |||
491 | -- access to locals of erroneous coroutines | 496 | -- access to locals of erroneous coroutines |
492 | local x = coroutine.create (function () | 497 | local x = coroutine.create (function () |
493 | local a = 10 | 498 | local a = 10 |
494 | _G.f = function () a=a+1; return a end | 499 | _G.F = function () a=a+1; return a end |
495 | error('x') | 500 | error('x') |
496 | end) | 501 | end) |
497 | 502 | ||
498 | assert(not coroutine.resume(x)) | 503 | assert(not coroutine.resume(x)) |
499 | -- overwrite previous position of local `a' | 504 | -- overwrite previous position of local `a' |
500 | assert(not coroutine.resume(x, 1, 1, 1, 1, 1, 1, 1)) | 505 | assert(not coroutine.resume(x, 1, 1, 1, 1, 1, 1, 1)) |
501 | assert(_G.f() == 11) | 506 | assert(_G.F() == 11) |
502 | assert(_G.f() == 12) | 507 | assert(_G.F() == 12) |
508 | _G.F = nil | ||
503 | 509 | ||
504 | 510 | ||
505 | if not T then | 511 | if not T then |
@@ -510,7 +516,7 @@ else | |||
510 | 516 | ||
511 | local turn | 517 | local turn |
512 | 518 | ||
513 | function fact (t, x) | 519 | local function fact (t, x) |
514 | assert(turn == t) | 520 | assert(turn == t) |
515 | if x == 0 then return 1 | 521 | if x == 0 then return 1 |
516 | else return x*fact(t, x-1) | 522 | else return x*fact(t, x-1) |
@@ -579,6 +585,7 @@ else | |||
579 | _G.X = nil; co(); assert(_G.X == line + 2 and _G.XX == nil) | 585 | _G.X = nil; co(); assert(_G.X == line + 2 and _G.XX == nil) |
580 | _G.X = nil; co(); assert(_G.X == line + 3 and _G.XX == 20) | 586 | _G.X = nil; co(); assert(_G.X == line + 3 and _G.XX == 20) |
581 | assert(co() == 10) | 587 | assert(co() == 10) |
588 | _G.X = nil | ||
582 | 589 | ||
583 | -- testing yields in count hook | 590 | -- testing yields in count hook |
584 | co = coroutine.wrap(function () | 591 | co = coroutine.wrap(function () |
@@ -656,6 +663,8 @@ else | |||
656 | 663 | ||
657 | assert(X == 'a a a' and Y == 'OK') | 664 | assert(X == 'a a a' and Y == 'OK') |
658 | 665 | ||
666 | X, Y = nil | ||
667 | |||
659 | 668 | ||
660 | -- resuming running coroutine | 669 | -- resuming running coroutine |
661 | C = coroutine.create(function () | 670 | C = coroutine.create(function () |
@@ -701,7 +710,7 @@ else | |||
701 | X = function (x) coroutine.yield(x, 'BB'); return 'CC' end; | 710 | X = function (x) coroutine.yield(x, 'BB'); return 'CC' end; |
702 | return 'ok']])) | 711 | return 'ok']])) |
703 | 712 | ||
704 | t = table.pack(T.testC(state, [[ | 713 | local t = table.pack(T.testC(state, [[ |
705 | rawgeti R 1 # get main thread | 714 | rawgeti R 1 # get main thread |
706 | pushstring 'XX' | 715 | pushstring 'XX' |
707 | getglobal X # get function for body | 716 | getglobal X # get function for body |
@@ -730,13 +739,13 @@ end | |||
730 | 739 | ||
731 | 740 | ||
732 | -- leaving a pending coroutine open | 741 | -- leaving a pending coroutine open |
733 | _X = coroutine.wrap(function () | 742 | _G.TO_SURVIVE = coroutine.wrap(function () |
734 | local a = 10 | 743 | local a = 10 |
735 | local x = function () a = a+1 end | 744 | local x = function () a = a+1 end |
736 | coroutine.yield() | 745 | coroutine.yield() |
737 | end) | 746 | end) |
738 | 747 | ||
739 | _X() | 748 | _G.TO_SURVIVE() |
740 | 749 | ||
741 | 750 | ||
742 | if not _soft then | 751 | if not _soft then |
@@ -935,7 +944,7 @@ assert(run(function () | |||
935 | do local _ENV = _ENV | 944 | do local _ENV = _ENV |
936 | f = function () AAA = BBB + 1; return AAA end | 945 | f = function () AAA = BBB + 1; return AAA end |
937 | end | 946 | end |
938 | g = new(10); g.k.BBB = 10; | 947 | local g = new(10); g.k.BBB = 10; |
939 | debug.setupvalue(f, 1, g) | 948 | debug.setupvalue(f, 1, g) |
940 | assert(run(f, {"idx", "nidx", "idx"}) == 11) | 949 | assert(run(f, {"idx", "nidx", "idx"}) == 11) |
941 | assert(g.k.AAA == 11) | 950 | assert(g.k.AAA == 11) |
@@ -1075,6 +1084,8 @@ assert(#a == 3 and a[1] == a[2] and a[2] == a[3] and a[3] == 34) | |||
1075 | 1084 | ||
1076 | -- testing yields with continuations | 1085 | -- testing yields with continuations |
1077 | 1086 | ||
1087 | local y | ||
1088 | |||
1078 | co = coroutine.wrap(function (...) return | 1089 | co = coroutine.wrap(function (...) return |
1079 | T.testC([[ # initial function | 1090 | T.testC([[ # initial function |
1080 | yieldk 1 2 | 1091 | yieldk 1 2 |
@@ -1127,6 +1138,9 @@ assert(x == "YIELD" and y == 4) | |||
1127 | 1138 | ||
1128 | assert(not pcall(co)) -- coroutine should be dead | 1139 | assert(not pcall(co)) -- coroutine should be dead |
1129 | 1140 | ||
1141 | _G.ctx = nil | ||
1142 | _G.status = nil | ||
1143 | |||
1130 | 1144 | ||
1131 | -- bug in nCcalls | 1145 | -- bug in nCcalls |
1132 | local co = coroutine.wrap(function () | 1146 | local co = coroutine.wrap(function () |