coroutine.lua 32 KB

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