Skip to content

Three codehz/ecs perf-suite tests fail: iterator/collection method lost through wrapped types (next/add "is not a function") #9023

Description

@proggeramlug

Running the codehz/ecs (v0.13.0) comprehensive.perf.test.ts suite with all seven tests enabled (the perf harness normally skips six), three fail under perry while all pass under node 26.5.1:

test error
should spawn and sync entities efficiently next is not a function
should handle mixed operations in a realistic game loop next is not a function
should handle exclusive sparse relation flips efficiently add is not a function

Established so far

  • Not a regression. Bisected by building pre-perf(runtime,codegen): SSO computed keys + megamorphic write stub cache (dynamic-property overwrite 5.3×) #8965 main (bdd395216) with all seven rows enabled: the same three fail with the same errors. This predates the 2026-08-28/29 perf work.
  • The obvious minimization does not reproduce. The suspect pattern from archetype/store.ts:166-172let s = map.get(k); if (!s) { s = new Set(); map.set(k, s); } s.add(v) — compiled standalone behaves identically to node (sizes, has, all correct). So the trigger is narrower than the raw Map-of-Set idiom.
  • The failing tests exercise: entity spawn + world.delete cleanup loops, the mixed-ops game loop, and sparse/exclusive relations (component({ sparse: true, exclusive: true }) + relation(ChildOf, parent)). The passing four never touch sparse relations, so getComponentIdFromRelationId / the sparse-relation store paths are prime suspects for at least the add failure.
  • next is not a function is the classic symptom of GetIterator returning a non-iterator (perry's js_get_iterator falls through to returning the value itself when no [Symbol.iterator] resolves), so some receiver shape in these tests resolves no iterator where node finds one.

Repro

# prepared workspace via secret-tests/ecs-suite/run.py::prepare_workspace on ecs-suite/.ecs
# then enable all it( ) tests and compile:
perry compile src/__tests__/perf/comprehensive.perf.test.ts -o ecs.bin
./ecs.bin   # => 7 tests | 4 passed | 3 failed

Suggested next steps

  1. Instrument the bun-test shim to print e.stack for the three failures (the shim currently swallows it) — one run pins the exact source lines.
  2. Bisect the failing test bodies (they are short) rather than the library idiom.

Worth fixing beyond correctness: the three hidden rows include the sparse-relation benchmark, so perf coverage of that path is currently zero.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions