------------------------------------------------------------------------------- -- Coroutine safe xpcall and pcall versions -- -- Encapsulates the protected calls with a coroutine based loop, so errors can -- be dealed without the usual Lua 5.0 pcall/xpcall issues with coroutines -- yielding inside the call to pcall or xpcall. -- -- Authors: Roberto Ierusalimschy and Andre Carregal -- -- $Id: coxpcall.lua,v 1.6 2005/05/16 21:27:42 carregal Exp $ -- -- Copyright 2005 - Kepler Project (www.keplerproject.org) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Implements xpcall with coroutines ------------------------------------------------------------------------------- function coxpcall(f, err) local co = coroutine.create(f) local arg = {} while true do local results = {coroutine.resume(co, unpack(arg))} local status = results[1] table.remove (results, 1) -- remove status of coroutine.resume if not status then return false, err(unpack(results)) end if coroutine.status(co) == "suspended" then arg = {coroutine.yield(unpack(results))} else return true, unpack(results) end end end ------------------------------------------------------------------------------- -- Implements pcall with coroutines ------------------------------------------------------------------------------- function copcall(f, ...) return coxpcall(function() return f(unpack(arg)) end, error) end