| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
There was a problem hiding this comment.
Note
Copilot was unable to run its full agentic suite in this review.
This PR refactors the Lua-lib Map/Set implementations to use insertion-ordered “flat array + tombstones” storage with compaction, and adds extensive iterator-mutation and memory-retention tests to validate behavior against JS/V8 semantics.
Changes:
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| test/unit/builtins/set.spec.ts | Adds iterator-mutation cases, V8-style iterator stress tests, and a Set GC-retention regression test. |
| test/unit/builtins/map.spec.ts | Adds iterator-mutation cases, V8-style iterator stress tests, and a Map GC-retention regression test with detailed Lua rehash rationale. |
| src/lualib/Set.ts | Reimplements Set ordering via array-like tables with tombstones + compaction and iterator lazy-transition logic. |
| src/lualib/Map.ts | Reimplements Map ordering via array-like tables with tombstones + compaction and iterator lazy-transition logic; adds design doc comment. |
Sorry, something went wrong.
| public forEach(callback: (value: V, key: K, map: Map<K, V>) => any): void { | ||
| for (const key of this.keys()) { | ||
| callback(this.items.get(key), key, this); | ||
| callback(this.orderedValues.get(this.keyIndex.get(key)), key, this); |
| const val = keys.get(idx); | ||
| idx++; | ||
| return { done: false, value: [val, val] as [T, T] }; |
| holeCount++; | ||
| oldKeys.set(-holeCount, i as any); |
| oldKeys.set(0, newKeys as any); | ||
| oldValues.set(0, newValues as any); |
| }; | ||
| `.getLuaExecutionResult(); | ||
| expect(result.size).toBe(0); | ||
| expect(result.retained).toBe(0); |
| }; | ||
| `.getLuaExecutionResult(); | ||
| expect(result.size).toBe(0); | ||
| expect(result.retained).toBe(0); |
…on during deletion Replace linked list (nextKey/previousKey) with flat arrays + V8-style version chain compaction. Deleted entries become tombstones (nil slots); iterators skip them via idx++. Compaction creates new arrays and links old → new; iterators transition lazily by adjusting their index. Changes: - Map/Set use keyIndex (hash), orderedKeys/orderedValues (arrays) - delete() marks tombstone, triggers compact when deletedCount > size - compact() records hole positions, links old arrays to new via index 0 - Iterator transitions through version chain (V8 Transition algorithm) - has() uses keyIndex (works correctly with null/undefined values) Based on V8's OrderedHashTable: https://chromium.googlesource.com/v8/v8/+/main/src/objects/ordered-hash-table.cc Tests: 166 Map/Set tests including V8 stress tests, memory leak tests, delete-during-iteration, re-add, and consecutive delete scenarios. Adapted from V8's collection-iterator.js: https://chromium.googlesource.com/v8/v8/+/main/test/mjsunit/es6/collection-iterator.js
| Back | FazBrowse Home | New Git URL |
Problem
Deleting Map/Set entries during iteration breaks the iterator — delete() clears nextKey[key], the pointer the iterator relies on to advance. This violates the ES spec.
Solution
Rewrite Map/Set internals from linked list to flat arrays with tombstone deletion and V8-style version chain compaction:
Also fixes has() returning false for keys with null/undefined values (now uses keyIndex instead of nextKey).