From 66f0ee616033189473a84c8e974ea97e83f5543d Mon Sep 17 00:00:00 2001 From: Philipp Janda Date: Mon, 22 Feb 2016 21:07:16 +0100 Subject: [PATCH] Use native (x)pcall if possible. Delegate to native (x)pcall if co(x)pcall is called from the main thread where yielding isn't allowed anyway. This reduces the runtime by more than 50% in this very common case. --- src/coxpcall.lua | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/coxpcall.lua b/src/coxpcall.lua index f2f28ea..3b49ce3 100644 --- a/src/coxpcall.lua +++ b/src/coxpcall.lua @@ -36,12 +36,12 @@ end -- Implements xpcall with coroutines ------------------------------------------------------------------------------- local performResume, handleReturnValue -local oldpcall = pcall +local oldpcall, oldxpcall = pcall, xpcall local pack = table.pack or function(...) return {n = select("#", ...), ...} end local unpack = table.unpack or unpack local running = coroutine.running local coromap = setmetatable({}, { __mode = "k" }) - + function handleReturnValue(err, co, status, ...) if not status then return false, err(debug.traceback(co, (...)), ...) @@ -57,15 +57,32 @@ function performResume(err, co, ...) return handleReturnValue(err, co, coroutine.resume(co, ...)) end +local function id(trace, ...) + return trace +end + function coxpcall(f, err, ...) - local res, co = oldpcall(coroutine.create, f) - if not res then - local params = pack(...) - local newf = function() return f(unpack(params, 1, params.n)) end - co = coroutine.create(newf) + local current = running() + if not current then + if err == id then + return oldpcall(f, ...) + else + if select("#", ...) > 0 then + local oldf, params = f, pack(...) + f = function() return oldf(unpack(params, 1, params.n)) end + end + return oldxpcall(f, err) + end + else + local res, co = oldpcall(coroutine.create, f) + if not res then + local params = pack(...) + local newf = function() return f(unpack(params, 1, params.n)) end + co = coroutine.create(newf) + end + coromap[co] = current + return performResume(err, co, ...) end - coromap[co] = (running() or "mainthread") - return performResume(err, co, ...) end local function corunning(coro) @@ -85,10 +102,6 @@ end -- Implements pcall with coroutines ------------------------------------------------------------------------------- -local function id(trace, ...) - return ... -end - function copcall(f, ...) return coxpcall(f, id, ...) end