Advertisement
Guest User

Untitled

a guest
Nov 25th, 2015
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.02 KB | None | 0 0
  1. -- In Lua 5.1 you can't yield over a pcall.
  2.  
  3. -- feature test
  4. local function has_yieldable_pcall(pcall)
  5. -- This has to happen inside a throwaway coroutine, as if the
  6. -- feature works, we don't want to yield back to whatever called us.
  7. -- You have to pass coroutine.create an actual lua function,
  8. -- so coroutine.create; a C function won't do.
  9. local ok, has = coroutine.resume(coroutine.create(function()
  10. -- Pass `true` so we don't need to fix up `has`
  11. return pcall(coroutine.yield, true)
  12. end))
  13. -- throw error if feature detection fails
  14. assert(ok, has)
  15. return has
  16. end
  17.  
  18. if not has_yieldable_pcall(pcall) then
  19. local function helper(co, ok, ...)
  20. if ok then
  21. return helper(co, coroutine.resume(co, coroutine.yield(...)))
  22. else
  23. return false, (...)
  24. end
  25. end
  26.  
  27. function pcall(func, ...)
  28. -- You have to pass coroutine.create an actual lua function,
  29. -- so coroutine.create; a C function won't do.
  30. local co = coroutine.create(function(...) return func(...) end)
  31. return helper(co, coroutine.resume(co, ...))
  32. end
  33. end
  34.  
  35.  
  36. local function foo(arg)
  37. assert(arg == "a")
  38. assert(coroutine.yield("1") == "b")
  39. assert(coroutine.yield("2") == "c")
  40. return "3"
  41. end
  42. do
  43. local co = coroutine.create(foo)
  44. assert(select(2, assert(coroutine.resume(co, "a"))) == "1")
  45. assert(select(2, assert(coroutine.resume(co, "b"))) == "2")
  46. assert(select(2, assert(coroutine.resume(co, "c"))) == "3")
  47. end
  48. do
  49. local function bar(...)
  50. return select(2, assert(pcall(foo, ...)))
  51. end
  52. local co = coroutine.create(bar)
  53. assert(select(2, assert(coroutine.resume(co, "a"))) == "1")
  54. assert(select(2, assert(coroutine.resume(co, "b"))) == "2")
  55. assert(select(2, assert(coroutine.resume(co, "c"))) == "3")
  56. end
  57.  
  58. do
  59. local co = coroutine.create(function()
  60. local ok, err = pcall(function()
  61. error("OK", 0)
  62. end)
  63. assert(not ok and err == "OK")
  64. end)
  65. assert(coroutine.resume(co, "a"))
  66. end
  67.  
  68. do
  69. local co = coroutine.create(function()
  70. return "1"
  71. end)
  72. assert(select(2, assert(coroutine.resume(co, "a"))) == "1")
  73. assert(select(2, assert(coroutine.resume(co, "a"))) == "1")
  74. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement