coroutine.lua 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263
  1. -- $Id: testes/coroutine.lua $
  2. -- See Copyright Notice in file lua.h
  3. print "testing coroutines"
  4. local debug = require'debug'
  5. local f
  6. local main, ismain = coroutine.running()
  7. assert(type(main) == "thread" and ismain)
  8. assert(not coroutine.resume(main))
  9. assert(not coroutine.isyieldable(main) and not coroutine.isyieldable())
  10. assert(not pcall(coroutine.yield))
  11. -- trivial errors
  12. assert(not pcall(coroutine.resume, 0))
  13. assert(not pcall(coroutine.status, 0))
  14. -- tests for multiple yield/resume arguments
  15. local function eqtab (t1, t2)
  16. assert(#t1 == #t2)
  17. for i = 1, #t1 do
  18. local v = t1[i]
  19. assert(t2[i] == v)
  20. end
  21. end
  22. _G.x = nil -- declare x
  23. _G.f = nil -- declare f
  24. local function foo (a, ...)
  25. local x, y = coroutine.running()
  26. assert(x == f and y == false)
  27. -- next call should not corrupt coroutine (but must fail,
  28. -- as it attempts to resume the running coroutine)
  29. assert(coroutine.resume(f) == false)
  30. assert(coroutine.status(f) == "running")
  31. local arg = {...}
  32. assert(coroutine.isyieldable(x))
  33. for i=1,#arg do
  34. _G.x = {coroutine.yield(table.unpack(arg[i]))}
  35. end
  36. return table.unpack(a)
  37. end
  38. f = coroutine.create(foo)
  39. assert(coroutine.isyieldable(f))
  40. assert(type(f) == "thread" and coroutine.status(f) == "suspended")
  41. assert(string.find(tostring(f), "thread"))
  42. local s,a,b,c,d
  43. s,a,b,c,d = coroutine.resume(f, {1,2,3}, {}, {1}, {'a', 'b', 'c'})
  44. assert(coroutine.isyieldable(f))
  45. assert(s and a == nil and coroutine.status(f) == "suspended")
  46. s,a,b,c,d = coroutine.resume(f)
  47. eqtab(_G.x, {})
  48. assert(s and a == 1 and b == nil)
  49. assert(coroutine.isyieldable(f))
  50. s,a,b,c,d = coroutine.resume(f, 1, 2, 3)
  51. eqtab(_G.x, {1, 2, 3})
  52. assert(s and a == 'a' and b == 'b' and c == 'c' and d == nil)
  53. s,a,b,c,d = coroutine.resume(f, "xuxu")
  54. eqtab(_G.x, {"xuxu"})
  55. assert(s and a == 1 and b == 2 and c == 3 and d == nil)
  56. assert(coroutine.status(f) == "dead")
  57. s, a = coroutine.resume(f, "xuxu")
  58. assert(not s and string.find(a, "dead") and coroutine.status(f) == "dead")
  59. _G.f = nil
  60. -- yields in tail calls
  61. local function foo (i) return coroutine.yield(i) end
  62. local f = coroutine.wrap(function ()
  63. for i=1,10 do
  64. assert(foo(i) == _G.x)
  65. end
  66. return 'a'
  67. end)
  68. for i=1,10 do _G.x = i; assert(f(i) == i) end
  69. _G.x = 'xuxu'; assert(f('xuxu') == 'a')
  70. _G.x = nil
  71. -- recursive
  72. local function pf (n, i)
  73. coroutine.yield(n)
  74. pf(n*i, i+1)
  75. end
  76. f = coroutine.wrap(pf)
  77. local s=1
  78. for i=1,10 do
  79. assert(f(1, 1) == s)
  80. s = s*i
  81. end
  82. -- sieve
  83. local function gen (n)
  84. return coroutine.wrap(function ()
  85. for i=2,n do coroutine.yield(i) end
  86. end)
  87. end
  88. local function filter (p, g)
  89. return coroutine.wrap(function ()
  90. while 1 do
  91. local n = g()
  92. if n == nil then return end
  93. if math.fmod(n, p) ~= 0 then coroutine.yield(n) end
  94. end
  95. end)
  96. end
  97. local x = gen(80)
  98. local a = {}
  99. while 1 do
  100. local n = x()
  101. if n == nil then break end
  102. table.insert(a, n)
  103. x = filter(n, x)
  104. end
  105. assert(#a == 22 and a[#a] == 79)
  106. x, a = nil
  107. do -- "bug" in 5.4.2
  108. local function foo () foo () end -- just create a stack overflow
  109. local co = coroutine.create(foo)
  110. -- running this coroutine would overflow the unsigned short 'nci', the
  111. -- counter of CallInfo structures available to the thread.
  112. -- (The issue only manifests in an 'assert'.)
  113. local st, msg = coroutine.resume(co)
  114. assert(string.find(msg, "stack overflow"))
  115. assert(coroutine.status(co) == "dead")
  116. end
  117. print("to-be-closed variables in coroutines")
  118. local function func2close (f)
  119. return setmetatable({}, {__close = f})
  120. end
  121. do
  122. -- ok to close a dead coroutine
  123. local co = coroutine.create(print)
  124. assert(coroutine.resume(co, "testing 'coroutine.close'"))
  125. assert(coroutine.status(co) == "dead")
  126. local st, msg = coroutine.close(co)
  127. assert(st and msg == nil)
  128. -- also ok to close it again
  129. st, msg = coroutine.close(co)
  130. assert(st and msg == nil)
  131. local main = coroutine.running()
  132. -- cannot close 'main'
  133. local st, msg = pcall(coroutine.close, main);
  134. assert(not st and string.find(msg, "main"))
  135. -- cannot close a "normal" coroutine
  136. ;(coroutine.wrap(function ()
  137. local st, msg = pcall(coroutine.close, main)
  138. assert(not st and string.find(msg, "normal"))
  139. end))()
  140. do -- close a coroutine while closing it
  141. local co
  142. co = coroutine.create(
  143. function()
  144. local x <close> = func2close(function()
  145. coroutine.close(co) -- close it again
  146. end)
  147. coroutine.yield(20)
  148. end)
  149. local st, msg = coroutine.resume(co)
  150. assert(st and msg == 20)
  151. st, msg = coroutine.close(co)
  152. assert(st and msg == nil)
  153. end
  154. -- to-be-closed variables in coroutines
  155. local X
  156. -- closing a coroutine after an error
  157. local co = coroutine.create(error)
  158. local st, msg = coroutine.resume(co, 100)
  159. assert(not st and msg == 100)
  160. st, msg = coroutine.close(co)
  161. assert(not st and msg == 100)
  162. -- after closing, no more errors
  163. st, msg = coroutine.close(co)
  164. assert(st and msg == nil)
  165. co = coroutine.create(function ()
  166. local x <close> = func2close(function (self, err)
  167. assert(err == nil); X = false
  168. end)
  169. X = true
  170. coroutine.yield()
  171. end)
  172. coroutine.resume(co)
  173. assert(X)
  174. assert(coroutine.close(co))
  175. assert(not X and coroutine.status(co) == "dead")
  176. -- error closing a coroutine
  177. local x = 0
  178. co = coroutine.create(function()
  179. local y <close> = func2close(function (self,err)
  180. assert(err == 111)
  181. x = 200
  182. error(200)
  183. end)
  184. local x <close> = func2close(function (self, err)
  185. assert(err == nil); error(111)
  186. end)
  187. coroutine.yield()
  188. end)
  189. coroutine.resume(co)
  190. assert(x == 0)
  191. local st, msg = coroutine.close(co)
  192. assert(st == false and coroutine.status(co) == "dead" and msg == 200)
  193. assert(x == 200)
  194. -- after closing, no more errors
  195. st, msg = coroutine.close(co)
  196. assert(st and msg == nil)
  197. end
  198. do
  199. -- <close> versus pcall in coroutines
  200. local X = false
  201. local Y = false
  202. local function foo ()
  203. local x <close> = func2close(function (self, err)
  204. Y = debug.getinfo(2)
  205. X = err
  206. end)
  207. error(43)
  208. end
  209. local co = coroutine.create(function () return pcall(foo) end)
  210. local st1, st2, err = coroutine.resume(co)
  211. assert(st1 and not st2 and err == 43)
  212. assert(X == 43 and Y.what == "C")
  213. -- recovering from errors in __close metamethods
  214. local track = {}
  215. local function h (o)
  216. local hv <close> = o
  217. return 1
  218. end
  219. local function foo ()
  220. local x <close> = func2close(function(_,msg)
  221. track[#track + 1] = msg or false
  222. error(20)
  223. end)
  224. local y <close> = func2close(function(_,msg)
  225. track[#track + 1] = msg or false
  226. return 1000
  227. end)
  228. local z <close> = func2close(function(_,msg)
  229. track[#track + 1] = msg or false
  230. error(10)
  231. end)
  232. coroutine.yield(1)
  233. h(func2close(function(_,msg)
  234. track[#track + 1] = msg or false
  235. error(2)
  236. end))
  237. end
  238. local co = coroutine.create(pcall)
  239. local st, res = coroutine.resume(co, foo) -- call 'foo' protected
  240. assert(st and res == 1) -- yield 1
  241. local st, res1, res2 = coroutine.resume(co) -- continue
  242. assert(coroutine.status(co) == "dead")
  243. assert(st and not res1 and res2 == 20) -- last error (20)
  244. assert(track[1] == false and track[2] == 2 and track[3] == 10 and
  245. track[4] == 10)
  246. end
  247. do print("coroutines closing itself")
  248. global <const> coroutine, string, os
  249. global <const> assert, error, pcall
  250. local X = nil
  251. local function new ()
  252. return coroutine.create(function (what)
  253. local <close>var = func2close(function (t, err)
  254. if what == "yield" then
  255. coroutine.yield()
  256. elseif what == "error" then
  257. error(200)
  258. else
  259. X = "Ok"
  260. return X
  261. end
  262. end)
  263. -- do an unprotected call so that coroutine becomes non-yieldable
  264. string.gsub("a", "a", function ()
  265. assert(not coroutine.isyieldable())
  266. -- do protected calls while non-yieldable, to add recovery
  267. -- entries (setjmp) to the stack
  268. assert(pcall(pcall, function ()
  269. -- 'close' works even while non-yieldable
  270. coroutine.close() -- close itself
  271. os.exit(false) -- not reacheable
  272. end))
  273. end)
  274. end)
  275. end
  276. local co = new()
  277. local st, msg = coroutine.resume(co, "ret")
  278. assert(st and msg == nil)
  279. assert(X == "Ok")
  280. local co = new()
  281. local st, msg = coroutine.resume(co, "error")
  282. assert(not st and msg == 200)
  283. local co = new()
  284. local st, msg = coroutine.resume(co, "yield")
  285. assert(not st and string.find(msg, "attempt to yield"))
  286. end
  287. -- yielding across C boundaries
  288. local co = coroutine.wrap(function()
  289. assert(not pcall(table.sort,{1,2,3}, coroutine.yield))
  290. assert(coroutine.isyieldable())
  291. coroutine.yield(20)
  292. return 30
  293. end)
  294. assert(co() == 20)
  295. assert(co() == 30)
  296. local f = function (s, i) return coroutine.yield(i) end
  297. local f1 = coroutine.wrap(function ()
  298. return xpcall(pcall, function (...) return ... end,
  299. function ()
  300. local s = 0
  301. for i in f, nil, 1 do pcall(function () s = s + i end) end
  302. error({s})
  303. end)
  304. end)
  305. f1()
  306. for i = 1, 10 do assert(f1(i) == i) end
  307. local r1, r2, v = f1(nil)
  308. assert(r1 and not r2 and v[1] == (10 + 1)*10/2)
  309. local function f (a, b) a = coroutine.yield(a); error{a + b} end
  310. local function g(x) return x[1]*2 end
  311. co = coroutine.wrap(function ()
  312. coroutine.yield(xpcall(f, g, 10, 20))
  313. end)
  314. assert(co() == 10)
  315. local r, msg = co(100)
  316. assert(not r and msg == 240)
  317. -- unyieldable C call
  318. do
  319. local function f (c)
  320. assert(not coroutine.isyieldable())
  321. return c .. c
  322. end
  323. local co = coroutine.wrap(function (c)
  324. assert(coroutine.isyieldable())
  325. local s = string.gsub("a", ".", f)
  326. return s
  327. end)
  328. assert(co() == "aa")
  329. end
  330. do -- testing single trace of coroutines
  331. local X
  332. local co = coroutine.create(function ()
  333. coroutine.yield(10)
  334. return 20;
  335. end)
  336. local trace = {}
  337. local function dotrace (event)
  338. trace[#trace + 1] = event
  339. end
  340. debug.sethook(co, dotrace, "clr")
  341. repeat until not coroutine.resume(co)
  342. local correcttrace = {"call", "line", "call", "return", "line", "return"}
  343. assert(#trace == #correcttrace)
  344. for k, v in pairs(trace) do
  345. assert(v == correcttrace[k])
  346. end
  347. end
  348. -- errors in coroutines
  349. function foo ()
  350. assert(debug.getinfo(1).currentline == debug.getinfo(foo).linedefined + 1)
  351. assert(debug.getinfo(2).currentline == debug.getinfo(goo).linedefined)
  352. coroutine.yield(3)
  353. error(foo)
  354. end
  355. function goo() foo() end
  356. x = coroutine.wrap(goo)
  357. assert(x() == 3)
  358. local a,b = pcall(x)
  359. assert(not a and b == foo)
  360. x = coroutine.create(goo)
  361. a,b = coroutine.resume(x)
  362. assert(a and b == 3)
  363. a,b = coroutine.resume(x)
  364. assert(not a and b == foo and coroutine.status(x) == "dead")
  365. a,b = coroutine.resume(x)
  366. assert(not a and string.find(b, "dead") and coroutine.status(x) == "dead")
  367. goo = nil
  368. -- co-routines x for loop
  369. local function all (a, n, k)
  370. if k == 0 then coroutine.yield(a)
  371. else
  372. for i=1,n do
  373. a[k] = i
  374. all(a, n, k-1)
  375. end
  376. end
  377. end
  378. local a = 0
  379. for t in coroutine.wrap(function () all({}, 5, 4) end) do
  380. a = a+1
  381. end
  382. assert(a == 5^4)
  383. -- access to locals of collected corroutines
  384. local C = {}; setmetatable(C, {__mode = "kv"})
  385. local x = coroutine.wrap (function ()
  386. local a = 10
  387. local function f () a = a+10; return a end
  388. while true do
  389. a = a+1
  390. coroutine.yield(f)
  391. end
  392. end)
  393. C[1] = x;
  394. local f = x()
  395. assert(f() == 21 and x()() == 32 and x() == f)
  396. x = nil
  397. collectgarbage()
  398. assert(C[1] == undef)
  399. assert(f() == 43 and f() == 53)
  400. -- old bug: attempt to resume itself
  401. local function co_func (current_co)
  402. assert(coroutine.running() == current_co)
  403. assert(coroutine.resume(current_co) == false)
  404. coroutine.yield(10, 20)
  405. assert(coroutine.resume(current_co) == false)
  406. coroutine.yield(23)
  407. return 10
  408. end
  409. local co = coroutine.create(co_func)
  410. local a,b,c = coroutine.resume(co, co)
  411. assert(a == true and b == 10 and c == 20)
  412. a,b = coroutine.resume(co, co)
  413. assert(a == true and b == 23)
  414. a,b = coroutine.resume(co, co)
  415. assert(a == true and b == 10)
  416. assert(coroutine.resume(co, co) == false)
  417. assert(coroutine.resume(co, co) == false)
  418. -- other old bug when attempting to resume itself
  419. -- (trigger C-code assertions)
  420. do
  421. local A = coroutine.running()
  422. local B = coroutine.create(function() return coroutine.resume(A) end)
  423. local st, res = coroutine.resume(B)
  424. assert(st == true and res == false)
  425. local X = false
  426. A = coroutine.wrap(function()
  427. local _ <close> = func2close(function () X = true end)
  428. return pcall(A, 1)
  429. end)
  430. st, res = A()
  431. assert(not st and string.find(res, "non%-suspended") and X == true)
  432. end
  433. -- bug in 5.4.1
  434. do
  435. -- coroutine ran close metamethods with invalid status during a
  436. -- reset.
  437. local co
  438. co = coroutine.wrap(function()
  439. local x <close> = func2close(function() return pcall(co) end)
  440. error(111)
  441. end)
  442. local st, errobj = pcall(co)
  443. assert(not st and errobj == 111)
  444. st, errobj = pcall(co)
  445. assert(not st and string.find(errobj, "dead coroutine"))
  446. end
  447. -- attempt to resume 'normal' coroutine
  448. local co1, co2
  449. co1 = coroutine.create(function () return co2() end)
  450. co2 = coroutine.wrap(function ()
  451. assert(coroutine.status(co1) == 'normal')
  452. assert(not coroutine.resume(co1))
  453. coroutine.yield(3)
  454. end)
  455. a,b = coroutine.resume(co1)
  456. assert(a and b == 3)
  457. assert(coroutine.status(co1) == 'dead')
  458. -- infinite recursion of coroutines
  459. a = function(a) coroutine.wrap(a)(a) end
  460. assert(not pcall(a, a))
  461. a = nil
  462. do
  463. -- bug in 5.4: thread can use message handler higher in the stack
  464. -- than the variable being closed
  465. local c = coroutine.create(function()
  466. local clo <close> = setmetatable({}, {__close=function()
  467. local x = 134 -- will overwrite message handler
  468. error(x)
  469. end})
  470. -- yields coroutine but leaves a new message handler for it,
  471. -- that would be used when closing the coroutine (except that it
  472. -- will be overwritten)
  473. xpcall(coroutine.yield, function() return "XXX" end)
  474. end)
  475. assert(coroutine.resume(c)) -- start coroutine
  476. local st, msg = coroutine.close(c)
  477. assert(not st and msg == 134)
  478. end
  479. -- access to locals of erroneous coroutines
  480. local x = coroutine.create (function ()
  481. local a = 10
  482. _G.F = function () a=a+1; return a end
  483. error('x')
  484. end)
  485. assert(not coroutine.resume(x))
  486. -- overwrite previous position of local `a'
  487. assert(not coroutine.resume(x, 1, 1, 1, 1, 1, 1, 1))
  488. assert(_G.F() == 11)
  489. assert(_G.F() == 12)
  490. _G.F = nil
  491. if not T then
  492. (Message or print)
  493. ('\n >>> testC not active: skipping coroutine API tests <<<\n')
  494. else
  495. print "testing yields inside hooks"
  496. local turn
  497. local function fact (t, x)
  498. assert(turn == t)
  499. if x == 0 then return 1
  500. else return x*fact(t, x-1)
  501. end
  502. end
  503. local A, B = 0, 0
  504. local x = coroutine.create(function ()
  505. T.sethook("yield 0", "", 2)
  506. A = fact("A", 6)
  507. end)
  508. local y = coroutine.create(function ()
  509. T.sethook("yield 0", "", 3)
  510. B = fact("B", 7)
  511. end)
  512. while A==0 or B==0 do -- A ~= 0 when 'x' finishes (similar for 'B','y')
  513. if A==0 then turn = "A"; assert(T.resume(x)) end
  514. if B==0 then turn = "B"; assert(T.resume(y)) end
  515. -- check that traceback works correctly after yields inside hooks
  516. debug.traceback(x)
  517. debug.traceback(y)
  518. end
  519. assert(B // A == 7) -- fact(7) // fact(6)
  520. do -- hooks vs. multiple values
  521. local done
  522. local function test (n)
  523. done = false
  524. return coroutine.wrap(function ()
  525. local a = {}
  526. for i = 1, n do a[i] = i end
  527. -- 'pushint' just to perturb the stack
  528. T.sethook("pushint 10; yield 0", "", 1) -- yield at each op.
  529. local a1 = {table.unpack(a)} -- must keep top between ops.
  530. assert(#a1 == n)
  531. for i = 1, n do assert(a[i] == i) end
  532. done = true
  533. end)
  534. end
  535. -- arguments to the coroutine are just to perturb its stack
  536. local co = test(0); while not done do co(30) end
  537. co = test(1); while not done do co(20, 10) end
  538. co = test(3); while not done do co() end
  539. co = test(100); while not done do co() end
  540. end
  541. local line = debug.getinfo(1, "l").currentline + 2 -- get line number
  542. local function foo ()
  543. local x = 10 --<< this line is 'line'
  544. x = x + 10
  545. _G.XX = x
  546. end
  547. -- testing yields in line hook
  548. local co = coroutine.wrap(function ()
  549. T.sethook("setglobal X; yield 0", "l", 0); foo(); return 10 end)
  550. _G.XX = nil;
  551. _G.X = nil; co(); assert(_G.X == line)
  552. _G.X = nil; co(); assert(_G.X == line + 1)
  553. _G.X = nil; co(); assert(_G.X == line + 2 and _G.XX == nil)
  554. _G.X = nil; co(); assert(_G.X == line + 3 and _G.XX == 20)
  555. assert(co() == 10)
  556. _G.X = nil
  557. -- testing yields in count hook
  558. co = coroutine.wrap(function ()
  559. T.sethook("yield 0", "", 1); foo(); return 10 end)
  560. _G.XX = nil;
  561. local c = 0
  562. repeat c = c + 1; local a = co() until a == 10
  563. assert(_G.XX == 20 and c >= 5)
  564. co = coroutine.wrap(function ()
  565. T.sethook("yield 0", "", 2); foo(); return 10 end)
  566. _G.XX = nil;
  567. local c = 0
  568. repeat c = c + 1; local a = co() until a == 10
  569. assert(_G.XX == 20 and c >= 5)
  570. _G.X = nil; _G.XX = nil
  571. do
  572. -- testing debug library on a coroutine suspended inside a hook
  573. -- (bug in 5.2/5.3)
  574. c = coroutine.create(function (a, ...)
  575. T.sethook("yield 0", "l") -- will yield on next two lines
  576. local b = a
  577. return ...
  578. end)
  579. assert(coroutine.resume(c, 1, 2, 3)) -- start coroutine
  580. local n,v = debug.getlocal(c, 0, 1) -- check its local
  581. assert(n == "a" and v == 1 and debug.getlocal(c, 0, 2) ~= "b")
  582. assert(debug.setlocal(c, 0, 1, 10)) -- test 'setlocal'
  583. local t = debug.getinfo(c, 0) -- test 'getinfo'
  584. assert(t.currentline == t.linedefined + 2)
  585. assert(not debug.getinfo(c, 1)) -- no other level
  586. assert(coroutine.resume(c)) -- run next line
  587. local n,v = debug.getlocal(c, 0, 2) -- check vararg table
  588. assert(n == "(vararg table)" and v == nil)
  589. local n,v = debug.getlocal(c, 0, 3) -- check next local
  590. assert(n == "b" and v == 10)
  591. v = {coroutine.resume(c)} -- finish coroutine
  592. assert(v[1] == true and v[2] == 2 and v[3] == 3 and v[4] == undef)
  593. assert(not coroutine.resume(c))
  594. end
  595. do
  596. -- testing debug library on last function in a suspended coroutine
  597. -- (bug in 5.2/5.3)
  598. local c = coroutine.create(function () T.testC("yield 1", 10, 20) end)
  599. local a, b = coroutine.resume(c)
  600. assert(a and b == 20)
  601. assert(debug.getinfo(c, 0).linedefined == -1)
  602. a, b = debug.getlocal(c, 0, 2)
  603. assert(b == 10)
  604. end
  605. print "testing coroutine API"
  606. -- reusing a thread
  607. assert(T.testC([[
  608. newthread # create thread
  609. pushvalue 2 # push body
  610. pushstring 'a a a' # push argument
  611. xmove 0 3 2 # move values to new thread
  612. resume -1, 1 # call it first time
  613. pushstatus
  614. xmove 3 0 0 # move results back to stack
  615. setglobal X # result
  616. setglobal Y # status
  617. pushvalue 2 # push body (to call it again)
  618. pushstring 'b b b'
  619. xmove 0 3 2
  620. resume -1, 1 # call it again
  621. pushstatus
  622. xmove 3 0 0
  623. return 1 # return result
  624. ]], function (...) return ... end) == 'b b b')
  625. assert(X == 'a a a' and Y == 'OK')
  626. X, Y = nil
  627. -- resuming running coroutine
  628. C = coroutine.create(function ()
  629. return T.testC([[
  630. pushnum 10;
  631. pushnum 20;
  632. resume -3 2;
  633. pushstatus
  634. gettop;
  635. return 3]], C)
  636. end)
  637. local a, b, c, d = coroutine.resume(C)
  638. assert(a == true and string.find(b, "non%-suspended") and
  639. c == "ERRRUN" and d == 4)
  640. a, b, c, d = T.testC([[
  641. rawgeti R !M # get main thread
  642. pushnum 10;
  643. pushnum 20;
  644. resume -3 2;
  645. pushstatus
  646. gettop;
  647. return 4]])
  648. assert(a == coroutine.running() and string.find(b, "non%-suspended") and
  649. c == "ERRRUN" and d == 4)
  650. -- using a main thread as a coroutine (dubious use!)
  651. local state = T.newstate()
  652. -- check that yielddable is working correctly
  653. assert(T.testC(state, "newthread; isyieldable -1; remove 1; return 1"))
  654. -- main thread is not yieldable
  655. assert(not T.testC(state, "rawgeti R !M; isyieldable -1; remove 1; return 1"))
  656. T.testC(state, "settop 0")
  657. T.loadlib(state, 1 | 2, 4) -- load _G and 'package', preload 'coroutine'
  658. assert(T.doremote(state, [[
  659. coroutine = require'coroutine';
  660. X = function (x) coroutine.yield(x, 'BB'); return 'CC' end;
  661. return 'ok']]))
  662. local t = table.pack(T.testC(state, [[
  663. rawgeti R !M # get main thread
  664. pushstring 'XX'
  665. getglobal X # get function for body
  666. pushstring AA # arg
  667. resume 1 1 # 'resume' shadows previous stack!
  668. gettop
  669. setglobal T # top
  670. setglobal B # second yielded value
  671. setglobal A # fist yielded value
  672. rawgeti R !M # get main thread
  673. pushnum 5 # arg (noise)
  674. resume 1 1 # after coroutine ends, previous stack is back
  675. pushstatus
  676. return *
  677. ]]))
  678. assert(t.n == 4 and t[2] == 'XX' and t[3] == 'CC' and t[4] == 'OK')
  679. assert(T.doremote(state, "return T") == '2')
  680. assert(T.doremote(state, "return A") == 'AA')
  681. assert(T.doremote(state, "return B") == 'BB')
  682. T.closestate(state)
  683. print'+'
  684. end
  685. -- leaving a pending coroutine open
  686. _G.TO_SURVIVE = coroutine.wrap(function ()
  687. local a = 10
  688. local x = function () a = a+1 end
  689. coroutine.yield()
  690. end)
  691. _G.TO_SURVIVE()
  692. if not _soft then
  693. -- bug (stack overflow)
  694. local lim = 1000000 -- stack limit; assume 32-bit machine
  695. local t = {lim - 10, lim - 5, lim - 1, lim, lim + 1, lim + 5}
  696. for i = 1, #t do
  697. local j = t[i]
  698. local co = coroutine.create(function()
  699. return table.unpack({}, 1, j)
  700. end)
  701. local r, msg = coroutine.resume(co)
  702. -- must fail for unpacking larger than stack limit
  703. assert(j < lim or not r)
  704. end
  705. end
  706. assert(coroutine.running() == main)
  707. print"+"
  708. print"testing yields inside metamethods"
  709. local function val(x)
  710. if type(x) == "table" then return x.x else return x end
  711. end
  712. local mt = {
  713. __eq = function(a,b) coroutine.yield(nil, "eq"); return val(a) == val(b) end,
  714. __lt = function(a,b) coroutine.yield(nil, "lt"); return val(a) < val(b) end,
  715. __le = function(a,b) coroutine.yield(nil, "le"); return a - b <= 0 end,
  716. __add = function(a,b) coroutine.yield(nil, "add");
  717. return val(a) + val(b) end,
  718. __sub = function(a,b) coroutine.yield(nil, "sub"); return val(a) - val(b) end,
  719. __mul = function(a,b) coroutine.yield(nil, "mul"); return val(a) * val(b) end,
  720. __div = function(a,b) coroutine.yield(nil, "div"); return val(a) / val(b) end,
  721. __idiv = function(a,b) coroutine.yield(nil, "idiv");
  722. return val(a) // val(b) end,
  723. __pow = function(a,b) coroutine.yield(nil, "pow"); return val(a) ^ val(b) end,
  724. __mod = function(a,b) coroutine.yield(nil, "mod"); return val(a) % val(b) end,
  725. __unm = function(a,b) coroutine.yield(nil, "unm"); return -val(a) end,
  726. __bnot = function(a,b) coroutine.yield(nil, "bnot"); return ~val(a) end,
  727. __shl = function(a,b) coroutine.yield(nil, "shl");
  728. return val(a) << val(b) end,
  729. __shr = function(a,b) coroutine.yield(nil, "shr");
  730. return val(a) >> val(b) end,
  731. __band = function(a,b)
  732. coroutine.yield(nil, "band")
  733. return val(a) & val(b)
  734. end,
  735. __bor = function(a,b) coroutine.yield(nil, "bor");
  736. return val(a) | val(b) end,
  737. __bxor = function(a,b) coroutine.yield(nil, "bxor");
  738. return val(a) ~ val(b) end,
  739. __concat = function(a,b)
  740. coroutine.yield(nil, "concat");
  741. return val(a) .. val(b)
  742. end,
  743. __index = function (t,k) coroutine.yield(nil, "idx"); return t.k[k] end,
  744. __newindex = function (t,k,v) coroutine.yield(nil, "nidx"); t.k[k] = v end,
  745. }
  746. local function new (x)
  747. return setmetatable({x = x, k = {}}, mt)
  748. end
  749. local a = new(10)
  750. local b = new(12)
  751. local c = new"hello"
  752. local function run (f, t)
  753. local i = 1
  754. local c = coroutine.wrap(f)
  755. while true do
  756. local res, stat = c()
  757. if res then assert(t[i] == undef); return res, t end
  758. assert(stat == t[i])
  759. i = i + 1
  760. end
  761. end
  762. assert(run(function () if (a>=b) then return '>=' else return '<' end end,
  763. {"le", "sub"}) == "<")
  764. assert(run(function () if (a<=b) then return '<=' else return '>' end end,
  765. {"le", "sub"}) == "<=")
  766. assert(run(function () if (a==b) then return '==' else return '~=' end end,
  767. {"eq"}) == "~=")
  768. assert(run(function () return a & b + a end, {"add", "band"}) == 2)
  769. assert(run(function () return 1 + a end, {"add"}) == 11)
  770. assert(run(function () return a - 25 end, {"sub"}) == -15)
  771. assert(run(function () return 2 * a end, {"mul"}) == 20)
  772. assert(run(function () return a ^ 2 end, {"pow"}) == 100)
  773. assert(run(function () return a / 2 end, {"div"}) == 5)
  774. assert(run(function () return a % 6 end, {"mod"}) == 4)
  775. assert(run(function () return a // 3 end, {"idiv"}) == 3)
  776. assert(run(function () return a + b end, {"add"}) == 22)
  777. assert(run(function () return a - b end, {"sub"}) == -2)
  778. assert(run(function () return a * b end, {"mul"}) == 120)
  779. assert(run(function () return a ^ b end, {"pow"}) == 10^12)
  780. assert(run(function () return a / b end, {"div"}) == 10/12)
  781. assert(run(function () return a % b end, {"mod"}) == 10)
  782. assert(run(function () return a // b end, {"idiv"}) == 0)
  783. -- repeat tests with larger constants (to use 'K' opcodes)
  784. local a1000 = new(1000)
  785. assert(run(function () return a1000 + 1000 end, {"add"}) == 2000)
  786. assert(run(function () return a1000 - 25000 end, {"sub"}) == -24000)
  787. assert(run(function () return 2000 * a end, {"mul"}) == 20000)
  788. assert(run(function () return a1000 / 1000 end, {"div"}) == 1)
  789. assert(run(function () return a1000 % 600 end, {"mod"}) == 400)
  790. assert(run(function () return a1000 // 500 end, {"idiv"}) == 2)
  791. assert(run(function () return a % b end, {"mod"}) == 10)
  792. assert(run(function () return ~a & b end, {"bnot", "band"}) == ~10 & 12)
  793. assert(run(function () return a | b end, {"bor"}) == 10 | 12)
  794. assert(run(function () return a ~ b end, {"bxor"}) == 10 ~ 12)
  795. assert(run(function () return a << b end, {"shl"}) == 10 << 12)
  796. assert(run(function () return a >> b end, {"shr"}) == 10 >> 12)
  797. assert(run(function () return 10 & b end, {"band"}) == 10 & 12)
  798. assert(run(function () return a | 2 end, {"bor"}) == 10 | 2)
  799. assert(run(function () return a ~ 2 end, {"bxor"}) == 10 ~ 2)
  800. assert(run(function () return a >> 2 end, {"shr"}) == 10 >> 2)
  801. assert(run(function () return 1 >> a end, {"shr"}) == 1 >> 10)
  802. assert(run(function () return a << 2 end, {"shl"}) == 10 << 2)
  803. assert(run(function () return 1 << a end, {"shl"}) == 1 << 10)
  804. assert(run(function () return 2 ~ a end, {"bxor"}) == 2 ~ 10)
  805. assert(run(function () return a..b end, {"concat"}) == "1012")
  806. assert(run(function() return a .. b .. c .. a end,
  807. {"concat", "concat", "concat"}) == "1012hello10")
  808. assert(run(function() return "a" .. "b" .. a .. "c" .. c .. b .. "x" end,
  809. {"concat", "concat", "concat"}) == "ab10chello12x")
  810. do -- a few more tests for comparison operators
  811. local mt1 = {
  812. __le = function (a,b)
  813. coroutine.yield(10)
  814. return (val(a) <= val(b))
  815. end,
  816. __lt = function (a,b)
  817. coroutine.yield(10)
  818. return val(a) < val(b)
  819. end,
  820. }
  821. local mt2 = { __lt = mt1.__lt, __le = mt1.__le }
  822. local function run (f)
  823. local co = coroutine.wrap(f)
  824. local res
  825. repeat
  826. res = co()
  827. until res ~= 10
  828. return res
  829. end
  830. local function test ()
  831. local a1 = setmetatable({x=1}, mt1)
  832. local a2 = setmetatable({x=2}, mt2)
  833. assert(a1 < a2)
  834. assert(a1 <= a2)
  835. assert(1 < a2)
  836. assert(1 <= a2)
  837. assert(2 > a1)
  838. assert(2 >= a2)
  839. return true
  840. end
  841. run(test)
  842. end
  843. assert(run(function ()
  844. a.BB = print
  845. return a.BB
  846. end, {"nidx", "idx"}) == print)
  847. -- getuptable & setuptable
  848. do local _ENV = _ENV
  849. f = function () AAA = BBB + 1; return AAA end
  850. end
  851. local g = new(10); g.k.BBB = 10;
  852. debug.setupvalue(f, 1, g)
  853. assert(run(f, {"idx", "nidx", "idx"}) == 11)
  854. assert(g.k.AAA == 11)
  855. print"+"
  856. print"testing yields inside 'for' iterators"
  857. local f = function (s, i)
  858. if i%2 == 0 then coroutine.yield(nil, "for") end
  859. if i < s then return i + 1 end
  860. end
  861. assert(run(function ()
  862. local s = 0
  863. for i in f, 4, 0 do s = s + i end
  864. return s
  865. end, {"for", "for", "for"}) == 10)
  866. -- tests for coroutine API
  867. if T==nil then
  868. (Message or print)('\n >>> testC not active: skipping coroutine API tests <<<\n')
  869. print "OK"; return
  870. end
  871. print('testing coroutine API')
  872. local function apico (...)
  873. local x = {...}
  874. return coroutine.wrap(function ()
  875. return T.testC(table.unpack(x))
  876. end)
  877. end
  878. local a = {apico(
  879. [[
  880. pushstring errorcode
  881. pcallk 1 0 2;
  882. invalid command (should not arrive here)
  883. ]],
  884. [[return *]],
  885. "stackmark",
  886. error
  887. )()}
  888. assert(#a == 4 and
  889. a[3] == "stackmark" and
  890. a[4] == "errorcode" and
  891. _G.status == "ERRRUN" and
  892. _G.ctx == 2) -- 'ctx' to pcallk
  893. local co = apico(
  894. "pushvalue 2; pushnum 10; pcallk 1 2 3; invalid command;",
  895. coroutine.yield,
  896. "getglobal status; getglobal ctx; pushvalue 2; pushstring a; pcallk 1 0 4; invalid command",
  897. "getglobal status; getglobal ctx; return *")
  898. assert(co() == 10)
  899. assert(co(20, 30) == 'a')
  900. a = {co()}
  901. assert(#a == 10 and
  902. a[2] == coroutine.yield and
  903. a[5] == 20 and a[6] == 30 and
  904. a[7] == "YIELD" and a[8] == 3 and
  905. a[9] == "YIELD" and a[10] == 4)
  906. assert(not pcall(co)) -- coroutine is dead now
  907. f = T.makeCfunc("pushnum 3; pushnum 5; yield 1;")
  908. co = coroutine.wrap(function ()
  909. assert(f() == 23); assert(f() == 23); return 10
  910. end)
  911. assert(co(23,16) == 5)
  912. assert(co(23,16) == 5)
  913. assert(co(23,16) == 10)
  914. -- testing coroutines with C bodies
  915. f = T.makeCfunc([[
  916. pushnum 102
  917. yieldk 1 U2
  918. cannot be here!
  919. ]],
  920. [[ # continuation
  921. pushvalue U3 # accessing upvalues inside a continuation
  922. pushvalue U4
  923. return *
  924. ]], 23, "huu")
  925. do -- testing bug introduced in commit f407b3c4a
  926. local X = false -- flag "to be closed"
  927. local coro = coroutine.wrap(T.testC)
  928. -- runs it until 'pcallk' (that yields)
  929. -- 4th argument (at index 4): object to be closed
  930. local res1, res2 = coro(
  931. [[
  932. toclose 3 # this could break the next 'pcallk'
  933. pushvalue 2 # push function 'yield' to call it
  934. pushint 22; pushint 33 # arguments to yield
  935. # calls 'yield' (2 args; 2 results; continuation function at index 4)
  936. pcallk 2 2 4
  937. invalid command (should not arrive here)
  938. ]], -- 1st argument (at index 1): code;
  939. coroutine.yield, -- (at index 2): function to be called
  940. func2close(function () X = true end), -- (index 3): TBC slot
  941. "pushint 43; return 3" -- (index 4): code for continuation function
  942. )
  943. assert(res1 == 22 and res2 == 33 and not X)
  944. local res1, res2, res3 = coro(34, "hi") -- runs continuation function
  945. assert(res1 == 34 and res2 == "hi" and res3 == 43 and X)
  946. end
  947. x = coroutine.wrap(f)
  948. assert(x() == 102)
  949. eqtab({x()}, {23, "huu"})
  950. f = T.makeCfunc[[pushstring 'a'; pushnum 102; yield 2; ]]
  951. a, b, c, d = T.testC([[newthread; pushvalue 2; xmove 0 3 1; resume 3 0;
  952. pushstatus; xmove 3 0 0; resume 3 0; pushstatus;
  953. return 4; ]], f)
  954. assert(a == 'YIELD' and b == 'a' and c == 102 and d == 'OK')
  955. -- testing chain of suspendable C calls
  956. local count = 3 -- number of levels
  957. f = T.makeCfunc([[
  958. remove 1; # remove argument
  959. pushvalue U3; # get selection function
  960. call 0 1; # call it (result is 'f' or 'yield')
  961. pushstring hello # single argument for selected function
  962. pushupvalueindex 2; # index of continuation program
  963. callk 1 -1 .; # call selected function
  964. errorerror # should never arrive here
  965. ]],
  966. [[
  967. # continuation program
  968. pushnum 34 # return value
  969. return * # return all results
  970. ]],
  971. function () -- selection function
  972. count = count - 1
  973. if count == 0 then return coroutine.yield
  974. else return f
  975. end
  976. end
  977. )
  978. co = coroutine.wrap(function () return f(nil) end)
  979. assert(co() == "hello") -- argument to 'yield'
  980. a = {co()}
  981. -- three '34's (one from each pending C call)
  982. assert(#a == 3 and a[1] == a[2] and a[2] == a[3] and a[3] == 34)
  983. -- testing yields with continuations
  984. local y
  985. co = coroutine.wrap(function (...) return
  986. T.testC([[ # initial function
  987. yieldk 1 2
  988. cannot be here!
  989. ]],
  990. [[ # 1st continuation
  991. yieldk 0 3
  992. cannot be here!
  993. ]],
  994. [[ # 2nd continuation
  995. yieldk 0 4
  996. cannot be here!
  997. ]],
  998. [[ # 3th continuation
  999. pushvalue 6 # function which is last arg. to 'testC' here
  1000. pushnum 10; pushnum 20;
  1001. pcall 2 0 0 # call should throw an error and return to next line
  1002. pop 1 # remove error message
  1003. pushvalue 6
  1004. getglobal status; getglobal ctx
  1005. pcallk 2 2 5 # call should throw an error and jump to continuation
  1006. cannot be here!
  1007. ]],
  1008. [[ # 4th (and last) continuation
  1009. return *
  1010. ]],
  1011. -- function called by 3th continuation
  1012. function (a,b) x=a; y=b; error("errmsg") end,
  1013. ...
  1014. )
  1015. end)
  1016. local a = {co(3,4,6)}
  1017. assert(a[1] == 6 and a[2] == undef)
  1018. a = {co()}; assert(a[1] == undef and _G.status == "YIELD" and _G.ctx == 2)
  1019. a = {co()}; assert(a[1] == undef and _G.status == "YIELD" and _G.ctx == 3)
  1020. a = {co(7,8)};
  1021. -- original arguments
  1022. assert(type(a[1]) == 'string' and type(a[2]) == 'string' and
  1023. type(a[3]) == 'string' and type(a[4]) == 'string' and
  1024. type(a[5]) == 'string' and type(a[6]) == 'function')
  1025. -- arguments left from fist resume
  1026. assert(a[7] == 3 and a[8] == 4)
  1027. -- arguments to last resume
  1028. assert(a[9] == 7 and a[10] == 8)
  1029. -- error message and nothing more
  1030. assert(a[11]:find("errmsg") and #a == 11)
  1031. -- check arguments to pcallk
  1032. assert(x == "YIELD" and y == 4)
  1033. assert(not pcall(co)) -- coroutine should be dead
  1034. _G.ctx = nil
  1035. _G.status = nil
  1036. -- bug in nCcalls
  1037. local co = coroutine.wrap(function ()
  1038. local a = {pcall(pcall,pcall,pcall,pcall,pcall,pcall,pcall,error,"hi")}
  1039. return pcall(assert, table.unpack(a))
  1040. end)
  1041. local a = {co()}
  1042. assert(a[10] == "hi")
  1043. print'OK'