Skip to content

Engine parity: super() constructor dispatch diverges across same-named classes in different files (jelly-micro fixture) #2251

Description

@carlos-alm

Summary

scripts/parity-compare.mjs (run with no --langs filter, comparing all fixtures) reports a wasm-vs-native divergence on the jelly-micro fixture (tests/benchmarks/resolution/fixtures/jelly-micro), unrelated to any in-flight change — reproduces identically on a clean origin/main checkout (verified at commit 5e704bc4).

Repro

node scripts/parity-compare.mjs --langs jelly-micro
=== jelly-micro: wasm vs native DIVERGED (0 node diffs, 3 edge diffs)
  [edge] [calls] classes/classes.js:D.constructor(method) -> super/super.js:A.constructor(method) conf=0.4 dyn=0 technique=super-dispatch  wasm=1 native=0
  [edge] [calls] classes/classes.js:D.constructor(method) -> super4/super4.js:A.constructor(method) conf=0.4 dyn=0 technique=super-dispatch  wasm=1 native=0
  [edge] [calls] classes/classes.js:D.constructor(method) -> super5/super5.js:A.constructor(method) conf=0.4 dyn=0 technique=super-dispatch  wasm=1 native=0

WASM emits a super() constructor-dispatch edge from classes/classes.js:D.constructor to A.constructor in three different files (super/super.js, super4/super4.js, super5/super5.js — each apparently declaring an unrelated class also named A). The native engine emits none of these three edges.

Why this needs investigation

Per this repo's dual-engine parity invariant, both engines must produce identical graphs. Here either:

  • WASM is wrong: D should extend a specific A (whichever one classes.js actually imports/extends), and fan-out to same-named-but-unrelated A classes in other fixture files is a false positive in the WASM this/super dispatch resolver (resolveThisDispatch in src/domain/graph/builder/cha.ts), or
  • Native is wrong: it's failing to resolve a real super() dispatch edge that WASM correctly finds.

Given the same-file-preference logic already present in resolveThisDispatch (only same-file nodes are preferred; a same-named class in an unrelated file can apparently still be included when the caller's own file has no local match), this may be an existing edge case in the multi-target super() resolution across identically-named classes declared independently in multiple files of the same fixture — need to determine which class D actually extends in classes/classes.js and whether the correct single edge is emitted by either engine, or whether both under/over-resolve.

Scope note

Found while running the full parity-compare.mjs suite (all 34 language fixtures) as part of verifying issue #2030 (cross-file ES6 accessor recognition) — confirmed via a from-scratch build of both engines on a clean origin/main worktree that this divergence is pre-existing and unrelated to that change. Filing per this repo's scope-discipline convention rather than fixing inline.

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