Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- In Lua 5.1 you can't yield over a pcall.
- -- feature test
- local function has_yieldable_pcall(pcall)
- -- This has to happen inside a throwaway coroutine, as if the
- -- feature works, we don't want to yield back to whatever called us.
- -- You have to pass coroutine.create an actual lua function,
- -- so coroutine.create; a C function won't do.
- local ok, has = coroutine.resume(coroutine.create(function()
- -- Pass `true` so we don't need to fix up `has`
- return pcall(coroutine.yield, true)
- end))
- -- throw error if feature detection fails
- assert(ok, has)
- return has
- end
- if not has_yieldable_pcall(pcall) then
- local function helper(co, ok, ...)
- if ok then
- return helper(co, coroutine.resume(co, coroutine.yield(...)))
- else
- return false, (...)
- end
- end
- function pcall(func, ...)
- -- You have to pass coroutine.create an actual lua function,
- -- so coroutine.create; a C function won't do.
- local co = coroutine.create(function(...) return func(...) end)
- return helper(co, coroutine.resume(co, ...))
- end
- end
- local function foo(arg)
- assert(arg == "a")
- assert(coroutine.yield("1") == "b")
- assert(coroutine.yield("2") == "c")
- return "3"
- end
- do
- local co = coroutine.create(foo)
- assert(select(2, assert(coroutine.resume(co, "a"))) == "1")
- assert(select(2, assert(coroutine.resume(co, "b"))) == "2")
- assert(select(2, assert(coroutine.resume(co, "c"))) == "3")
- end
- do
- local function bar(...)
- return select(2, assert(pcall(foo, ...)))
- end
- local co = coroutine.create(bar)
- assert(select(2, assert(coroutine.resume(co, "a"))) == "1")
- assert(select(2, assert(coroutine.resume(co, "b"))) == "2")
- assert(select(2, assert(coroutine.resume(co, "c"))) == "3")
- end
- do
- local co = coroutine.create(function()
- local ok, err = pcall(function()
- error("OK", 0)
- end)
- assert(not ok and err == "OK")
- end)
- assert(coroutine.resume(co, "a"))
- end
- do
- local co = coroutine.create(function()
- return "1"
- end)
- assert(select(2, assert(coroutine.resume(co, "a"))) == "1")
- assert(select(2, assert(coroutine.resume(co, "a"))) == "1")
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement