From 415a0596bbdefec83c9423de464e846e651b3a0b Mon Sep 17 00:00:00 2001 From: Sam Atman Date: Sat, 26 Mar 2022 09:19:36 -0400 Subject: [PATCH 1/2] Adds string conversion, caches 'coroutine' by tag This patch makes two changes: it caches the return values by tag, and auto-converts a string tag into a private table. The combination of these means that any module can call something like ```lua local coro = coromake 'scheduler' ``` And will obtain the same nested coroutines table, without running into a problem with using `yield 'scheduler'` somewhere as a literal value. Which is visible in the example, but the silent bug is when the string slips into some process or collection. --- src/coroutine/make.lua | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/coroutine/make.lua b/src/coroutine/make.lua index 66d7adb..e94eb68 100644 --- a/src/coroutine/make.lua +++ b/src/coroutine/make.lua @@ -1,20 +1,37 @@ -local select = select -local create = coroutine.create -local isyieldable = coroutine.isyieldable -- luacheck: ignore -local resume = coroutine.resume -local running = coroutine.running -local status = coroutine.status -local wrap = coroutine.wrap -local yield = coroutine.yield - -return function (tag) +local select = select +local setmetatable = setmetatable +local create = coroutine.create +local isyieldable = coroutine.isyieldable -- luacheck: ignore +local resume = coroutine.resume +local running = coroutine.running +local status = coroutine.status +local wrap = coroutine.wrap +local yield = coroutine.yield + +local _tagged = setmetatable({}, {__mode = 'kv'}) + +local _str_tags = setmetatable({}, {__mode = 'v'}) + +return function(tag) + if type(tag) == 'string' then + local _tag = _str_tags[tag] or {} + _str_tags[tag] = _tag + tag = _tag + end + + tag = tag or {} + + if _tagged[tag] then + return _tagged[tag] + end + local coroutine = { isyieldable = isyieldable, running = running, status = status, } - tag = tag or {} + _tagged[tag] = coroutine local function for_wrap (co, ...) if tag == ... then return select (2, ...) From acd5e2fe1f2cbedb347fcc5ae0de8372cb2cdd68 Mon Sep 17 00:00:00 2001 From: Sam Atman Date: Sat, 26 Mar 2022 09:33:51 -0400 Subject: [PATCH 2/2] Restore space mark for cleaner diff --- src/coroutine/make.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coroutine/make.lua b/src/coroutine/make.lua index e94eb68..f176ecc 100644 --- a/src/coroutine/make.lua +++ b/src/coroutine/make.lua @@ -12,7 +12,7 @@ local _tagged = setmetatable({}, {__mode = 'kv'}) local _str_tags = setmetatable({}, {__mode = 'v'}) -return function(tag) +return function (tag) if type(tag) == 'string' then local _tag = _str_tags[tag] or {} _str_tags[tag] = _tag