summaryrefslogtreecommitdiff
path: root/xmake/core/base/hashset.lua
diff options
context:
space:
mode:
authorruki <[email protected]>2026-04-15 00:44:04 +0800
committerruki <[email protected]>2026-04-15 00:44:04 +0800
commit56b93f6181438ace9764d280b5d906d75cfc5883 (patch)
tree68174a109ccc32201407856feb7f9a447fe7f18b /xmake/core/base/hashset.lua
parent346f929f7819e92e2752c7b3335894297fb02630 (diff)
improve pairs for lua5.5
Diffstat (limited to 'xmake/core/base/hashset.lua')
-rw-r--r--xmake/core/base/hashset.lua35
1 files changed, 24 insertions, 11 deletions
diff --git a/xmake/core/base/hashset.lua b/xmake/core/base/hashset.lua
index c052d36ee..ea184c6bf 100644
--- a/xmake/core/base/hashset.lua
+++ b/xmake/core/base/hashset.lua
@@ -119,15 +119,23 @@ end
-- end
-- @endcode
--
+-- Stateful closure so the loop body can safely reassign the first loop
+-- variable under lua 5.4+ (paired with the RDKCONST->VDKREG compile-time
+-- patch in core/src/lua/xmake.lua).
function hashset:items()
- return function (t, item)
- local k, _ = next(t._DATA, item)
- if k == hashset._NIL then
+ -- keep `next`'s key in an upvalue so the loop body can safely reassign
+ -- the first loop variable. In lua 5.4+ the for-in control slot is
+ -- merged with the first user variable; threading the key through the
+ -- loop would otherwise corrupt `next` on the following iteration.
+ local data = self._DATA
+ local k = nil
+ return function ()
+ k = next(data, k)
+ if k == nil or k == hashset._NIL then
return nil
- else
- return k
end
- end, self, nil
+ return k
+ end
end
-- iterate order items
@@ -175,14 +183,19 @@ end
-- @endcode
--
function hashset:keys()
- return function (t, key)
- local k, _ = next(t._DATA, key)
+ -- see hashset:items() for rationale
+ local data = self._DATA
+ local k = nil
+ return function ()
+ k = next(data, k)
+ if k == nil then
+ return nil
+ end
if k == hashset._NIL then
return k, nil
- else
- return k, k
end
- end, self, nil
+ return k, k
+ end
end
-- iterate order keys (deprecated, please use orderitems())